diff --git a/sf_manufacturing/models/agv_setting.py b/sf_manufacturing/models/agv_setting.py index efdde900..62f4f633 100644 --- a/sf_manufacturing/models/agv_setting.py +++ b/sf_manufacturing/models/agv_setting.py @@ -42,7 +42,9 @@ class AgvTaskRoute(models.Model): name = fields.Char('名称') type = fields.Selection([ - ('F01', '搬运'), ], string='类型', default="F01") + ('F01', '搬运'), ], string='任务类型', default="F01") + route_type = fields.Selection([ + ('上产线', '上产线'), ('下产线', '下产线'), ('运送空料架', '运送空料架')], string='类型') start_site_id = fields.Many2one('sf.agv.site', '起点接驳站位置编号') end_site_id = fields.Many2one('sf.agv.site', '终点接驳站位置编号') destination_production_line_id = fields.Many2one('sf.production.line', '目的生产线') diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 20077f3c..2dac0665 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -427,19 +427,22 @@ class ResMrpWorkOrder(models.Model): if not item.route_id: raise UserError('【工件配送】明细中请选择【任务路线】') else: - if item.is_cnc_program_down is True: - if item.status == '待下发': - return { - 'name': _('确认'), - 'type': 'ir.actions.act_window', - 'view_mode': 'form', - 'res_model': 'sf.workpiece.delivery.wizard', - 'target': 'new', - 'context': { - 'default_workorder_id': self.id, - }} + if self.state == 'done': + if item.is_cnc_program_down is True: + if item.status == '待下发': + return { + 'name': _('确认'), + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_model': 'sf.workpiece.delivery.wizard', + 'target': 'new', + 'context': { + 'default_workorder_id': self.id, + }} + else: + raise UserError(_("该制造订单还未下发CNC程序单,无法进行工件配送")) else: - raise UserError(_("该制造订单还未下发CNC程序单,无法进行工件配送")) + raise UserError(_("该工单暂未完成,无法进行工件配送")) # 拼接工单对象属性值 def json_workorder_str(self, k, production, route): @@ -636,6 +639,33 @@ class ResMrpWorkOrder(models.Model): # 'domain': [('production_id', '=', self.id)], # '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): """ @@ -822,6 +852,8 @@ class ResMrpWorkOrder(models.Model): self.process_state = '已完工' self.production_id.button_mark_done1() # self.production_id.state = 'done' + # if self.routing_type == '装夹预调': + # self.workpiece_delivery_ids.write({''}) # 将FTP的检测报告文件下载到临时目录 def download_reportfile_tmp(self, workorder, reportpath): @@ -1096,6 +1128,7 @@ class WorkPieceDelivery(models.Model): name = fields.Char('单据编号') 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_line_id = fields.Many2one('sf.production.line', string='目的生产线') plan_start_processing_time = fields.Datetime('计划开始加工时间', readonly=True) @@ -1140,6 +1173,7 @@ class WorkPieceDelivery(models.Model): # 工件配送 def button_delivery(self): delivery_ids = [] + production_ids = [] is_cnc_down = 0 is_not_production_line = 0 is_not_route = 0 @@ -1172,7 +1206,13 @@ class WorkPieceDelivery(models.Model): if production_type != item.type: raise UserError('请选择类型为%s的制造订单进行配送' % production_type) if down_status != item.status: - raise UserError('请选择状态为【待下发】的制造订单进行配送') + 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: @@ -1181,13 +1221,15 @@ class WorkPieceDelivery(models.Model): 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: raise UserError('您所选择制造订单的【CNC程序】暂未下发,请在程序下发后再进行配送') if is_not_production_line >= 1: raise UserError('您所选择制造订单的【目的生产线】不一致,请重新确认') if is_not_route >= 1: raise UserError('您所选择制造订单的【任务路线】不一致,请重新确认') - is_free = self._check_avgsite_state() + # is_free = self._check_avgsite_state() + is_free = True if is_free is True: if delivery_ids: return { @@ -1198,6 +1240,9 @@ class WorkPieceDelivery(models.Model): 'target': 'new', 'context': { '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, }} else: if self.type == '运送空料架': @@ -1231,21 +1276,27 @@ class WorkPieceDelivery(models.Model): # 配送至avg小车 def _delivery_avg(self): config = self.env['res.config.settings'].get_values() - if self.type == '运送空料架': - 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}) positionCode_Arr = [] delivery_Arr = [] feeder_station_start = None feeder_station_destination = None + route_id = None for item in self: - 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 delivery_Arr.append(item.name) + if item.type in ['上产线', '下产线']: + if route_id is None: + route_id = item.route_id.id + 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)) if feeder_station_start is not None: positionCode_Arr.append({ diff --git a/sf_manufacturing/views/agv_setting_views.xml b/sf_manufacturing/views/agv_setting_views.xml index 61b25e10..f41e4488 100644 --- a/sf_manufacturing/views/agv_setting_views.xml +++ b/sf_manufacturing/views/agv_setting_views.xml @@ -34,7 +34,8 @@ - + + diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 9cfb9e40..22228ea7 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -626,7 +626,7 @@ - + @@ -649,7 +649,7 @@ tree,search - [('type','in',['上产线','下产线'])] + [('type','in',['上产线','下产线']),('workorder_state','=','done')] diff --git a/sf_manufacturing/wizard/workpiece_delivery_views.xml b/sf_manufacturing/wizard/workpiece_delivery_views.xml index a65593d7..d2d56471 100644 --- a/sf_manufacturing/wizard/workpiece_delivery_views.xml +++ b/sf_manufacturing/wizard/workpiece_delivery_views.xml @@ -5,13 +5,32 @@ sf.workpiece.delivery.wizard
+ -
是否确定配送?
-
-
+ + + +
+ + +
+ + +
+ + + + +
+ 是否确定配送 +
+ +
diff --git a/sf_manufacturing/wizard/workpiece_delivery_wizard.py b/sf_manufacturing/wizard/workpiece_delivery_wizard.py index d606b8b2..5e7c6efb 100644 --- a/sf_manufacturing/wizard/workpiece_delivery_wizard.py +++ b/sf_manufacturing/wizard/workpiece_delivery_wizard.py @@ -2,7 +2,7 @@ # Part of YiZuo. See LICENSE file for full copyright and licensing details. from odoo.exceptions import UserError, ValidationError from datetime import datetime -from odoo import models, api, fields +from odoo import models, api, fields, _ class WorkpieceDeliveryWizard(models.TransientModel): @@ -10,15 +10,70 @@ class WorkpieceDeliveryWizard(models.TransientModel): _description = '工件配送' delivery_ids = fields.Many2many('sf.workpiece.delivery', string='配送') + rfid_code = fields.Char('rfid码') 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): if self.workorder_id: self.workorder_id.workpiece_delivery_ids[0]._delivery_avg() 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 + }} + + @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