# -*- coding: utf-8 -*- # Part of YiZuo. See LICENSE file for full copyright and licensing details. import logging from odoo.exceptions import UserError, ValidationError from datetime import datetime from odoo import models, api, fields, _ class WorkpieceDeliveryWizard(models.TransientModel): _name = 'sf.workpiece.delivery.wizard' _inherit = ["barcodes.barcode_events_mixin"] _description = '工件配送' rfid_code = fields.Char('rfid码') delivery_ids = fields.Many2many('sf.workpiece.delivery', string='配送单') workorder_ids = fields.Many2many('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', '目的接驳站') workcenter_id = fields.Many2one(string='所属区域', comodel_name='mrp.workcenter', tracking=True) confirm_button = fields.Char('按钮名称') @api.onchange('delivery_type') def _onchange_type(self): if self.delivery_type: routes = self.env['sf.agv.task.route'].search([('route_type', '=', self.delivery_type)]) if self.workcenter_id: routes = routes.filtered(lambda a: a.start_site_id.workcenter_id.id == self.workcenter_id.id) start_site_ids = routes.mapped('start_site_id.id') workcenter_ids = routes.mapped('end_site_id.workcenter_id.id') if workcenter_ids: self.workcenter_id = workcenter_ids[0] return { 'domain': { 'feeder_station_start_id': [('id', 'in', start_site_ids)], 'workcenter_id': [('id', 'in', workcenter_ids)], } } else: return { 'domain': { 'feeder_station_start_id': [], 'workcenter_id': [], } } def _get_agv_route_type_selection(self): return self.env['sf.agv.task.route'].fields_get(['route_type'])['route_type']['selection'] delivery_type = fields.Selection(selection=_get_agv_route_type_selection, string='类型') def confirm(self): try: # if self.workorder_id: # self.workorder_id.workpiece_delivery_ids[0].agv_scheduling_id() # else: # 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: scheduling = self.env['sf.agv.scheduling'].add_scheduling( agv_start_site_id=self.feeder_station_start_id.id, agv_route_type=self.delivery_type, workorders=self.workorder_ids, ) # 如果关联了工件配送单,则修改状态为已下发 if self.delivery_ids: self.delivery_ids.write({ 'status': '已下发', 'agv_scheduling_id': scheduling.id, 'feeder_station_start_id': scheduling.start_site_id.id, }) # 如果是解除装夹工单,则需要处理工单逻辑 for item in self.workorder_ids: if item.routing_type == '解除装夹' and item.state == 'ready': item.button_start() item.button_finish() # 显示通知 return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'target': 'new', 'params': { 'message': '任务下发成功!AGV任务调度编号为【%s】' % scheduling.name, 'type': 'success', 'sticky': False, 'next': {'type': 'ir.actions.act_window_close'}, } } except Exception as e: logging.info('%s任务下发失败:%s' % (self.delivery_type, e)) raise UserError('%s任务下发失败:%s' % (self.delivery_type, e)) # def recognize_production(self): # # production_ids = [] # # delivery_ids = [] # # aa = self.production_ids.workorder_ids.filtered( # # lambda b: b.routing_type == "装夹预调").workpiece_delivery_ids.filtered( # # lambda c: c.rfid_code == self.rfid_code) # # logging.info('aa:%s' % aa) # 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 def on_barcode_scanned(self, barcode): delivery_type = self.env.context.get('default_delivery_type') if delivery_type == '上产线': workorder = self.env['mrp.workorder'].search( [('production_line_state', '=', '待上产线'), ('rfid_code', '=', barcode), ('state', '=', 'done')]) # 找到对应的配送单 delivery = self.env['sf.workpiece.delivery'].search( [('type', '=', '上产线'), ('rfid_code', '=', barcode), ('status', '=', '待下发')]) if delivery: self.delivery_ids |= delivery elif delivery_type == '运送空料架': workorder = self.env['mrp.workorder'].search( [('routing_type', '=', '解除装夹'), ('rfid_code', '=', barcode), ('state', '=', 'ready')]) if workorder: if len(self.production_ids) > 0 and workorder.production_line_id.id != self.production_ids[0].production_line_id.id: raise UserError('该rfid对应的制造订单号为%s的目的生产线不一致' % workorder.production_id.name) # 将对象添加到对应的同模型且是多对多类型里 self.production_ids |= workorder.production_id self.workorder_ids |= workorder else: raise UserError('该rfid码对应的工单不存在') return