diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index c8e26f2f..b5abdf98 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -194,6 +194,8 @@ class ResMrpWorkOrder(models.Model): else: domain = [('origin', '=', ','.join(production_list))] purchase = self.env['purchase.order'].search(domain) + if not purchase: + order.surface_technics_purchase_count = 0 for line in purchase.order_line: if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id: if (line.product_qty == len(production_no_remanufacture)) or technology_design.is_auto is False: @@ -908,25 +910,44 @@ class ResMrpWorkOrder(models.Model): return workorders_values_str @api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state', - 'production_id.tool_state') + 'production_id.tool_state', 'production_id.schedule_state') def _compute_state(self): # super()._compute_state() for workorder in self: logging.info(workorder.name) logging.info(workorder.state) logging.info(workorder.sequence) + logging.info(workorder.id) + # logging.info(workorder.blocked_by_workorder_ids) + # logging.info(workorder.blocked_by_workorder_ids.name) + # logging.info(workorder.blocked_by_workorder_ids.sequence) + logging.info('----------------------') + if workorder.sequence != 1: + previous_workorder = self.env['mrp.workorder'].search( + [('production_id', '=', workorder.production_id.id), + ('sequence', '=', workorder.sequence - 1)]) 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.production_id.reservation_state == 'assigned' and workorder.production_id.schedule_state == '已排': + if (workorder.sequence == 1 and not workorder.blocked_by_workorder_ids) or ( + workorder.blocked_by_workorder_ids.state in ('done', 'cancel')) or ( + previous_workorder.state in ( + 'done', 'cancel') and not workorder.blocked_by_workorder_ids): + workorder.state = 'ready' + continue + if workorder.production_id.schedule_state == '未排' and workorder.state in ('waiting', 'ready'): + if workorder.sequence != 1: + workorder.state = 'pending' + continue if workorder.state not in ('waiting', 'ready'): continue + if workorder.state in ( + 'waiting') and workorder.sequence == 1 and workorder.production_id.schedule_state == '已排': + workorder.state = 'ready' + continue if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): workorder.state = 'pending' if workorder.state in ['waiting']: - previous_workorder = self.env['mrp.workorder'].search( - [('production_id', '=', workorder.production_id.id), - ('sequence', '=', workorder.sequence - 1)]) if previous_workorder.state == 'waiting': workorder.state = 'pending' if workorder.sequence == 1 and workorder.state == 'pending': @@ -934,7 +955,7 @@ class ResMrpWorkOrder(models.Model): continue if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'): continue - if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting': + if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting' and workorder.production_id.schedule_state == '已排': workorder.state = 'ready' elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready': workorder.state = 'waiting' @@ -991,7 +1012,7 @@ class ResMrpWorkOrder(models.Model): 'done', 'rework', 'cancel']: if workorder.production_id.is_rework is False: - if re_work or cnc_workorder or unclamp_workorder: + if re_work or cnc_workorder or unclamp_workorder : workorder.state = 'ready' # if (re_work or cnc_workorder) and workorder.production_id.is_rework is False: # workorder.state = 'ready' @@ -1001,7 +1022,7 @@ class ResMrpWorkOrder(models.Model): workorder.state = 'ready' else: production_programming = self.env['mrp.production'].search( - [('programming_no', '=', self.production_id.programming_no)], order='name asc') + [('origin', '=', self.production_id.origin)], order='name asc') production_no_remanufacture = production_programming.filtered( lambda a: a.is_remanufacture is False) production_list = [production.name for production in production_programming] @@ -1088,7 +1109,7 @@ class ResMrpWorkOrder(models.Model): 'actual_start_time': datetime.now() }) - if self.routing_type == '装夹预调': + if self.sequence == 1: # 判断是否有坯料的序列号信息 boolean = False if self.production_id.move_raw_ids: @@ -1196,9 +1217,9 @@ class ResMrpWorkOrder(models.Model): if record.routing_type == '装夹预调': if not record.rfid_code and record.is_rework is False: raise UserError("请扫RFID码进行绑定") - if record.is_rework is False: - if not record.material_center_point: - raise UserError("坯料中心点为空,请检查") + # if record.is_rework is False: + # if not record.material_center_point: + # raise UserError("坯料中心点为空,请检查") # if record.X_deviation_angle <= 0: # raise UserError("X偏差角度小于等于0,请检查!本次计算的X偏差角度为:%s" % record.X_deviation_angle) record.process_state = '待加工' @@ -1230,23 +1251,10 @@ class ResMrpWorkOrder(models.Model): ''' record.date_finished = datetime.now() if record.routing_type == '表面工艺': - logging.info('record.picking_ids:%s' % record.picking_ids) - logging.info('record.picking_out:%s' % record.picking_ids[0]) if record.picking_ids: - for pick_item in record.picking_ids: - if pick_item.state not in ['done']: - raise UserError( - '请先完成该工单的工艺外协再进行操作') - picking_out = record.env['stock.move.line'].search( - [('picking_id', '=', record.picking_ids[0].id)]) - logging.info('picking_out:%s' % picking_out.picking_id.name) - # if picking_out: - # order_line_ids = [] - # logging.info('surface_technics_parameters_id:%s' % record.surface_technics_parameters_id.name) - # - # else: - # raise UserError( - # '请先在产品中配置表面工艺为%s相关的外协服务产品' % item.surface_technics_parameters_id.name) + picks = record.picking_ids.filtered(lambda p: p.state not in ('done')) + # if picks: + # raise UserError('请先完成该工单的工艺外协再进行操作') tem_date_planned_finished = record.date_planned_finished tem_date_finished = record.date_finished logging.info('routing_type:%s' % record.routing_type) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 3fda8faf..0283df22 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -659,32 +659,27 @@ class StockPicking(models.Model): return '%s%s' % (rescode, num) def button_validate(self): - move_out = self.env['stock.move'].search( - [('location_id', '=', self.env['stock.location'].search( - [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), - ('location_dest_id', '=', self.env['stock.location'].search( - [('barcode', 'ilike', 'VL-SPOC')]).id), - ('origin', '=', self.origin)]) - # if self.id == move_out.picking_id.id: - # if move_out.move_line_ids.workorder_id.state not in ['progress']: - # raise UserError( - # _('该出库单里源单据内的单号为%s的工单还未开始,不能进行验证操作!' % move_out.move_line_ids.workorder_id.name)) - # 入库单验证 - move_in = self.env['stock.move'].search( - [('location_dest_id', '=', self.env['stock.location'].search( - [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), - ('location_id', '=', self.env['stock.location'].search( - [('barcode', 'ilike', 'VL-SPOC')]).id), - ('origin', '=', self.origin), ('picking_id', '=', self.id)]) - if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id: - if move_out.origin == move_in.origin: - move_in.write({'production_id': False}) - if move_out.picking_id.state != 'done': - raise UserError( - _('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name)) + if self.picking_type_id.barcode == 'OCOUT': + move_out = self.env['stock.move'].search( + [('location_id', '=', self.env['stock.location'].search( + [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), + ('location_dest_id', '=', self.env['stock.location'].search( + [('barcode', 'ilike', 'VL-SPOC')]).id), + ('origin', '=', self.origin)]) + move_in = self.env['stock.move'].search( + [('location_dest_id', '=', self.env['stock.location'].search( + [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), + ('location_id', '=', self.env['stock.location'].search( + [('barcode', 'ilike', 'VL-SPOC')]).id), + ('origin', '=', self.origin), ('picking_id', '=', self.id)]) + if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id: + if move_out.origin == move_in.origin: + move_in.write({'production_id': False}) + if move_out.picking_id.state != 'done': + raise UserError( + _('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name)) res = super().button_validate() - if res is True and self.picking_type_id: - + if res is True and self.picking_type_id.barcode == 'OCIN': if self.id == move_out.picking_id.id: # if move_out.move_line_ids.workorder_id.state == 'progress': move_in = self.env['stock.move'].search( @@ -704,36 +699,37 @@ class StockPicking(models.Model): def create_outcontract_picking(self, sorted_workorders_arr, item): for sorted_workorders in sorted_workorders_arr: # pick_ids = [] - outcontract_stock_move = self.env['stock.move'].search( - [('workorder_id', '=', sorted_workorders.id), ('production_id', '=', item.id)]) - if not outcontract_stock_move: - new_picking = True - location_id = self.env['stock.location'].search( - [('barcode', 'ilike', 'VL-SPOC')]).id, - location_dest_id = self.env['stock.location'].search( - [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id, - outcontract_picking_type_in = self.env.ref( - 'sf_manufacturing.outcontract_picking_in').id, - outcontract_picking_type_out = self.env.ref( - 'sf_manufacturing.outcontract_picking_out').id, - moves_out = self.env['stock.move'].sudo().create( - self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id, - outcontract_picking_type_out)) - picking_out = self.create( - moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/')) - # pick_ids.append(picking_out.id) - moves_out.write( - {'picking_id': picking_out.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id}) - moves_out._assign_picking_post_process(new=new_picking) - moves_in = self.env['stock.move'].sudo().create( - self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id, - outcontract_picking_type_in)) - picking_in = self.create( - moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/')) - # pick_ids.append(picking_in.id) - moves_in.write( - {'picking_id': picking_in.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id}) - moves_in._assign_picking_post_process(new=new_picking) + if not sorted_workorders.picking_ids: + outcontract_stock_move = self.env['stock.move'].search( + [('workorder_id', '=', sorted_workorders.id), ('production_id', '=', item.id)]) + if not outcontract_stock_move: + new_picking = True + location_id = self.env['stock.location'].search( + [('barcode', 'ilike', 'VL-SPOC')]).id, + location_dest_id = self.env['stock.location'].search( + [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id, + outcontract_picking_type_in = self.env.ref( + 'sf_manufacturing.outcontract_picking_in').id, + outcontract_picking_type_out = self.env.ref( + 'sf_manufacturing.outcontract_picking_out').id, + moves_out = self.env['stock.move'].sudo().create( + self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id, + outcontract_picking_type_out)) + picking_out = self.create( + moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/')) + # pick_ids.append(picking_out.id) + moves_out.write( + {'picking_id': picking_out.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id}) + moves_out._assign_picking_post_process(new=new_picking) + moves_in = self.env['stock.move'].sudo().create( + self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id, + outcontract_picking_type_in)) + picking_in = self.create( + moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/')) + # pick_ids.append(picking_in.id) + moves_in.write( + {'picking_id': picking_in.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id}) + moves_in._assign_picking_post_process(new=new_picking) # sorted_workorders.write({'picking_ids': [(6, 0, pick_ids)]}) @@ -791,7 +787,7 @@ class ReStockMove(models.Model): 'picking_id': self.picking_id.id, 'reserved_uom_qty': 1.0, 'lot_id': production_id.move_line_raw_ids.lot_id.id, - 'company_id': self.company_id.id, + 'company_id': self.env.company.id, # 'workorder_id': '' if not sorted_workorders else sorted_workorders.id, # 'production_id': '' if not sorted_workorders else sorted_workorders.production_id.id, 'state': 'assigned', diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 44416d7a..46d90fdd 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -347,6 +347,7 @@ + - + diff --git a/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py b/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py index 4fa14f53..9fdd31f7 100644 --- a/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py +++ b/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py @@ -17,11 +17,41 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel): domain = [('origin', '=', self.origin), ('state', '=', 'confirmed')] else: domain = [('id', '=', self.production_id.id)] + technology_designs = self.production_id.technology_design_ids productions = self.env['mrp.production'].search(domain) workorders_values = [] - for item in productions: + for production_my in productions: + # 该制造订单的其他同一销售订单的制造订单的工艺设计处理 + if production_my != self.production_id: + for td_other in production_my.technology_design_ids: + for td_main in technology_designs: + route_other = production_my.technology_design_ids.filtered( + lambda td: td.route_id.id == td_main.route_id.id) + if not route_other: + production_my.write({'technology_design_ids': [(0, 0, { + 'route_id': td_main.route_id.id, + 'process_parameters_id': False if td_main.process_parameters_id is False else + self.env[ + 'sf.production.process.parameter'].search( + [('id', '=', td_main.process_parameters_id.id)]).id, + 'sequence': td_main.sequence})]}) + else: + if td_main.route_id == td_other.route_id: + if td_main.route_id.routing_type == '表面工艺': + display_name = td_main.process_parameters_id.display_name + else: + display_name = td_main.route_id.display_name + if (td_main.panel is not False and td_main.panel == td_other.panel) or ( + display_name == td_other.display_name): + if td_main.sequence != td_other.sequence: + td_other.write({'sequence': td_main.sequence}) + logging.info(td_main.route_id.name) + logging.info(td_main.sequence) + logging.info(td_other.route_id.name) + logging.info(td_other.sequence) + special_design = self.env['sf.technology.design'].sudo().search( - [('routing_tag', '=', 'special'), ('production_id', '=', item.id), + [('routing_tag', '=', 'special'), ('production_id', '=', production_my.id), ('is_auto', '=', False), ('active', 'in', [True, False])]) for special in special_design: if special.active is False: @@ -42,7 +72,12 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel): if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id: purchase_order.write({'state': 'cancel'}) else: - workorder = self.env['mrp.workorder'].search([('name', '=', special.route_id.display_name)]) + if special.route_id.routing_type == '表面工艺': + display_name = special.process_parameters_id.display_name + else: + display_name = special.route_id.display_name + workorder = self.env['mrp.workorder'].search( + [('name', '=', display_name), ('production_id', '=', special.production_id.id)]) if not workorder: if special.route_id.routing_type == '表面工艺': product_production_process = self.env['product.template'].search( @@ -57,10 +92,16 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel): else: workorders_values.append( self.env['mrp.workorder'].json_workorder_str(special.production_id, special)) - if workorders_values: - productions.write({'workorder_ids': workorders_values}) - productions.get_subcontract_pick() - productions._reset_work_order_sequence() + special.production_id.write({'workorder_ids': workorders_values}) + special.production_id.get_subcontract_pick() + special.production_id._reset_work_order_sequence() + workorders_values = [] + else: + if len(workorder.blocked_by_workorder_ids) > 1: + if workorder.sequence == 1: + workorder.blocked_by_workorder_ids = None + else: + workorder.blocked_by_workorder_ids = blocked_by_workorder_ids[0] for item in productions: workorder = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted( key=lambda a: a.sequence) diff --git a/sf_manufacturing/wizard/production_technology_wizard.py b/sf_manufacturing/wizard/production_technology_wizard.py index 5d822587..240f0917 100644 --- a/sf_manufacturing/wizard/production_technology_wizard.py +++ b/sf_manufacturing/wizard/production_technology_wizard.py @@ -18,8 +18,24 @@ class ProductionTechnologyWizard(models.TransientModel): domain = [('origin', '=', self.origin)] else: domain = [('id', '=', self.production_id.id)] + technology_designs = self.production_id.technology_design_ids productions = self.env['mrp.production'].search(domain) for production in productions: + if production != self.production_id: + for td_other in production.technology_design_ids: + for td_main in technology_designs: + route_other = production.technology_design_ids.filtered( + lambda td: td.route_id.id == td_main.route_id.id) + if not route_other: + production.write({'technology_design_ids': [(0, 0, { + 'route_id': td_main.route_id.id, + 'process_parameters_id': False if td_main.process_parameters_id is False else self.env[ + 'sf.production.process.parameter'].search( + [('id', '=', td_main.process_parameters_id.id)]).id, + 'sequence': td_main.sequence})]}) + else: + if td_main.sequence != td_other.sequence: + td_other.sequence = td_main.sequence special = production.technology_design_ids.filtered( lambda td: td.is_auto is False and td.process_parameters_id is not False) if special: @@ -28,4 +44,5 @@ class ProductionTechnologyWizard(models.TransientModel): for item in productions: workorder = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted( key=lambda a: a.sequence) - workorder[0].state = 'waiting' + if workorder[0].state in ['pending']: + workorder[0].state = 'waiting'