From 4738b03a4509689e8e8a68a68ad81b6d57bc4360 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Wed, 11 Dec 2024 10:03:20 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=80=E5=94=AE=E8=AE=A2=E5=8D=95=E4=B8=8E?= =?UTF-8?q?=E5=88=B6=E9=80=A0=E8=AE=A2=E5=8D=95=E5=85=B3=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 129 +++++++++++++----- .../views/mrp_production_addional_change.xml | 3 + 2 files changed, 97 insertions(+), 35 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 309bb0aa..21d4b8ee 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -8,6 +8,9 @@ import re import requests from itertools import groupby from collections import defaultdict, namedtuple + +from loguru import _logger + from odoo import api, fields, models, SUPERUSER_ID, _ from odoo.exceptions import UserError, ValidationError from odoo.addons.sf_base.commons.common import Common @@ -18,6 +21,7 @@ class MrpProduction(models.Model): _inherit = 'mrp.production' _description = "制造订单" _order = 'create_date desc' + sale_order_id = fields.Many2one('sale.order',string='销售订单', compute='_compute_sale_order_id', store=True) deadline_of_delivery = fields.Date('订单交期', tracking=True, compute='_compute_deadline_of_delivery') # tray_ids = fields.One2many('sf.tray', 'production_id', string="托盘") maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests") @@ -34,6 +38,28 @@ class MrpProduction(models.Model): tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', compute='_compute_tool_state_remark', store=True) tool_state_remark2 = fields.Text(string='功能刀具状态备注(无效刀)', readonly=True) + @api.depends('procurement_group_id.mrp_production_ids.move_dest_ids.group_id.sale_id') + def _compute_sale_order_id(self): + for production in self: + # 初始化 sale_order_id 为 False + sale_order_id = False + # 使用正则表达式查找产品名称中的 'S' 开头的字母数字字符串 + match = re.search(r'S\d+', production.product_id.with_context(lang='zh_CN').name) # 从字符串开始匹配 + + if match: + result = match.group(0) + try: + # 查找与匹配的字符串相符的销售订单 + sale_order = self.env['sale.order'].search( + [('name', '=', result)], limit=1, order='id asc' + ) + if sale_order: + production.sale_order_id = sale_order.id + else: + _logger.warning("No sale order found for production %s with product %s (name match: %s)", + production.id, production.product_id.name, result) + except Exception as e: + _logger.error("Error while fetching sale order for production %s: %s", production.id, str(e)) @api.depends('procurement_group_id.mrp_production_ids.move_dest_ids.group_id.sale_id') def _compute_deadline_of_delivery(self): for production in self: @@ -309,7 +335,8 @@ class MrpProduction(models.Model): for move in production.move_raw_ids if move.product_id): production.state = 'progress' # 新添加的状态逻辑 - if production.state in ['to_close', 'progress', 'technology_to_confirmed'] and production.schedule_state == '未排': + if production.state in ['to_close', 'progress', + 'technology_to_confirmed'] and production.schedule_state == '未排': if not production.workorder_ids or production.is_adjust is True: production.state = 'technology_to_confirmed' else: @@ -320,11 +347,7 @@ class MrpProduction(models.Model): elif production.state == 'pending_cam' and production.schedule_state == '未排': production.state = 'confirmed' elif production.state == 'to_close' and production.schedule_state == '已排': - if all( - wo_state in ('done', 'cancel') for wo_state in production.workorder_ids.mapped('state')): - production.state = 'done' - else: - production.state = 'pending_cam' + production.state = 'pending_cam' elif production.state == 'confirmed' and production.is_adjust is True: production.state = 'technology_to_confirmed' if production.state == 'confirmed' and production.schedule_state == '已排': @@ -335,6 +358,9 @@ class MrpProduction(models.Model): production.state = 'pending_cam' if production.is_rework is True: production.state = 'rework' + if (production.state == 'rework' and production.tool_state == '0' + and production.schedule_state == '已排' and production.is_rework is False): + production.state = 'pending_cam' # if production.state == 'pending_cam': # if all(wo_state in 'done' for wo_state in production.workorder_ids.mapped('state')): # production.state = 'done' @@ -721,10 +747,16 @@ 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') + ('is_subcontract', '=', True), ('state', '!=', 'cancel')], order='sequence asc') if process_parameter_workorder: + # 将这些特殊表面工艺工单的采购单与调拨单置为失效 + for workorder in process_parameter_workorder: + workorder._get_surface_technics_purchase_ids().write({'state': 'cancel'}) + workorder.move_subcontract_workorder_ids.write({'state': 'cancel'}) + workorder.move_subcontract_workorder_ids.picking_id.write({'state': 'cancel'}) consecutive_workorders = [] sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.sequence) for i, workorder in enumerate(sorted_workorders): @@ -737,10 +769,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 +784,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: @@ -847,17 +884,22 @@ class MrpProduction(models.Model): # workorder.picking_ids.move_ids = False workorder.picking_ids = False purchase_order = self.env['purchase.order'].search( - [('state', '=', 'draft'), ('origin', '=', ','.join(production_process)), + [('state', '=', 'draft'), ('origin', '=', item.name), ('purchase_type', '=', 'consignment')]) - for line in purchase_order.order_line: - server_template = self.env['product.template'].search( - [('server_product_process_parameters_id', '=', workorder.surface_technics_parameters_id.id), - ('detailed_type', '=', 'service')]) - purchase_order_line = self.env['purchase.order.line'].search( - [('product_id', '=', server_template.product_variant_id.id), ('id', '=', line.id), - ('product_qty', '=', len(production_process))], limit=1, order='id desc') - if purchase_order_line: - line.unlink() + server_template = self.env['product.template'].search( + [('server_product_process_parameters_id', '=', + workorder.surface_technics_parameters_id.id), + ('detailed_type', '=', 'service')]) + for po in purchase_order: + for line in po.order_line: + if line.product_id == server_template.product_variant_id: + continue + if server_template.server_product_process_parameters_id != line.product_id.server_product_process_parameters_id: + purchase_order_line = self.env['purchase.order.line'].search( + [('product_id', '=', server_template.product_variant_id.id), ('id', '=', line.id), + ('product_qty', '=', 1)], limit=1, order='id desc') + if purchase_order_line: + line.unlink() def _reset_work_order_sequence(self): """ @@ -898,8 +940,6 @@ class MrpProduction(models.Model): for cw in cancel_work_ids: cw.sequence = sequence + 1 - - def _reset_work_order_sequence_1(self): """ 工单工序排序方法(旧) @@ -1012,7 +1052,7 @@ class MrpProduction(models.Model): if self.production_type == '自动化产线加工': date_planned_start, date_planned_end, last_time = work.auto_production_process(last_time, count, type_map) - elif self.production_type == '人工线下加工': + elif self.production_type == '': date_planned_start, date_planned_end, last_time = work.manual_offline_process(last_time, index) work.update_work_start_end(date_planned_start, date_planned_end) @@ -1324,11 +1364,10 @@ class MrpProduction(models.Model): move = self.env['stock.move'].search([('origin', '=', productions.name)], order='id desc') for mo in move: domain = [] - if mo.procure_method == 'make_to_order' and mo.name != productions.name: - if mo.name == '/': - domain = [('barcode', '=', 'WH-PC'), ('sequence_code', '=', 'PC')] - elif mo.name == '拉': - domain = [('barcode', '=', 'WH-INTERNAL'), ('sequence_code', '=', 'INT')] + if mo.location_id.barcode == 'WH-POSTPRODUCTION' and mo.rule_id.picking_type_id.barcode == 'PC': + domain = [('barcode', '=', 'WH-PC'), ('sequence_code', '=', 'PC')] + elif mo.location_id.barcode == 'PL' and mo.rule_id.picking_type_id.barcode == 'INT': + domain = [('barcode', '=', 'WH-INTERNAL'), ('sequence_code', '=', 'INT')] if domain: picking_type = self.env['stock.picking.type'].search(domain) mo.write({'picking_type_id': picking_type.id}) @@ -1422,6 +1461,26 @@ class MrpProduction(models.Model): for production in self: production.production_type = '自动化产线加工' if not production.product_id.is_manual_processing else '人工线下加工' + @api.depends('procurement_group_id.mrp_production_ids.move_dest_ids.group_id.sale_id') + def _compute_sale_order_count(self): + for production in self: + if production.sale_order_id: + production.sale_order_count = 1 + else: + production.sale_order_count = 0 + def action_view_sale_orders(self): + if self.sale_order_id: + action = { + 'res_model': 'sale.order', + 'type': 'ir.actions.act_window', + } + action.update({ + 'view_mode': 'form', + 'res_id': self.sale_order_id.id, + }) + return action + + @api.model_create_multi def create(self, vals_list): """ diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 783f39dd..b999dd63 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -43,6 +43,7 @@ + @@ -123,6 +124,7 @@ + @@ -583,6 +585,7 @@ +