diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 9156dc38..d1349671 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -721,6 +721,7 @@ class MrpProduction(models.Model): for product_id, pd in grouped_product_ids.items(): product_id_to_production_names[product_id] = [p.name for p in pd] for production in production_all: + proc_workorders = [] process_parameter_workorder = self.env['mrp.workorder'].search( [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id), ('is_subcontract', '=', True)], order='sequence asc') @@ -737,10 +738,11 @@ class MrpProduction(models.Model): else: # 处理连续组,如果它不为空 if consecutive_workorders: + proc_workorders.append(consecutive_workorders) # 创建外协出入库单和采购订单 - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production) - self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, - product_id_to_production_names) + # self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production, sorted_workorders) + # self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, + # product_id_to_production_names) if i < len(sorted_workorders) - 1: # 重置连续组,并添加当前工作订单 consecutive_workorders = [workorder] @@ -751,18 +753,22 @@ class MrpProduction(models.Model): i - 1].supplier_id.id: consecutive_workorders = [workorder] else: + proc_workorders.append([workorder]) # 立即创建外协出入库单和采购订单 - self.env['stock.picking'].create_outcontract_picking(workorder, production) - self.env['purchase.order'].get_purchase_order(workorder, production, - product_id_to_production_names) + # self.env['stock.picking'].create_outcontract_picking(workorder, production) + # self.env['purchase.order'].get_purchase_order(workorder, production, + # product_id_to_production_names) consecutive_workorders = [] # 处理最后一个组,即使它可能只有一个工作订单 if consecutive_workorders: - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production) - self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, - product_id_to_production_names) - + proc_workorders.append(consecutive_workorders) + # self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production) + # self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, + # product_id_to_production_names) + for workorders in reversed(proc_workorders): + self.env['stock.picking'].create_outcontract_picking(workorders, production, sorted_workorders) + self.env['purchase.order'].get_purchase_order(workorders, production, product_id_to_production_names) # 工单排序 def _reset_work_order_sequence1(self, k): for rec in self: diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 19be2289..6e0f1422 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -23,12 +23,15 @@ class ResMrpWorkOrder(models.Model): product_tmpl_name = fields.Char('坯料产品名称', related='production_bom_id.bom_line_ids.product_id.name') - product_tmpl_id_length = fields.Float(related='production_id.product_tmpl_id.length', readonly=True, store=True, - string="坯料长度(mm)") - product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True, - string="坯料宽度(mm)") - product_tmpl_id_height = fields.Float(related='production_id.product_tmpl_id.height', readonly=True, store=True, - string="坯料高度(mm)") + product_tmpl_id_length = fields.Float(string='坯料长度(mm)', related='material_length', readonly=True, store=False) + product_tmpl_id_width = fields.Float(string='坯料宽度(mm)', related='material_width', readonly=True, store=False) + product_tmpl_id_height = fields.Float(string='坯料高度(mm)', related='material_height', readonly=True, store=False) + # product_tmpl_id_length = fields.Float(related='production_id.product_tmpl_id.length', readonly=True, store=True, + # string="坯料长度(mm)") + # product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True, + # string="坯料宽度(mm)") + # product_tmpl_id_height = fields.Float(related='production_id.product_tmpl_id.height', readonly=True, store=True, + # string="坯料高度(mm)") product_tmpl_id_materials_id = fields.Many2one(related='production_id.product_tmpl_id.materials_id', readonly=True, store=True, check_company=True, string="材料") product_tmpl_id_materials_type_id = fields.Many2one(related='production_id.product_tmpl_id.materials_type_id', @@ -134,8 +137,10 @@ class ResMrpWorkOrder(models.Model): glb_file = fields.Binary("glb模型文件", related='production_id.model_file') is_subcontract = fields.Boolean(string='是否外协') surface_technics_parameters_id = fields.Many2one('sf.production.process.parameter', string="表面工艺可选参数") + picking_ids = fields.Many2many('stock.picking', string='外协出入库单', compute='_compute_surface_technics_picking_ids') - # purchase_id = fields.Many2one('purchase.order', string='外协采购单') + + purchase_id = fields.Many2many('purchase.order', string='外协采购单') surface_technics_picking_count = fields.Integer("外协出入库", compute='_compute_surface_technics_picking_ids') surface_technics_purchase_count = fields.Integer("外协采购", compute='_compute_surface_technics_purchase_ids') @@ -239,13 +244,11 @@ class ResMrpWorkOrder(models.Model): previous_workorder = self.env['mrp.workorder'].search( [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'), ('production_id', '=', workorder.production_id.id)]) - if previous_workorder: - if previous_workorder.supplier_id != workorder.supplier_id: - # process_product = self.env['product.template']._get_process_parameters_product( - # previous_workorder.surface_technics_parameters_id) - domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)] - else: - domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)] + # if previous_workorder: + # if previous_workorder.supplier_id != workorder.supplier_id: + # domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)] + # else: + domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)] picking_ids = self.env['stock.picking'].search(domain, order='id asc') workorder.surface_technics_picking_count = len(picking_ids) workorder.picking_ids = picking_ids.ids @@ -314,24 +317,27 @@ class ResMrpWorkOrder(models.Model): # if technology_design.is_auto is False: # domain = [('origin', '=', self.production_id.name)] # else: - domain = [('origin', '=', self.production_id.name), ('purchase_type', '=', 'consignment'), - ('state', '!=', 'cancel')] + purchase_orders_id = self._get_surface_technics_purchase_ids() + result = { + "type": "ir.actions.act_window", + "res_model": "purchase.order", + "res_id": purchase_orders_id.id, + # "domain": [['id', 'in', self.purchase_id]], + "name": _("Purchase Orders"), + 'view_mode': 'form', + } + return result + + def _get_surface_technics_purchase_ids(self): + domain = [('origin', '=', self.production_id.name), ('purchase_type', '=', 'consignment')] purchase_orders = self.env['purchase.order'].search(domain) purchase_orders_id = None for po in purchase_orders: for line in po.order_line: if line.product_id.server_product_process_parameters_id == self.surface_technics_parameters_id: if line.product_qty == 1: - purchase_orders_id = line.order_id.id - result = { - "type": "ir.actions.act_window", - "res_model": "purchase.order", - "res_id": purchase_orders_id, - # "domain": [['id', 'in', self.purchase_id]], - "name": _("Purchase Orders"), - 'view_mode': 'form', - } - return result + purchase_orders_id = line.order_id + return purchase_orders_id supplier_id = fields.Many2one('res.partner', string='外协供应商') equipment_id = fields.Many2one('maintenance.equipment', string='加工设备', tracking=True) @@ -1029,47 +1035,47 @@ class ResMrpWorkOrder(models.Model): 'production_id.programming_state') def _compute_state(self): # super()._compute_state() - for workorder in self: - 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]): - 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') - and workorder.blocked_by_workorder_ids.test_results not in ['报废', '返工']) - or (previous_workorder.state in ('done', 'cancel') - and not workorder.blocked_by_workorder_ids - and previous_workorder.test_results not in ['报废', '返工']) - ): - 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']: - if previous_workorder.state == 'waiting': - workorder.state = 'pending' - if workorder.sequence == 1 and workorder.state == 'pending': - workorder.state = 'waiting' - continue - if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'): - continue - 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' + # for workorder in self: + # 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]): + # 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') + # and workorder.blocked_by_workorder_ids.test_results not in ['报废', '返工']) + # or (previous_workorder.state in ('done', 'cancel') + # and not workorder.blocked_by_workorder_ids + # and previous_workorder.test_results not in ['报废', '返工']) + # ): + # 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']: + # if previous_workorder.state == 'waiting': + # workorder.state = 'pending' + # if workorder.sequence == 1 and workorder.state == 'pending': + # workorder.state = 'waiting' + # continue + # if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'): + # continue + # 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' for workorder in self: # 如果工单的工序没有进行排序则跳出循环 @@ -1120,21 +1126,26 @@ class ResMrpWorkOrder(models.Model): if workorder.is_subcontract is False: workorder.state = 'ready' else: - production_programming = self.env['mrp.production'].search( - [('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] - purchase_orders = self.env['purchase.order'].search( - [('origin', 'ilike', ','.join(production_list))]) - for line in purchase_orders.order_line: - if ( - line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id - and line.product_qty == len(production_no_remanufacture)): - if all(pur_order.state == 'purchase' for pur_order in purchase_orders): - workorder.state = 'ready' - else: - workorder.state = 'waiting' + # production_programming = self.env['mrp.production'].search( + # [('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] + # purchase_orders = self.env['purchase.order'].search( + # [('origin', 'ilike', ','.join(production_list))]) + # for line in purchase_orders.order_line: + # if ( + # line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id + # and line.product_qty == len(production_no_remanufacture)): + # if all(pur_order.state == 'purchase' for pur_order in purchase_orders): + # workorder.state = 'ready' + # else: + # workorder.state = 'waiting' + purchase_orders_id = self._get_surface_technics_purchase_ids() + if purchase_orders_id: + workorder.state = 'ready' if purchase_orders_id.state == 'purchase' else 'waiting' + else: + workorder.state = 'waiting' # re_work = self.env['mrp.workorder'].search([('production_id', '=', workorder.production_id.id), # ('processing_panel', '=', workorder.processing_panel), @@ -1197,6 +1208,10 @@ class ResMrpWorkOrder(models.Model): # 重写工单开始按钮方法 def button_start(self): + # 判断工单状态是否为等待组件 + if self.state in ['waiting', 'pending']: + raise UserError('制造订单【%s】缺少组件信息!' % self.production_id.name) + if self.routing_type == 'CNC加工': self.env['sf.production.plan'].sudo().search([('name', '=', self.production_id.name)]).write({ 'state': 'processing', @@ -1204,9 +1219,6 @@ class ResMrpWorkOrder(models.Model): }) if self.sequence == 1: - # 判断工单状态是否为等待组件 - if self.state == 'waiting': - raise UserError('制造订单【%s】缺少组件信息!' % self.production_id.name) # 判断是否有坯料的序列号信息 boolean = False if self.production_id.move_raw_ids: @@ -1243,19 +1255,33 @@ class ResMrpWorkOrder(models.Model): # 表面工艺外协出库单 if self.routing_type == '表面工艺': if self.is_subcontract is True: - 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.production_id.name), ('state', 'not in', ['cancel', 'done'])]) + move_out = self.move_subcontract_workorder_ids[1] + # 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.production_id.name), ('state', 'not in', ['cancel', 'done'])]) for mo in move_out: - pick = self.env['stock.picking'].search([('id', '=', mo.picking_id.id), ('name', 'ilike', 'OCOUT'), - ('partner_id', '=', self.supplier_id.id)]) - if pick: - if mo.state != 'done': - mo.write({'state': 'assigned', 'production_id': False}) + if mo.state != 'done': + mo.write({'state': 'assigned', 'production_id': False}) + if not mo.move_line_ids: self.env['stock.move.line'].create(mo.get_move_line(self.production_id, self)) + # product_qty = mo.product_uom._compute_quantity( + # mo.product_uom_qty, mo.product_id.uom_id, rounding_method='HALF-UP') + # available_quantity = self.env['stock.quant']._get_available_quantity( + # mo.product_id, + # mo.location_id, + # lot_id=mo.move_line_ids.lot_id, + # strict=False, + # ) + # mo._update_reserved_quantity( + # product_qty, + # available_quantity, + # mo.location_id, + # lot_id=mo.move_line_ids.lot_id, + # strict=False, + # ) # move_out._action_assign() if self.state == 'waiting' or self.state == 'ready' or self.state == 'progress': @@ -1360,6 +1386,13 @@ class ResMrpWorkOrder(models.Model): picks = record.picking_ids.filtered(lambda p: p.state not in ('done')) if picks: raise UserError('请先完成该工单的工艺外协再进行操作') + # 表面工艺外协,最后一张工单 + workorders = self.production_id.workorder_ids + subcontract_workorders = workorders.filtered(lambda wo: wo.is_subcontract == True).sorted('sequence') + if self == subcontract_workorders[-1]: + # 给下一个库存移动就绪 + self.move_subcontract_workorder_ids[0].move_dest_ids._action_done() + # self.production_id.button_mark_done() tem_date_planned_finished = record.date_planned_finished tem_date_finished = record.date_finished logging.info('routing_type:%s' % record.routing_type) @@ -1402,13 +1435,13 @@ class ResMrpWorkOrder(models.Model): move_raw_id.quantity_done = move_raw_id.product_uom_qty record.process_state = '已完工' record.production_id.process_state = '已完工' - if record.routing_type in ['表面工艺']: - raw_move = self.env['stock.move'].sudo().search( - [('origin', '=', record.production_id.name), - ('procure_method', 'in', ['make_to_order', 'make_to_stock']), - ('state', '!=', 'done')]) - if raw_move: - raw_move.write({'state': 'done'}) + # if record.routing_type in ['表面工艺']: + # raw_move = self.env['stock.move'].sudo().search( + # [('origin', '=', record.production_id.name), + # ('procure_method', 'in', ['make_to_order', 'make_to_stock']), + # ('state', '!=', 'done')]) + # if raw_move: + # raw_move.write({'state': 'done'}) record.production_id.button_mark_done1() # record.production_id.state = 'done' @@ -1528,6 +1561,8 @@ class ResMrpWorkOrder(models.Model): 'default_confirm_button': '确认解除', # 'default_feeder_station_start_id': feeder_station_start_id, }} + + move_subcontract_workorder_ids = fields.One2many('stock.move', 'subcontract_workorder_id', string='组件') class CNCprocessing(models.Model): diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 50c7e672..e464e995 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -636,74 +636,85 @@ class StockPicking(models.Model): def button_validate(self): res = super().button_validate() - if res is True and self.picking_type_id.sequence_code == 'OCOUT': - # 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( - [('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), ('state', 'not in', ['cancel', 'done'])]) - production = self.env['mrp.production'].search([('name', '=', self.origin)]) - for mi in move_in: - pick = self.env['stock.picking'].search([('id', '=', mi.picking_id.id), ('name', 'ilike', 'OCIN'), - ('partner_id', '=', self.partner_id.id)]) - # if pick: - # if mi.state != 'done': - # mi.write({'state': 'assigned'}) - # self.env['stock.move.line'].create(mi.get_move_line(production, None)) - + picking_type_in = self.env.ref('sf_manufacturing.outcontract_picking_in').id + if res is True and self.picking_type_id.id == picking_type_in: + # 如果是最后一张外协入库单,则设置库存位置的预留数量 + move_in = self.move_ids + if move_in: + workorder = move_in.subcontract_workorder_id + workorders = workorder.production_id.workorder_ids + subcontract_workorders = workorders.filtered(lambda wo: wo.is_subcontract == True).sorted('sequence') + if workorder == subcontract_workorders[-1]: + self.env['stock.quant']._update_reserved_quantity( + move_in.product_id, move_in.location_dest_id, move_in.product_uom_qty, lot_id=move_in.move_line_ids.lot_id, + package_id=False, owner_id=False, strict=False + ) + return res # 创建 外协出库入单 - def create_outcontract_picking(self, sorted_workorders_arr, item): + def create_outcontract_picking(self, workorders, item, sorted_workorders): domain = [('origin', '=', item.name), ('name', 'ilike', 'OCOUT')] - if len(sorted_workorders_arr) > 1: - sorted_workorders_arr = sorted_workorders_arr[0] + if len(workorders) > 1: + workorders = workorders[0] else: domain += [ - ('surface_technics_parameters_id', '=', sorted_workorders_arr[0].surface_technics_parameters_id.id)] + ('surface_technics_parameters_id', '=', workorders[0].surface_technics_parameters_id.id)] stock_picking = self.env['stock.picking'].search(domain) if not stock_picking: - for sorted_workorders in sorted_workorders_arr: + for workorder in workorders: # pick_ids = [] - if not sorted_workorders.picking_ids: + if not workorder.picking_ids: # outcontract_stock_move = self.env['stock.move'].search([('production_id', '=', item.id)]) # if not outcontract_stock_move: # 创建一个新的补货组 procurement_group_id = self.env['procurement.group'].create({ - 'name': sorted_workorders.name, + 'name': workorder.name, 'partner_id': self.partner_id.id, }) + move_dest_id = False + # 如果当前工单是是制造订单的最后一个工单 + if workorder == item.workorder_ids[-1]: + move_dest_id = item.move_raw_ids[0].id + else: + # 从sorted_workorders中找到上一工单的move + move_dest_id = sorted_workorders[sorted_workorders.index(workorder) - 1].move_subcontract_workorder_ids[1].id 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_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, procurement_group_id.id)) + self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_in, procurement_group_id.id, move_dest_id)) picking_in = self.create( - moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/')) + moves_in._get_new_picking_values_Res(item, workorder, 'WH/OCIN/')) # pick_ids.append(picking_in.id) moves_in.write( {'picking_id': picking_in.id, 'state': 'waiting'}) moves_in._assign_picking_post_process(new=new_picking) 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, procurement_group_id.id, moves_in.id)) + self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_out, procurement_group_id.id, moves_in.id)) + workorder.write({'move_subcontract_workorder_ids': [(6, 0, [moves_in.id, moves_out.id])]}) picking_out = self.create( - moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/')) + moves_out._get_new_picking_values_Res(item, workorder, 'WH/OCOUT/')) # pick_ids.append(picking_out.id) moves_out.write( {'picking_id': picking_out.id, 'state': 'waiting'}) moves_out._assign_picking_post_process(new=new_picking) + return moves_in, moves_out + @api.depends('move_type', 'immediate_transfer', 'move_ids.state', 'move_ids.picking_id') + def _compute_state(self): + super(StockPicking, self)._compute_state() + for picking in self: + # 外协出库单根据工单状态,采购单状态来确定 + picking_type_id = self.env.ref('sf_manufacturing.outcontract_picking_out').id + if picking.picking_type_id.id == picking_type_id: + if picking.move_ids: + workorder = picking.move_ids[0].subcontract_workorder_id + if picking.state == 'assigned': + if workorder.state in ['pending', 'waiting'] or workorder._get_surface_technics_purchase_ids().state in ['draft', 'sent']: + picking.state = 'waiting' class ReStockMove(models.Model): @@ -713,16 +724,17 @@ class ReStockMove(models.Model): materiel_width = fields.Float(string='物料宽度', digits=(16, 4)) materiel_height = fields.Float(string='物料高度', digits=(16, 4)) - def _get_stock_move_values_Res(self, item, location_src_id, location_dest_id, picking_type_id, group_id, move_dest_ids=False): - route = self.env['stock.route'].sudo().search([('name', '=', '表面工艺外协')]) + def _get_stock_move_values_Res(self, item, picking_type_id, group_id, move_dest_ids=False): + route_id = self.env.ref('sf_manufacturing.route_surface_technology_outsourcing').id + stock_rule = self.env['stock.rule'].sudo().search([('route_id', '=', route_id), ('picking_type_id', '=', picking_type_id)]) move_values = { 'name': '推', 'company_id': item.company_id.id, 'product_id': item.bom_id.bom_line_ids.product_id.id, 'product_uom': item.bom_id.bom_line_ids.product_uom_id.id, 'product_uom_qty': 1.0, - 'location_id': location_src_id, - 'location_dest_id': location_dest_id, + 'location_id': stock_rule.location_src_id.id, + 'location_dest_id': stock_rule.location_dest_id.id, 'origin': item.name, 'group_id': group_id, 'move_dest_ids': [(6, 0, [move_dest_ids])] if move_dest_ids else False, @@ -749,7 +761,7 @@ class ReStockMove(models.Model): 'picking_type_id': picking_type_id, 'location_id': self.mapped('location_id').id, 'location_dest_id': self.mapped('location_dest_id').id, - 'state': 'confirmed', + 'state': 'waiting', } def get_move_line(self, production_id, sorted_workorders): @@ -965,7 +977,7 @@ class ReStockMove(models.Model): 合并制造订单的完成move单据 """ res = super(ReStockMove, self)._merge_moves_fields() - if self[0].origin and self.picking_type_id.name in ['生产发料', '内部调拨', '生产入库']: + if self[0].origin and self.picking_type_id.name in ['生产发料', '内部调拨', '生产入库', '客供料入库']: production = self.env['mrp.production'].search([('name', '=', self[0].origin)], limit=1, order='id asc') productions = self.env['mrp.production'].search( [('origin', '=', production.origin), ('product_id', '=', production.product_id.id)]) @@ -991,6 +1003,8 @@ class ReStockMove(models.Model): res['origin'] = ','.join(productions.mapped('name')) res['retrospect_ref'] = production.product_id.name return res + + subcontract_workorder_id = fields.Many2one('mrp.workorder', '外协工单组件', check_company=True, index='btree_not_null') class ReStockQuant(models.Model): diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 5f9a7ef3..fd0a5ead 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -738,7 +738,7 @@ - - 制造订单生产计划 + CNC产线计划排程 ir.actions.act_window sf.production.plan gantt,tree,form diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index e225c274..6a1d3023 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -279,13 +279,14 @@ class RePurchaseOrder(models.Model): 'product_uom': server_template.uom_id.id })) - if server_product_process: - self.env['purchase.order'].sudo().create({ - 'partner_id': server_template.seller_ids[0].partner_id.id, - 'origin': production.name, - 'state': 'draft', - 'purchase_type': 'consignment', - 'order_line': server_product_process}) + if server_product_process: + purchase_order = self.env['purchase.order'].sudo().create({ + 'partner_id': server_template.seller_ids[0].partner_id.id, + 'origin': production.name, + 'state': 'draft', + 'purchase_type': 'consignment', + 'order_line': server_product_process}) + pp.purchase_id = [(6, 0, [purchase_order.id])] # self.env.cr.commit() @api.onchange('order_line') diff --git a/sf_sale/views/quick_easy_order_view.xml b/sf_sale/views/quick_easy_order_view.xml index 3b386062..89792a49 100644 --- a/sf_sale/views/quick_easy_order_view.xml +++ b/sf_sale/views/quick_easy_order_view.xml @@ -128,9 +128,9 @@ - + + + + \ No newline at end of file