Accept Merge Request #990: (feature/修复工件配送 -> develop)
Merge Request: 优化最新AGV及新增中控日志接口调用 Created By: @杨金灵 Reviewed By: @马广威 Approved By: @马广威 Accepted By: @杨金灵 URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/990
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
'depends': ['sf_base', 'sf_maintenance', 'web_widget_model_viewer', 'sf_warehouse'],
|
'depends': ['sf_base', 'sf_maintenance', 'web_widget_model_viewer', 'sf_warehouse'],
|
||||||
'data': [
|
'data': [
|
||||||
'data/stock_data.xml',
|
'data/stock_data.xml',
|
||||||
|
'data/empty_racks_data.xml',
|
||||||
'security/group_security.xml',
|
'security/group_security.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'wizard/workpiece_delivery_views.xml',
|
'wizard/workpiece_delivery_views.xml',
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from odoo.http import request
|
|||||||
|
|
||||||
class Manufacturing_Connect(http.Controller):
|
class Manufacturing_Connect(http.Controller):
|
||||||
|
|
||||||
@http.route('/AutoDeviceApi/GetWoInfo', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
@http.route('/AutoDeviceApi/GetWoInfo', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def get_Work_Info(self, **kw):
|
def get_Work_Info(self, **kw):
|
||||||
"""
|
"""
|
||||||
@@ -21,6 +21,8 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True, 'Datas': []}
|
res = {'Succeed': True, 'Datas': []}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/GetWoInfo'})
|
||||||
logging.info('RfidCode:%s' % ret['RfidCode'])
|
logging.info('RfidCode:%s' % ret['RfidCode'])
|
||||||
if 'RfidCode' in ret:
|
if 'RfidCode' in ret:
|
||||||
workorder = request.env['mrp.workorder'].sudo().search([('rfid_code', '=', ret['RfidCode'])])
|
workorder = request.env['mrp.workorder'].sudo().search([('rfid_code', '=', ret['RfidCode'])])
|
||||||
@@ -60,6 +62,8 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True, 'Datas': []}
|
res = {'Succeed': True, 'Datas': []}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/GetShiftPlan'})
|
||||||
if 'ProductionLine' in ret:
|
if 'ProductionLine' in ret:
|
||||||
workorder_ids = request.env['mrp.workorder'].sudo().get_plan_workorder(ret['ProductionLine'])
|
workorder_ids = request.env['mrp.workorder'].sudo().get_plan_workorder(ret['ProductionLine'])
|
||||||
else:
|
else:
|
||||||
@@ -113,6 +117,8 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True, 'Datas': []}
|
res = {'Succeed': True, 'Datas': []}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/QcCheck'})
|
||||||
logging.info('RfidCode:%s' % ret['RfidCode'])
|
logging.info('RfidCode:%s' % ret['RfidCode'])
|
||||||
if 'RfidCode' in ret:
|
if 'RfidCode' in ret:
|
||||||
workorder = request.env['mrp.workorder'].sudo().search(
|
workorder = request.env['mrp.workorder'].sudo().search(
|
||||||
@@ -150,6 +156,8 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True, 'Datas': ['工单已开始']}
|
res = {'Succeed': True, 'Datas': ['工单已开始']}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/FeedBackStart'})
|
||||||
production_id = ret['BillId']
|
production_id = ret['BillId']
|
||||||
routing_type = ret['CraftId']
|
routing_type = ret['CraftId']
|
||||||
equipment_id = ret["DeviceId"]
|
equipment_id = ret["DeviceId"]
|
||||||
@@ -193,6 +201,8 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True, 'Datas': ['工单已结束']}
|
res = {'Succeed': True, 'Datas': ['工单已结束']}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/FeedBackEnd'})
|
||||||
production_id = ret['BillId']
|
production_id = ret['BillId']
|
||||||
routing_type = ret['CraftId']
|
routing_type = ret['CraftId']
|
||||||
workorder = request.env['mrp.workorder'].sudo().search(
|
workorder = request.env['mrp.workorder'].sudo().search(
|
||||||
@@ -237,6 +247,8 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True}
|
res = {'Succeed': True}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/PartQualityInspect'})
|
||||||
production_id = ret['BillId']
|
production_id = ret['BillId']
|
||||||
routing_type = ret['CraftId']
|
routing_type = ret['CraftId']
|
||||||
workorder = request.env['mrp.workorder'].sudo().search(
|
workorder = request.env['mrp.workorder'].sudo().search(
|
||||||
@@ -293,6 +305,8 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True, 'Datas': []}
|
res = {'Succeed': True, 'Datas': []}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/CMMProgDolod'})
|
||||||
if 'RfidCode' in ret:
|
if 'RfidCode' in ret:
|
||||||
logging.info('RfidCode:%s' % ret['RfidCode'])
|
logging.info('RfidCode:%s' % ret['RfidCode'])
|
||||||
workorder = request.env['mrp.workorder'].sudo().search(
|
workorder = request.env['mrp.workorder'].sudo().search(
|
||||||
@@ -331,6 +345,8 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True, 'Datas': []}
|
res = {'Succeed': True, 'Datas': []}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/NCProgDolod'})
|
||||||
if 'RfidCode' in ret:
|
if 'RfidCode' in ret:
|
||||||
logging.info('RfidCode:%s' % ret['RfidCode'])
|
logging.info('RfidCode:%s' % ret['RfidCode'])
|
||||||
workorder = request.env['mrp.workorder'].sudo().search(
|
workorder = request.env['mrp.workorder'].sudo().search(
|
||||||
@@ -370,6 +386,8 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True, 'Datas': []}
|
res = {'Succeed': True, 'Datas': []}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/LocationChange'})
|
||||||
logging.info('LocationChange_ret===========:%s' % ret)
|
logging.info('LocationChange_ret===========:%s' % ret)
|
||||||
RfidCode = ret['RfidCode']
|
RfidCode = ret['RfidCode']
|
||||||
ChangeType = ret['ChangeType']
|
ChangeType = ret['ChangeType']
|
||||||
@@ -426,11 +444,13 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True}
|
res = {'Succeed': True}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/AGVToProduct'})
|
||||||
logging.info('ret:%s' % ret)
|
logging.info('ret:%s' % ret)
|
||||||
if 'DeviceId' in ret:
|
if 'DeviceId' in ret:
|
||||||
logging.info('DeviceId:%s' % ret['DeviceId'])
|
logging.info('DeviceId:%s' % ret['DeviceId'])
|
||||||
if 'IsComplete' in ret:
|
if 'IsComplete' in ret:
|
||||||
if ret['IsComplete'] is True:
|
if ret['IsComplete'] is True or ret['IsComplete'] is False:
|
||||||
for i in range(1, 5):
|
for i in range(1, 5):
|
||||||
logging.info('F-RfidCode:%s' % i)
|
logging.info('F-RfidCode:%s' % i)
|
||||||
if f'RfidCode{i}' in ret:
|
if f'RfidCode{i}' in ret:
|
||||||
@@ -477,12 +497,14 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True}
|
res = {'Succeed': True}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/AGVDownProduct'})
|
||||||
logging.info('ret:%s' % ret)
|
logging.info('ret:%s' % ret)
|
||||||
if 'DeviceId' in ret:
|
if 'DeviceId' in ret:
|
||||||
logging.info('DeviceId:%s' % ret['DeviceId'])
|
logging.info('DeviceId:%s' % ret['DeviceId'])
|
||||||
delivery_Arr = []
|
delivery_Arr = []
|
||||||
if 'IsComplete' in ret:
|
if 'IsComplete' in ret:
|
||||||
if ret['IsComplete'] is True:
|
if ret['IsComplete'] is True or ret['IsComplete'] is False:
|
||||||
for i in range(1, 5):
|
for i in range(1, 5):
|
||||||
logging.info('F-RfidCode:%s' % i)
|
logging.info('F-RfidCode:%s' % i)
|
||||||
if f'RfidCode{i}' in ret:
|
if f'RfidCode{i}' in ret:
|
||||||
@@ -538,6 +560,8 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
res = {'Succeed': True}
|
res = {'Succeed': True}
|
||||||
datas = request.httprequest.data
|
datas = request.httprequest.data
|
||||||
ret = json.loads(datas)
|
ret = json.loads(datas)
|
||||||
|
request.env['center_control.interface.log'].sudo().create(
|
||||||
|
{'content': ret, 'name': 'AutoDeviceApi/EquipmentBaseCoordinate'})
|
||||||
if 'DeviceId' in ret:
|
if 'DeviceId' in ret:
|
||||||
equipment = request.env['maintenance.equipment'].sudo().search('name', '=', ret['DeviceId'])
|
equipment = request.env['maintenance.equipment'].sudo().search('name', '=', ret['DeviceId'])
|
||||||
if equipment:
|
if equipment:
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class Workpiece(http.Controller):
|
|||||||
req_codes = ret['reqCode'].split(',')
|
req_codes = ret['reqCode'].split(',')
|
||||||
for req_code in req_codes:
|
for req_code in req_codes:
|
||||||
workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(
|
workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(
|
||||||
[('delivery_num', '=', req_code.strip()), ('task_completion_time', '=', False)])
|
[('name', '=', req_code.strip()), ('task_completion_time', '=', False)])
|
||||||
if workpiece_delivery:
|
if workpiece_delivery:
|
||||||
workpiece_delivery.write({'status': '已配送', 'task_completion_time': datetime.now()})
|
workpiece_delivery.write({'status': '已配送', 'task_completion_time': datetime.now()})
|
||||||
else:
|
else:
|
||||||
|
|||||||
48
sf_manufacturing/data/empty_racks_data.xml
Normal file
48
sf_manufacturing/data/empty_racks_data.xml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="0">
|
||||||
|
<record id="sequence_workpiece_delivery" model="ir.sequence">
|
||||||
|
<field name="name">工件配送</field>
|
||||||
|
<field name="code">sf.workpiece.delivery</field>
|
||||||
|
<field name="prefix">WDO%(year)s%(month)s%(day)s</field>
|
||||||
|
<field name="padding">4</field>
|
||||||
|
<field name="company_id" eval="False"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="workpiece_delivery_empty_racks_1" model="sf.workpiece.delivery">
|
||||||
|
<field name="name">运送空料架路线:C01-A01</field>
|
||||||
|
<field name="type">运送空料架</field>
|
||||||
|
<field name="route_id"
|
||||||
|
search="[('start_site_id.name','=','C01'),('end_site_id.name','=','A01')]"/>
|
||||||
|
<field name="feeder_station_start_id" search="[('name','=','C01')]"/>
|
||||||
|
<field name="feeder_station_destination_id" search="[('name','=','A01')]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="workpiece_delivery_empty_racks_2" model="sf.workpiece.delivery">
|
||||||
|
<field name="name">运送空料架路线:B01-B02</field>
|
||||||
|
<field name="type">运送空料架</field>
|
||||||
|
<field name="route_id"
|
||||||
|
search="[('start_site_id.name','=','B01'),('end_site_id.name','=','B02')]"/>
|
||||||
|
<field name="feeder_station_start_id" search="[('name','=','B01')]"/>
|
||||||
|
<field name="feeder_station_destination_id" search="[('name','=','B02')]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="workpiece_delivery_empty_racks_3" model="sf.workpiece.delivery">
|
||||||
|
<field name="name">运送空料架路线:B01-A01</field>
|
||||||
|
<field name="type">运送空料架</field>
|
||||||
|
<field name="route_id"
|
||||||
|
search="[('start_site_id.name','=','B01'),('end_site_id.name','=','A01')]"/>
|
||||||
|
<field name="feeder_station_start_id" search="[('name','=','B01')]"/>
|
||||||
|
<field name="feeder_station_destination_id" search="[('name','=','A01')]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="workpiece_delivery_empty_racks_4" model="sf.workpiece.delivery">
|
||||||
|
<field name="name">运送空料架路线:C01-B02</field>
|
||||||
|
<field name="type">运送空料架</field>
|
||||||
|
<field name="route_id"
|
||||||
|
search="[('start_site_id.name','=','C01'),('end_site_id.name','=','B02')]"/>
|
||||||
|
<field name="feeder_station_start_id" search="[('name','=','C01')]"/>
|
||||||
|
<field name="feeder_station_destination_id" search="[('name','=','B02')]"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
@@ -32,6 +32,8 @@ class AgvSetting(models.Model):
|
|||||||
if da['DeviceId'] == item.name:
|
if da['DeviceId'] == item.name:
|
||||||
if da['AtHome'] is True:
|
if da['AtHome'] is True:
|
||||||
item.state = '占用'
|
item.state = '占用'
|
||||||
|
else:
|
||||||
|
item.state = '空闲'
|
||||||
|
|
||||||
|
|
||||||
class AgvTaskRoute(models.Model):
|
class AgvTaskRoute(models.Model):
|
||||||
@@ -40,15 +42,20 @@ class AgvTaskRoute(models.Model):
|
|||||||
|
|
||||||
name = fields.Char('名称')
|
name = fields.Char('名称')
|
||||||
type = fields.Selection([
|
type = fields.Selection([
|
||||||
('F01', '搬运'), ], string='类型', default="F01")
|
('F01', '搬运'), ], string='任务类型', default="F01")
|
||||||
|
route_type = fields.Selection([
|
||||||
|
('上产线', '上产线'), ('下产线', '下产线'), ('运送空料架', '运送空料架')], string='类型')
|
||||||
start_site_id = fields.Many2one('sf.agv.site', '起点接驳站位置编号')
|
start_site_id = fields.Many2one('sf.agv.site', '起点接驳站位置编号')
|
||||||
end_site_id = fields.Many2one('sf.agv.site', '终点接驳站位置编号')
|
end_site_id = fields.Many2one('sf.agv.site', '终点接驳站位置编号')
|
||||||
destination_production_line_id = fields.Many2one('sf.production.line', '目的生产线')
|
destination_production_line_id = fields.Many2one('sf.production.line', '目的生产线')
|
||||||
priority = fields.Selection([
|
active = fields.Boolean('有效', default=True)
|
||||||
('0', '正常'),
|
|
||||||
('1', '低'),
|
|
||||||
('2', '中'),
|
class Center_controlInterfaceLog(models.Model):
|
||||||
('3', '高'),
|
_name = 'center_control.interface.log'
|
||||||
('4', '紧急'),
|
_description = '中控接口调用日志'
|
||||||
], string='优先级', default='0')
|
|
||||||
|
name = fields.Char('接口名称')
|
||||||
|
content = fields.Char('接口内容')
|
||||||
|
interface_call_date = fields.Datetime("调用时间", default=fields.Datetime.now, readonly=True)
|
||||||
active = fields.Boolean('有效', default=True)
|
active = fields.Boolean('有效', default=True)
|
||||||
|
|||||||
@@ -180,6 +180,11 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
detection_report = fields.Binary('检测报告', readonly=True)
|
detection_report = fields.Binary('检测报告', readonly=True)
|
||||||
is_remanufacture = fields.Boolean(string='是否重新生成制造订单', default=True)
|
is_remanufacture = fields.Boolean(string='是否重新生成制造订单', default=True)
|
||||||
|
|
||||||
|
@api.onchange('rfid_code')
|
||||||
|
def _onchange(self):
|
||||||
|
if self.rfid_code and self.state == 'progress':
|
||||||
|
self.workpiece_delivery_ids[0].write({'rfid_code': self.rfid_code})
|
||||||
|
|
||||||
def get_plan_workorder(self, production_line):
|
def get_plan_workorder(self, production_line):
|
||||||
tomorrow = (date.today() + timedelta(days=+1)).strftime("%Y-%m-%d")
|
tomorrow = (date.today() + timedelta(days=+1)).strftime("%Y-%m-%d")
|
||||||
tomorrow_start = tomorrow + ' 00:00:00'
|
tomorrow_start = tomorrow + ' 00:00:00'
|
||||||
@@ -422,19 +427,22 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
if not item.route_id:
|
if not item.route_id:
|
||||||
raise UserError('【工件配送】明细中请选择【任务路线】')
|
raise UserError('【工件配送】明细中请选择【任务路线】')
|
||||||
else:
|
else:
|
||||||
if item.is_cnc_program_down is True:
|
if self.state == 'done':
|
||||||
if item.status == '待下发':
|
if item.is_cnc_program_down is True:
|
||||||
return {
|
if item.status == '待下发':
|
||||||
'name': _('确认'),
|
return {
|
||||||
'type': 'ir.actions.act_window',
|
'name': _('确认'),
|
||||||
'view_mode': 'form',
|
'type': 'ir.actions.act_window',
|
||||||
'res_model': 'sf.workpiece.delivery.wizard',
|
'view_mode': 'form',
|
||||||
'target': 'new',
|
'res_model': 'sf.workpiece.delivery.wizard',
|
||||||
'context': {
|
'target': 'new',
|
||||||
'default_workorder_id': self.id,
|
'context': {
|
||||||
}}
|
'default_workorder_id': self.id,
|
||||||
|
}}
|
||||||
|
else:
|
||||||
|
raise UserError(_("该制造订单还未下发CNC程序单,无法进行工件配送"))
|
||||||
else:
|
else:
|
||||||
raise UserError(_("该制造订单还未下发CNC程序单,无法进行工件配送"))
|
raise UserError(_("该工单暂未完成,无法进行工件配送"))
|
||||||
|
|
||||||
# 拼接工单对象属性值
|
# 拼接工单对象属性值
|
||||||
def json_workorder_str(self, k, production, route):
|
def json_workorder_str(self, k, production, route):
|
||||||
@@ -485,9 +493,8 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
|
|
||||||
def _json_workpiece_delivery_list(self, production):
|
def _json_workpiece_delivery_list(self, production):
|
||||||
return [
|
return [
|
||||||
[0, '', {'production_id': production.id, 'type': '上产线', 'delivery_num': '%s-%s' % (production.name, 1)}],
|
[0, '', {'production_id': production.id, 'type': '上产线'}],
|
||||||
[0, '',
|
[0, '', {'production_id': production.id, 'type': '下产线'}]]
|
||||||
{'production_id': production.id, 'type': '下产线', 'delivery_num': '%s-%s' % (production.name, 2)}]]
|
|
||||||
|
|
||||||
# 拼接工单对象属性值(表面工艺)
|
# 拼接工单对象属性值(表面工艺)
|
||||||
def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id):
|
def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id):
|
||||||
@@ -632,6 +639,33 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
# 'domain': [('production_id', '=', self.id)],
|
# 'domain': [('production_id', '=', self.id)],
|
||||||
# 'target':'new'
|
# 'target':'new'
|
||||||
# }
|
# }
|
||||||
|
@api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state')
|
||||||
|
def _compute_state(self):
|
||||||
|
for workorder in self:
|
||||||
|
if workorder.routing_type == '装夹预调':
|
||||||
|
if not workorder.cnc_ids:
|
||||||
|
workorder.state = 'waiting'
|
||||||
|
else:
|
||||||
|
for item in workorder.cnc_ids:
|
||||||
|
functional_cutting_tool = self.env['sf.functional.cutting.tool.entity'].search(
|
||||||
|
[('tool_name_id.name', '=', item.cutting_tool_name)])
|
||||||
|
if not functional_cutting_tool:
|
||||||
|
workorder.state = 'waiting'
|
||||||
|
if workorder.state == 'pending':
|
||||||
|
if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
|
||||||
|
workorder.state = 'ready' if workorder.production_id.reservation_state == 'assigned' else 'waiting'
|
||||||
|
continue
|
||||||
|
if workorder.state not in ('waiting', 'ready'):
|
||||||
|
continue
|
||||||
|
if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
|
||||||
|
workorder.state = 'pending'
|
||||||
|
continue
|
||||||
|
if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'):
|
||||||
|
continue
|
||||||
|
if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting':
|
||||||
|
workorder.state = 'ready'
|
||||||
|
elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready':
|
||||||
|
workorder.state = 'waiting'
|
||||||
|
|
||||||
def recreateManufacturingOrWorkerOrder(self):
|
def recreateManufacturingOrWorkerOrder(self):
|
||||||
"""
|
"""
|
||||||
@@ -777,14 +811,11 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
raise UserError("请对前置三元检测定位参数进行计算定位")
|
raise UserError("请对前置三元检测定位参数进行计算定位")
|
||||||
if not self.rfid_code:
|
if not self.rfid_code:
|
||||||
raise UserError("请扫RFID码进行绑定")
|
raise UserError("请扫RFID码进行绑定")
|
||||||
self.workpiece_delivery_ids[0].write({'status': '待下发'})
|
|
||||||
|
|
||||||
if self.routing_type == '解除装夹':
|
if self.routing_type == '解除装夹':
|
||||||
'''
|
'''
|
||||||
记录结束时间
|
记录结束时间
|
||||||
'''
|
'''
|
||||||
self.date_finished = datetime.now()
|
self.date_finished = datetime.now()
|
||||||
|
|
||||||
if self.picking_out_id:
|
if self.picking_out_id:
|
||||||
picking_out = self.env['stock.picking'].search([('id', '=', self.picking_out_id.id)])
|
picking_out = self.env['stock.picking'].search([('id', '=', self.picking_out_id.id)])
|
||||||
if picking_out.workorder_out_id:
|
if picking_out.workorder_out_id:
|
||||||
@@ -821,6 +852,8 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
self.process_state = '已完工'
|
self.process_state = '已完工'
|
||||||
self.production_id.button_mark_done1()
|
self.production_id.button_mark_done1()
|
||||||
# self.production_id.state = 'done'
|
# self.production_id.state = 'done'
|
||||||
|
# if self.routing_type == '装夹预调':
|
||||||
|
# self.workpiece_delivery_ids.write({''})
|
||||||
|
|
||||||
# 将FTP的检测报告文件下载到临时目录
|
# 将FTP的检测报告文件下载到临时目录
|
||||||
def download_reportfile_tmp(self, workorder, reportpath):
|
def download_reportfile_tmp(self, workorder, reportpath):
|
||||||
@@ -918,6 +951,9 @@ class CNCprocessing(models.Model):
|
|||||||
if workpiece_delivery:
|
if workpiece_delivery:
|
||||||
for item in workpiece_delivery:
|
for item in workpiece_delivery:
|
||||||
item.is_cnc_program_down = True
|
item.is_cnc_program_down = True
|
||||||
|
if item.workorder_id.state == 'waiting':
|
||||||
|
item.workorder_id.state = 'ready'
|
||||||
|
|
||||||
# cnc_workorder.time_ids.date_end = datetime.now()
|
# cnc_workorder.time_ids.date_end = datetime.now()
|
||||||
# cnc_workorder.button_finish()
|
# cnc_workorder.button_finish()
|
||||||
|
|
||||||
@@ -1096,12 +1132,11 @@ class WorkPieceDelivery(models.Model):
|
|||||||
_name = "sf.workpiece.delivery"
|
_name = "sf.workpiece.delivery"
|
||||||
_description = '工件配送'
|
_description = '工件配送'
|
||||||
|
|
||||||
delivery_num = fields.Char('工件配送编码')
|
name = fields.Char('单据编号')
|
||||||
workorder_id = fields.Many2one('mrp.workorder', string='工单', readonly=True)
|
workorder_id = fields.Many2one('mrp.workorder', string='工单', readonly=True)
|
||||||
|
workorder_state = fields.Selection(related='workorder_id.state', string='工单状态')
|
||||||
production_id = fields.Many2one('mrp.production', string='制造订单号', readonly=True)
|
production_id = fields.Many2one('mrp.production', string='制造订单号', readonly=True)
|
||||||
production_line_id = fields.Many2one('sf.production.line', compute='_compute_production_line_id',
|
production_line_id = fields.Many2one('sf.production.line', string='目的生产线')
|
||||||
string='目的生产线', readonly=True,
|
|
||||||
store=True)
|
|
||||||
plan_start_processing_time = fields.Datetime('计划开始加工时间', readonly=True)
|
plan_start_processing_time = fields.Datetime('计划开始加工时间', readonly=True)
|
||||||
|
|
||||||
route_id = fields.Many2one('sf.agv.task.route', '任务路线')
|
route_id = fields.Many2one('sf.agv.task.route', '任务路线')
|
||||||
@@ -1115,9 +1150,25 @@ class WorkPieceDelivery(models.Model):
|
|||||||
status = fields.Selection(
|
status = fields.Selection(
|
||||||
[('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送')], string='状态', default='待下发')
|
[('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送')], string='状态', default='待下发')
|
||||||
is_cnc_program_down = fields.Boolean('程序是否下发', default=False)
|
is_cnc_program_down = fields.Boolean('程序是否下发', default=False)
|
||||||
|
rfid_code = fields.Char('rfid码')
|
||||||
|
active = fields.Boolean(string="有效", default=True)
|
||||||
|
|
||||||
# @api.model
|
@api.model
|
||||||
# def create(self, vals):
|
def create(self, vals):
|
||||||
|
if vals.get('name', '/') == '/' or vals.get('name', '/') is False:
|
||||||
|
vals['name'] = self.env['ir.sequence'].next_by_code('sf.workpiece.delivery') or '/'
|
||||||
|
obj = super(WorkPieceDelivery, self).create(vals)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def action_delivery_history(self):
|
||||||
|
return {
|
||||||
|
'name': _('配送历史'),
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'view_mode': 'tree',
|
||||||
|
'res_model': 'sf.workpiece.delivery',
|
||||||
|
'view_id': self.env.ref('sf_manufacturing.sf_workpiece_delivery_empty_racks_tree').id,
|
||||||
|
'domain': [('type', '=', '运送空料架'), ('route_id', '=', self.route_id.id), ('name', 'ilike', 'WDO')]
|
||||||
|
}
|
||||||
|
|
||||||
@api.onchange('route_id')
|
@api.onchange('route_id')
|
||||||
def onchange_route(self):
|
def onchange_route(self):
|
||||||
@@ -1128,6 +1179,7 @@ class WorkPieceDelivery(models.Model):
|
|||||||
# 工件配送
|
# 工件配送
|
||||||
def button_delivery(self):
|
def button_delivery(self):
|
||||||
delivery_ids = []
|
delivery_ids = []
|
||||||
|
production_ids = []
|
||||||
is_cnc_down = 0
|
is_cnc_down = 0
|
||||||
is_not_production_line = 0
|
is_not_production_line = 0
|
||||||
is_not_route = 0
|
is_not_route = 0
|
||||||
@@ -1138,29 +1190,44 @@ class WorkPieceDelivery(models.Model):
|
|||||||
num = 0
|
num = 0
|
||||||
for item in self:
|
for item in self:
|
||||||
num += 1
|
num += 1
|
||||||
if num > 4:
|
|
||||||
raise UserError('仅限于配送1-4个制造订单,请重新选择')
|
|
||||||
if item.route_id:
|
|
||||||
if same_route_id is None:
|
|
||||||
same_route_id = item.route_id.id
|
|
||||||
if item.route_id.id != same_route_id:
|
|
||||||
is_not_route += 1
|
|
||||||
else:
|
|
||||||
raise UserError('请选择【任务路线】再进行配送')
|
|
||||||
if production_type is None:
|
if production_type is None:
|
||||||
production_type = item.type
|
production_type = item.type
|
||||||
if production_type != item.type:
|
if item.type == "运送空料架":
|
||||||
raise UserError('请选择类型为%s的制造订单进行配送' % production_type)
|
if num >= 2:
|
||||||
if down_status != item.status:
|
raise UserError('仅选择一条路线进行配送,请重新选择')
|
||||||
raise UserError('请选择状态为【待下发】的制造订单进行配送')
|
else:
|
||||||
if same_production_line_id is None:
|
delivery_ids.append(item.id)
|
||||||
same_production_line_id = item.production_line_id.id
|
else:
|
||||||
if item.production_line_id.id != same_production_line_id:
|
if num > 4:
|
||||||
is_not_production_line += 1
|
raise UserError('仅限于配送1-4个制造订单,请重新选择')
|
||||||
if item.is_cnc_program_down is False:
|
if item.status in ['待配送', '已配送']:
|
||||||
is_cnc_down += 1
|
raise UserError('请选择状态为【待下发】的制造订单进行配送')
|
||||||
if is_cnc_down == 0 and is_not_production_line == 0 and is_not_route == 0:
|
if item.route_id:
|
||||||
delivery_ids.append(item.id)
|
if same_route_id is None:
|
||||||
|
same_route_id = item.route_id.id
|
||||||
|
if item.route_id.id != same_route_id:
|
||||||
|
is_not_route += 1
|
||||||
|
else:
|
||||||
|
raise UserError('请选择【任务路线】再进行配送')
|
||||||
|
if production_type != item.type:
|
||||||
|
raise UserError('请选择类型为%s的制造订单进行配送' % production_type)
|
||||||
|
if down_status != item.status:
|
||||||
|
up_workpiece = self.search([('type', '=', '上产线'), ('production_id', '=', item.production_id),
|
||||||
|
('status', '=', '待下发')])
|
||||||
|
if up_workpiece:
|
||||||
|
raise UserError('您所选择的制造订单暂未上产线,请在上产线后再进行配送')
|
||||||
|
else:
|
||||||
|
raise UserError('请选择状态为【待下发】的制造订单进行配送')
|
||||||
|
|
||||||
|
if same_production_line_id is None:
|
||||||
|
same_production_line_id = item.production_line_id.id
|
||||||
|
if item.production_line_id.id != same_production_line_id:
|
||||||
|
is_not_production_line += 1
|
||||||
|
if item.is_cnc_program_down is False:
|
||||||
|
is_cnc_down += 1
|
||||||
|
if is_cnc_down == 0 and is_not_production_line == 0 and is_not_route == 0:
|
||||||
|
delivery_ids.append(item.id)
|
||||||
|
production_ids.append(item.production_id.id)
|
||||||
if is_cnc_down >= 1:
|
if is_cnc_down >= 1:
|
||||||
raise UserError('您所选择制造订单的【CNC程序】暂未下发,请在程序下发后再进行配送')
|
raise UserError('您所选择制造订单的【CNC程序】暂未下发,请在程序下发后再进行配送')
|
||||||
if is_not_production_line >= 1:
|
if is_not_production_line >= 1:
|
||||||
@@ -1178,9 +1245,17 @@ class WorkPieceDelivery(models.Model):
|
|||||||
'target': 'new',
|
'target': 'new',
|
||||||
'context': {
|
'context': {
|
||||||
'default_delivery_ids': [(6, 0, delivery_ids)],
|
'default_delivery_ids': [(6, 0, delivery_ids)],
|
||||||
|
'default_production_ids': [(6, 0, production_ids)],
|
||||||
|
'default_destination_production_line_id': same_production_line_id,
|
||||||
|
'default_route_id': same_route_id,
|
||||||
|
'default_type': production_type,
|
||||||
}}
|
}}
|
||||||
else:
|
else:
|
||||||
raise UserError("您所选择制造订单的【任务路线】的【终点接驳站】已占用,请在该接驳站空闲时进行配送")
|
if self.type == '运送空料架':
|
||||||
|
raise UserError("您所选择的【任务路线】的【终点接驳站】已占用,请在该接驳站空闲时进行配送")
|
||||||
|
else:
|
||||||
|
raise UserError(
|
||||||
|
"您所选择制造订单的【任务路线】的【终点接驳站】已占用,请在该接驳站空闲时或选择其他路线进行配送")
|
||||||
|
|
||||||
# 验证agv站点是否可用
|
# 验证agv站点是否可用
|
||||||
def _check_avgsite_state(self):
|
def _check_avgsite_state(self):
|
||||||
@@ -1189,15 +1264,18 @@ class WorkPieceDelivery(models.Model):
|
|||||||
if agv_site:
|
if agv_site:
|
||||||
agv_site.update_site_state()
|
agv_site.update_site_state()
|
||||||
for item in self:
|
for item in self:
|
||||||
if item.type in ["上产线", "下产线"]:
|
logging.info('工件配送-起点状态:%s-%s' % (
|
||||||
logging.info('工件配送-起点状态:%s-%s' % (
|
item.feeder_station_start_id.name, item.feeder_station_start_id.state))
|
||||||
item.feeder_station_start_id.name, item.feeder_station_start_id.state))
|
logging.info('工件配送-终点状态:%s-%s' % (
|
||||||
logging.info('工件配送-终点状态:%s-%s' % (
|
item.feeder_station_destination_id.name, item.feeder_station_destination_id.state))
|
||||||
item.feeder_station_destination_id.name, item.feeder_station_destination_id.state))
|
if item.type in ['上产线', '下产线']:
|
||||||
if (
|
if (
|
||||||
item.feeder_station_start_id.state == '占用' and item.feeder_station_destination_id.state == '空闲') or (
|
item.feeder_station_start_id.state == '占用' and item.feeder_station_destination_id.state == '空闲') or (
|
||||||
item.feeder_station_start_id.state == '空闲' and item.feeder_station_destination_id.state == '空闲'):
|
item.feeder_station_start_id.state == '空闲' and item.feeder_station_destination_id.state == '空闲'):
|
||||||
is_free = True
|
is_free = True
|
||||||
|
else:
|
||||||
|
if item.feeder_station_destination_id.state == '空闲':
|
||||||
|
is_free = True
|
||||||
logging.info('is_free:%s' % is_free)
|
logging.info('is_free:%s' % is_free)
|
||||||
return is_free
|
return is_free
|
||||||
|
|
||||||
@@ -1208,12 +1286,23 @@ class WorkPieceDelivery(models.Model):
|
|||||||
delivery_Arr = []
|
delivery_Arr = []
|
||||||
feeder_station_start = None
|
feeder_station_start = None
|
||||||
feeder_station_destination = None
|
feeder_station_destination = None
|
||||||
|
route_id = None
|
||||||
for item in self:
|
for item in self:
|
||||||
if feeder_station_start is None:
|
delivery_Arr.append(item.name)
|
||||||
feeder_station_start = item.feeder_station_start_id.name
|
if item.type in ['上产线', '下产线']:
|
||||||
if feeder_station_destination is None:
|
if route_id is None:
|
||||||
feeder_station_destination = item.feeder_station_destination_id.name
|
route_id = item.route_id.id
|
||||||
delivery_Arr.append(item.delivery_num)
|
if feeder_station_start is None:
|
||||||
|
feeder_station_start = item.feeder_station_start_id.name
|
||||||
|
if feeder_station_destination is None:
|
||||||
|
feeder_station_destination = item.feeder_station_destination_id.name
|
||||||
|
item.route_id = route_id
|
||||||
|
else:
|
||||||
|
self = self.create(
|
||||||
|
{'name': self.env['ir.sequence'].next_by_code('sf.workpiece.delivery'),
|
||||||
|
'route_id': self.route_id.id,
|
||||||
|
'feeder_station_start_id': self.feeder_station_start_id.id,
|
||||||
|
'feeder_station_destination_id': self.feeder_station_destination_id.id})
|
||||||
delivery_str = ','.join(map(str, delivery_Arr))
|
delivery_str = ','.join(map(str, delivery_Arr))
|
||||||
if feeder_station_start is not None:
|
if feeder_station_start is not None:
|
||||||
positionCode_Arr.append({
|
positionCode_Arr.append({
|
||||||
@@ -1242,24 +1331,19 @@ class WorkPieceDelivery(models.Model):
|
|||||||
req_codes = ret['reqCode'].split(',')
|
req_codes = ret['reqCode'].split(',')
|
||||||
for delivery_item in self:
|
for delivery_item in self:
|
||||||
for req_code in req_codes:
|
for req_code in req_codes:
|
||||||
if delivery_item.delivery_num == req_code.strip():
|
if delivery_item.name == req_code.strip():
|
||||||
logging.info('delivery_num:%s' % delivery_item.delivery_num)
|
logging.info('delivery_item-name:%s' % delivery_item.name)
|
||||||
delivery_item.write({
|
delivery_item.write({
|
||||||
'task_delivery_time': fields.Datetime.now(),
|
'task_delivery_time': fields.Datetime.now(),
|
||||||
'status': '待配送'
|
'status': '待配送'
|
||||||
})
|
})
|
||||||
delivery_item.workorder_id.write({'is_delivery': True})
|
if delivery_item == "上产线":
|
||||||
|
delivery_item.workorder_id.write({'is_delivery': True})
|
||||||
else:
|
else:
|
||||||
raise UserError(ret['message'])
|
raise UserError(ret['message'])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.info('config-e:%s' % e)
|
logging.info('config-e:%s' % e)
|
||||||
raise UserError("工件配送请求agv失败")
|
raise UserError("工件配送请求agv失败:%s" % e)
|
||||||
|
|
||||||
@api.onchange('production_id.production_line_id')
|
|
||||||
def _compute_production_line_id(self):
|
|
||||||
if self.production_id.production_line_id:
|
|
||||||
self.production_line_id = self.production_id.production_line_id.id
|
|
||||||
self.plan_start_processing_time = self.production_id.plan_start_processing_time
|
|
||||||
|
|
||||||
@api.depends('task_delivery_time', 'task_completion_time')
|
@api.depends('task_delivery_time', 'task_completion_time')
|
||||||
def _compute_delivery_duration(self):
|
def _compute_delivery_duration(self):
|
||||||
|
|||||||
@@ -133,3 +133,4 @@ access_sf_workpiece_delivery_group_plan_dispatch,sf.workpiece.delivery,sf_manufa
|
|||||||
|
|
||||||
access_sf_agv_site_group_sf_order_user,sf_agv_site_group_sf_order_user,model_sf_agv_site,sf_base.group_sf_order_user,1,1,1,0
|
access_sf_agv_site_group_sf_order_user,sf_agv_site_group_sf_order_user,model_sf_agv_site,sf_base.group_sf_order_user,1,1,1,0
|
||||||
access_sf_agv_task_route_group_sf_order_user,sf_agv_task_route_group_sf_order_user,model_sf_agv_task_route,sf_base.group_sf_order_user,1,1,1,0
|
access_sf_agv_task_route_group_sf_order_user,sf_agv_task_route_group_sf_order_user,model_sf_agv_task_route,sf_base.group_sf_order_user,1,1,1,0
|
||||||
|
access_center_control_interface_log_admin,center_control_interface_log_admin,model_center_control_interface_log,base.group_system,1,1,1,0
|
||||||
|
@@ -34,7 +34,8 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree editable="bottom">
|
<tree editable="bottom">
|
||||||
<field name="name" required="1"/>
|
<field name="name" required="1"/>
|
||||||
<field name="type" readonly="1"/>
|
<field name="type" readonly="1" string="任务类型"/>
|
||||||
|
<field name="route_type" string="类型"/>
|
||||||
<field name="start_site_id" required="1" options="{'no_create': True}" string="起点接驳站"/>
|
<field name="start_site_id" required="1" options="{'no_create': True}" string="起点接驳站"/>
|
||||||
<field name="end_site_id" required="1" options="{'no_create': True}" string="终点接驳站"/>
|
<field name="end_site_id" required="1" options="{'no_create': True}" string="终点接驳站"/>
|
||||||
<field name="destination_production_line_id" required="1" options="{'no_create': True}"/>
|
<field name="destination_production_line_id" required="1" options="{'no_create': True}"/>
|
||||||
@@ -54,4 +55,34 @@
|
|||||||
sequence="13"
|
sequence="13"
|
||||||
action="action_agv_task_route_form"/>
|
action="action_agv_task_route_form"/>
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="center_control_interface_logging_tree_view">
|
||||||
|
<field name="model">center_control.interface.log</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="Logs" create="0" edit="0" delete="0">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="content"/>
|
||||||
|
<field name="interface_call_date"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="center_control_interface_logging_search_view">
|
||||||
|
<field name="model">center_control.interface.log</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="Logs">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="interface_call_date"/>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window" id="center_control_interface_logging_act">
|
||||||
|
<field name="name">中控调用日志</field>
|
||||||
|
<field name="res_model">center_control.interface.log</field>
|
||||||
|
<field name="view_mode">tree</field>
|
||||||
|
</record>
|
||||||
|
<menuitem parent="base.next_id_9" id="center_control_interface_logging_menu"
|
||||||
|
action="center_control_interface_logging_act"/>
|
||||||
</odoo>
|
</odoo>
|
||||||
@@ -80,12 +80,12 @@
|
|||||||
<field name="schedule_state" invisible='1'/>
|
<field name="schedule_state" invisible='1'/>
|
||||||
<field name="manual_quotation" readonly="1"/>
|
<field name="manual_quotation" readonly="1"/>
|
||||||
<field name="programming_state" readonly="1"/>
|
<field name="programming_state" readonly="1"/>
|
||||||
<field name="production_line_id" readonly="1"/>
|
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='user_id']" position="before">
|
<xpath expr="//field[@name='user_id']" position="before">
|
||||||
<field name="plan_start_processing_time" readonly="1"/>
|
<field name="plan_start_processing_time" readonly="1"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='user_id']" position="after">
|
<xpath expr="//field[@name='user_id']" position="after">
|
||||||
|
<field name="production_line_id" readonly="1"/>
|
||||||
<field name="production_line_state" readonly="1"/>
|
<field name="production_line_state" readonly="1"/>
|
||||||
<field name="part_number"/>
|
<field name="part_number"/>
|
||||||
<field name="part_drawing"/>
|
<field name="part_drawing"/>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
<attribute name="attrs">{'invisible':
|
<attribute name="attrs">{'invisible':
|
||||||
['|',("user_permissions","=",False),("name","=","获取CNC加工程序")]}
|
['|',("user_permissions","=",False),("name","=","获取CNC加工程序")]}
|
||||||
</attribute>
|
</attribute>
|
||||||
<!-- <attribute name="string">停工</attribute> -->
|
<!-- <attribute name="string">停工</attribute> -->
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//button[@name='action_open_wizard']" position="attributes">
|
<xpath expr="//button[@name='action_open_wizard']" position="attributes">
|
||||||
<attribute name="invisible">1</attribute>
|
<attribute name="invisible">1</attribute>
|
||||||
@@ -111,36 +111,38 @@
|
|||||||
<field name='name' invisible="1"/>
|
<field name='name' invisible="1"/>
|
||||||
<field name='is_delivery' invisible="1"/>
|
<field name='is_delivery' invisible="1"/>
|
||||||
<!-- 工单form页面的开始停工按钮等 -->
|
<!-- 工单form页面的开始停工按钮等 -->
|
||||||
<!-- <button name="button_start" type="object" string="开始" class="btn-success" -->
|
<!-- <button name="button_start" type="object" string="开始" class="btn-success" -->
|
||||||
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'not in', ('pending_processing', 'pending_cam', 'pending_era_cam')), ('state','!=','ready'), ('routing_type', 'not in', ('装夹预调', 'CNC加工', '解除装夹'))]}" -->
|
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'not in', ('pending_processing', 'pending_cam', 'pending_era_cam')), ('state','!=','ready'), ('routing_type', 'not in', ('装夹预调', 'CNC加工', '解除装夹'))]}" -->
|
||||||
<!-- groups="sf_base.group_sf_mrp_user"/> -->
|
<!-- groups="sf_base.group_sf_mrp_user"/> -->
|
||||||
<!-- <button name="button_pending" type="object" string="暂停" class="btn-warning" -->
|
<!-- <button name="button_pending" type="object" string="暂停" class="btn-warning" -->
|
||||||
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'not in', ('pending_processing', 'pending_cam', 'pending_era_cam')), ('state','!=','progress'), ('routing_type', 'not in', ('装夹预调', 'CNC加工', '解除装夹'))]}" -->
|
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'not in', ('pending_processing', 'pending_cam', 'pending_era_cam')), ('state','!=','progress'), ('routing_type', 'not in', ('装夹预调', 'CNC加工', '解除装夹'))]}" -->
|
||||||
<!-- groups="sf_base.group_sf_mrp_user"/> -->
|
<!-- groups="sf_base.group_sf_mrp_user"/> -->
|
||||||
<!-- <button name="button_finish" type="object" string="完成" class="btn-success" -->
|
<!-- <button name="button_finish" type="object" string="完成" class="btn-success" -->
|
||||||
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'not in', ('pending_processing', 'pending_cam', 'pending_era_cam')), ('state','!=','progress'), ('routing_type', 'not in', ('装夹预调', 'CNC加工', '解除装夹'))]}" -->
|
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'not in', ('pending_processing', 'pending_cam', 'pending_era_cam')), ('state','!=','progress'), ('routing_type', 'not in', ('装夹预调', 'CNC加工', '解除装夹'))]}" -->
|
||||||
<!-- groups="sf_base.group_sf_mrp_user" confirm="是否确认完工"/> -->
|
<!-- groups="sf_base.group_sf_mrp_user" confirm="是否确认完工"/> -->
|
||||||
|
|
||||||
<button name="button_start" type="object" string="开始" class="btn-success"
|
<button name="button_start" type="object" string="开始" class="btn-success"
|
||||||
attrs="{'invisible': ['|', '|', '|', ('production_state','in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')), ('is_user_working', '!=', False)]}"/>
|
attrs="{'invisible': ['|', '|', '|', ('production_state','in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')), ('is_user_working', '!=', False)]}"/>
|
||||||
<button name="button_pending" type="object" string="暂停" class="btn-warning"
|
<button name="button_pending" type="object" string="暂停" class="btn-warning"
|
||||||
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"/>
|
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"/>
|
||||||
<button name="button_finish" type="object" string="完成" class="btn-success"
|
<button name="button_finish" type="object" string="完成" class="btn-success"
|
||||||
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"/>
|
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"/>
|
||||||
|
|
||||||
<button name="%(mrp.act_mrp_block_workcenter_wo)d" type="action" string="阻塞" context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
|
<button name="%(mrp.act_mrp_block_workcenter_wo)d" type="action" string="阻塞"
|
||||||
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked')]}"/>
|
context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
|
||||||
<button name="button_unblock" type="object" string="取消阻塞" context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
|
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked')]}"/>
|
||||||
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked')]}"/>
|
<button name="button_unblock" type="object" string="取消阻塞"
|
||||||
|
context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
|
||||||
|
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked')]}"/>
|
||||||
|
|
||||||
<!-- <button name="%(mrp.act_mrp_block_workcenter_wo)d" type="action" string="停工" -->
|
<!-- <button name="%(mrp.act_mrp_block_workcenter_wo)d" type="action" string="停工" -->
|
||||||
<!-- context="{'default_workcenter_id': workcenter_id}" class="btn-danger" -->
|
<!-- context="{'default_workcenter_id': workcenter_id}" class="btn-danger" -->
|
||||||
<!-- groups="sf_base.group_sf_mrp_user" -->
|
<!-- groups="sf_base.group_sf_mrp_user" -->
|
||||||
<!-- attrs="{'invisible': ['|', ('production_state', '!=', 'pending_processing'), ('state','!=','progress')]}"/> -->
|
<!-- attrs="{'invisible': ['|', ('production_state', '!=', 'pending_processing'), ('state','!=','progress')]}"/> -->
|
||||||
<!-- <button name="button_unblock" type="object" string="Unblock" -->
|
<!-- <button name="button_unblock" type="object" string="Unblock" -->
|
||||||
<!-- context="{'default_workcenter_id': workcenter_id}" class="btn-danger" -->
|
<!-- context="{'default_workcenter_id': workcenter_id}" class="btn-danger" -->
|
||||||
<!-- groups="sf_base.group_sf_mrp_user" -->
|
<!-- groups="sf_base.group_sf_mrp_user" -->
|
||||||
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('state','=','done')]}"/> -->
|
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('state','=','done')]}"/> -->
|
||||||
<button name="button_workpiece_delivery" type="object" string="工件配送" class="btn-primary"
|
<button name="button_workpiece_delivery" type="object" string="工件配送" class="btn-primary"
|
||||||
attrs="{'invisible': ['|',('routing_type','!=','装夹预调'),('is_delivery','=',True)]}"/>
|
attrs="{'invisible': ['|',('routing_type','!=','装夹预调'),('is_delivery','=',True)]}"/>
|
||||||
|
|
||||||
@@ -196,6 +198,8 @@
|
|||||||
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/>
|
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/>
|
||||||
<field name="equipment_id"
|
<field name="equipment_id"
|
||||||
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/>
|
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/>
|
||||||
|
<field name="production_line_id"
|
||||||
|
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/>
|
||||||
<field name="production_line_state"
|
<field name="production_line_state"
|
||||||
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/>
|
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/>
|
||||||
<field name="functional_fixture_id"
|
<field name="functional_fixture_id"
|
||||||
@@ -602,8 +606,7 @@
|
|||||||
decoration-warning="status == '待下发'"
|
decoration-warning="status == '待下发'"
|
||||||
decoration-danger="status == '待配送'"/>
|
decoration-danger="status == '待配送'"/>
|
||||||
<field name="production_id"/>
|
<field name="production_id"/>
|
||||||
<field name="type"/>
|
<field name="type" readonly="1"/>
|
||||||
<!-- <field name="delivery_num" />-->
|
|
||||||
<field name="production_line_id" options="{'no_create': True}"/>
|
<field name="production_line_id" options="{'no_create': True}"/>
|
||||||
<field name="route_id" options="{'no_create': True}"/>
|
<field name="route_id" options="{'no_create': True}"/>
|
||||||
<field name="feeder_station_start_id" readonly="1" force_save="1"/>
|
<field name="feeder_station_start_id" readonly="1" force_save="1"/>
|
||||||
@@ -621,9 +624,9 @@
|
|||||||
<field name="model">sf.workpiece.delivery</field>
|
<field name="model">sf.workpiece.delivery</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search string="工件配送">
|
<search string="工件配送">
|
||||||
<filter string="待下发" name="on_down" domain="[('status', '=', '待下发'),('type','=',['上产线'])]"/>
|
<filter string="上产线" name="up" domain="[('type', '=', '上产线')]"/>
|
||||||
<filter string="上产线" name="down" domain="[('type', '=', '上产线')]"/>
|
<filter string="下产线" name="down" domain="[('type', '=', '下产线' )]"/>
|
||||||
<filter string="下产线" name="up" domain="[('type', '=', '下产线')]"/>
|
<field name="rfid_code"/>
|
||||||
<field name="production_id"/>
|
<field name="production_id"/>
|
||||||
<field name="feeder_station_start_id"/>
|
<field name="feeder_station_start_id"/>
|
||||||
<field name="production_line_id"/>
|
<field name="production_line_id"/>
|
||||||
@@ -644,9 +647,68 @@
|
|||||||
<field name="name">工件配送</field>
|
<field name="name">工件配送</field>
|
||||||
<field name="res_model">sf.workpiece.delivery</field>
|
<field name="res_model">sf.workpiece.delivery</field>
|
||||||
<field name="search_view_id" ref="sf_workpiece_delivery_search"/>
|
<field name="search_view_id" ref="sf_workpiece_delivery_search"/>
|
||||||
<field name="context">{'search_default_on_down':1}</field>
|
<!-- <field name="context">{'search_default_on_up':1}</field>-->
|
||||||
<field name="view_mode">tree,search</field>
|
<field name="view_mode">tree,search</field>
|
||||||
<field name="domain">[('type','in',['上产线','下产线'])]</field>
|
<field name="domain">[('type','in',['上产线','下产线']),('workorder_state','=','done')]</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<!--=========================================运送空料架列表======================================-->
|
||||||
|
<record id="sf_workpiece_delivery_empty_racks_template_tree" model="ir.ui.view">
|
||||||
|
<field name="name">空料架配送</field>
|
||||||
|
<field name="model">sf.workpiece.delivery</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="工件配送" class="center" create="0" edit="0" delete="0">
|
||||||
|
<header>
|
||||||
|
<button name="button_delivery" type="object" string="配送" class="oe_highlight"/>
|
||||||
|
</header>
|
||||||
|
<field name="name" string="路线名称" readonly="1"/>
|
||||||
|
<field name="route_id" options="{'no_create': True}"/>
|
||||||
|
<field name="feeder_station_start_id" readonly="1"/>
|
||||||
|
<field name="feeder_station_destination_id" readonly="1"/>
|
||||||
|
<button name="action_delivery_history" type="object" class="btn btn-link text-info" icon="fa-history"
|
||||||
|
string="历史"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="sf_workpiece_delivery_empty_racks_tree" model="ir.ui.view">
|
||||||
|
<field name="name">空料架配送</field>
|
||||||
|
<field name="model">sf.workpiece.delivery</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="运送空料架" class="center" create="0" delete="0" edit="0">
|
||||||
|
<field name="status"/>
|
||||||
|
<field name="route_id"/>
|
||||||
|
<field name="feeder_station_start_id"/>
|
||||||
|
<field name="feeder_station_destination_id"/>
|
||||||
|
<field name="task_delivery_time"/>
|
||||||
|
<field name="task_completion_time"/>
|
||||||
|
<field name="delivery_duration" widget="float_time"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="sf_workpiece_delivery_empty_racks_search" model="ir.ui.view">
|
||||||
|
<field name="name">空料架配送</field>
|
||||||
|
<field name="model">sf.workpiece.delivery</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="运送空料架">
|
||||||
|
<field name="route_id"/>
|
||||||
|
<field name="feeder_station_start_id"/>
|
||||||
|
<field name="feeder_station_destination_id"/>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="sf_workpiece_delivery_empty_racks_act" model="ir.actions.act_window">
|
||||||
|
<field name="name">空料架配送</field>
|
||||||
|
<field name="res_model">sf.workpiece.delivery</field>
|
||||||
|
<field name="view_id" ref="sf_workpiece_delivery_empty_racks_template_tree"/>
|
||||||
|
<field name="search_view_id" ref="sf_workpiece_delivery_empty_racks_search"/>
|
||||||
|
<field name="view_mode">tree</field>
|
||||||
|
<field name="domain">[('type','in',['运送空料架']),('name','not ilike','WDO')]</field>
|
||||||
</record>
|
</record>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,32 @@
|
|||||||
<field name="model">sf.workpiece.delivery.wizard</field>
|
<field name="model">sf.workpiece.delivery.wizard</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form>
|
<form>
|
||||||
|
<sheet>
|
||||||
<field name="delivery_ids" invisible="True"/>
|
<field name="delivery_ids" invisible="True"/>
|
||||||
<field name="workorder_id" invisible="True"/>
|
<field name="workorder_id" invisible="True"/>
|
||||||
<div>是否确定配送?</div>
|
<field name="type" invisible="True"/>
|
||||||
<footer>
|
<group attrs="{'invisible': [('type', 'in', ['运送空料架'])]}">
|
||||||
<button string="确认" name="confirm" type="object" class="oe_highlight"/>
|
<field name="production_ids" readonly="1" widget="many2many_tags" string="制造订单号"/>
|
||||||
<button string="取消" class="btn btn-secondary" special="cancel"/>
|
<div class="o_address_format">
|
||||||
</footer>
|
<lable for="rfid_code"></lable>
|
||||||
|
<field name="rfid_code" class="o_address_zip"/>
|
||||||
|
<button name="recognize_production" string="识别" type="object" class="oe_highlight"/>
|
||||||
|
</div>
|
||||||
|
<field name="destination_production_line_id" readonly="1"/>
|
||||||
|
<field name="route_id"/>
|
||||||
|
</group>
|
||||||
|
<group attrs="{'invisible': [('type', 'in', ['运送空料架'])]}">
|
||||||
|
<field name="feeder_station_start_id" focesave="1" readonly="1"/>
|
||||||
|
<field name="feeder_station_destination_id" focesave="1" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<div attrs="{'invisible': [('type', 'in', ['上产线','下产线'])]}">
|
||||||
|
是否确定配送
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<button string="配送" name="confirm" type="object" class="oe_highlight"/>
|
||||||
|
<button string="取消" class="btn btn-secondary" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</sheet>
|
||||||
</form>
|
</form>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# Part of YiZuo. See LICENSE file for full copyright and licensing details.
|
# Part of YiZuo. See LICENSE file for full copyright and licensing details.
|
||||||
from odoo.exceptions import UserError, ValidationError
|
from odoo.exceptions import UserError, ValidationError
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from odoo import models, api, fields
|
from odoo import models, api, fields, _
|
||||||
|
|
||||||
|
|
||||||
class WorkpieceDeliveryWizard(models.TransientModel):
|
class WorkpieceDeliveryWizard(models.TransientModel):
|
||||||
@@ -10,10 +10,74 @@ class WorkpieceDeliveryWizard(models.TransientModel):
|
|||||||
_description = '工件配送'
|
_description = '工件配送'
|
||||||
|
|
||||||
delivery_ids = fields.Many2many('sf.workpiece.delivery', string='配送')
|
delivery_ids = fields.Many2many('sf.workpiece.delivery', string='配送')
|
||||||
|
rfid_code = fields.Char('rfid码')
|
||||||
workorder_id = fields.Many2one('mrp.workorder', string='工单')
|
workorder_id = fields.Many2one('mrp.workorder', string='工单')
|
||||||
|
production_ids = fields.Many2many('mrp.production', string='制造订单号')
|
||||||
|
destination_production_line_id = fields.Many2one('sf.production.line', '目的生产线')
|
||||||
|
route_id = fields.Many2one('sf.agv.task.route', '任务路线', domain=[('route_type', 'in', ['上产线', '下产线'])])
|
||||||
|
feeder_station_start_id = fields.Many2one('sf.agv.site', '起点接驳站')
|
||||||
|
feeder_station_destination_id = fields.Many2one('sf.agv.site', '目的接驳站')
|
||||||
|
type = fields.Selection(
|
||||||
|
[('上产线', '上产线'), ('下产线', '下产线'), ('运送空料架', '运送空料架')], string='类型')
|
||||||
|
|
||||||
def confirm(self):
|
def confirm(self):
|
||||||
|
if self.type != '运送空料架':
|
||||||
|
if not self.route_id:
|
||||||
|
raise UserError('请选择路线')
|
||||||
if self.workorder_id:
|
if self.workorder_id:
|
||||||
self.workorder_id.workpiece_delivery_ids[0]._delivery_avg()
|
self.workorder_id.workpiece_delivery_ids[0]._delivery_avg()
|
||||||
else:
|
else:
|
||||||
self.delivery_ids._delivery_avg()
|
is_not_production_line = 0
|
||||||
|
same_production_line_id = None
|
||||||
|
notsame_production_line_arr = []
|
||||||
|
for item in self.production_ids:
|
||||||
|
if same_production_line_id is None:
|
||||||
|
same_production_line_id = item.production_line_id.id
|
||||||
|
if item.production_line_id.id != same_production_line_id:
|
||||||
|
notsame_production_line_arr.append(item.name)
|
||||||
|
notsame_production_line_str = ','.join(map(str, notsame_production_line_arr))
|
||||||
|
if is_not_production_line >= 1:
|
||||||
|
raise UserError('制造订单号为%s的目的生产线不一致' % notsame_production_line_str)
|
||||||
|
else:
|
||||||
|
self.delivery_ids._delivery_avg()
|
||||||
|
|
||||||
|
def recognize_production(self):
|
||||||
|
# production_ids = []
|
||||||
|
# delivery_ids = []
|
||||||
|
if len(self.production_ids) > 4:
|
||||||
|
raise UserError('只能配送四个制造订单')
|
||||||
|
else:
|
||||||
|
if self.rfid_code:
|
||||||
|
wd = self.env['sf.workpiece.delivery'].search(
|
||||||
|
[('type', '=', self.delivery_ids[0].type), ('rfid_code', '=', self.rfid_code),
|
||||||
|
('status', '=', self.delivery_ids[0].status)])
|
||||||
|
if wd:
|
||||||
|
if wd.production_line_id.id == self.delivery_ids[0].production_line_id.id:
|
||||||
|
# production_ids.append(wd.production_id)
|
||||||
|
# delivery_ids.append(wd.id)
|
||||||
|
# 将对象添加到对应的同模型且是多对多类型里
|
||||||
|
self.production_ids |= wd.production_id
|
||||||
|
self.delivery_ids |= wd
|
||||||
|
self.rfid_code = False
|
||||||
|
# self.production_ids = [(6, 0, production_ids)]
|
||||||
|
# self.delivery_ids = [(6, 0, delivery_ids)]
|
||||||
|
else:
|
||||||
|
raise UserError('该rfid对应的制造订单号为%s的目的生产线不一致' % wd.production_id.name)
|
||||||
|
return {
|
||||||
|
'name': _('确认'),
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'view_mode': 'form',
|
||||||
|
'res_model': 'sf.workpiece.delivery.wizard',
|
||||||
|
'target': 'new',
|
||||||
|
'context': {
|
||||||
|
'default_delivery_ids': [(6, 0, self.delivery_ids.ids)],
|
||||||
|
'default_production_ids': [(6, 0, self.production_ids.ids)],
|
||||||
|
'default_route_id': self.delivery_ids[0].route_id.id,
|
||||||
|
'default_type': self.delivery_ids[0].type
|
||||||
|
}}
|
||||||
|
|
||||||
|
@api.onchange('route_id')
|
||||||
|
def onchange_route(self):
|
||||||
|
if self.route_id:
|
||||||
|
self.feeder_station_start_id = self.route_id.start_site_id.id
|
||||||
|
self.feeder_station_destination_id = self.route_id.end_site_id.id
|
||||||
|
|||||||
@@ -84,7 +84,8 @@ class sf_production_plan(models.Model):
|
|||||||
item.sudo().production_id.production_line_id = item.production_line_id.id
|
item.sudo().production_id.production_line_id = item.production_line_id.id
|
||||||
item.sudo().production_id.workorder_ids.filtered(
|
item.sudo().production_id.workorder_ids.filtered(
|
||||||
lambda b: b.routing_type == "装夹预调").workpiece_delivery_ids.write(
|
lambda b: b.routing_type == "装夹预调").workpiece_delivery_ids.write(
|
||||||
{'production_line_id': item.production_line_id.id})
|
{'production_line_id': item.production_line_id.id,
|
||||||
|
'plan_start_processing_time': item.plan_start_processing_time})
|
||||||
# item.sudo().production_id.plan_start_processing_time = item.date_planned_start
|
# item.sudo().production_id.plan_start_processing_time = item.date_planned_start
|
||||||
|
|
||||||
# @api.onchange('state')
|
# @api.onchange('state')
|
||||||
|
|||||||
@@ -306,6 +306,14 @@
|
|||||||
action="sf_manufacturing.sf_workpiece_delivery_act"
|
action="sf_manufacturing.sf_workpiece_delivery_act"
|
||||||
parent="mrp.menu_mrp_manufacturing"
|
parent="mrp.menu_mrp_manufacturing"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<menuitem
|
||||||
|
id="sf_workpiece_delivery__empty_racks_menu"
|
||||||
|
name="空料架配送"
|
||||||
|
sequence="11"
|
||||||
|
action="sf_manufacturing.sf_workpiece_delivery_empty_racks_act"
|
||||||
|
parent="mrp.menu_mrp_manufacturing"
|
||||||
|
/>
|
||||||
<!-- <menuitem -->
|
<!-- <menuitem -->
|
||||||
<!-- id="sale_custom_menu" -->
|
<!-- id="sale_custom_menu" -->
|
||||||
<!-- name="报价单" -->
|
<!-- name="报价单" -->
|
||||||
|
|||||||
Reference in New Issue
Block a user