From 4e2947c107aec1a50416cb8e5fbf9b8c5c348e65 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Wed, 19 Apr 2023 18:05:41 +0800 Subject: [PATCH] =?UTF-8?q?sf=E7=9A=84=E9=94=80=E5=94=AE=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=88=B6=E9=80=A0=E8=AE=A2=E5=8D=95=E7=9A=84?= =?UTF-8?q?=E6=96=B9=E6=B3=95,=E8=AF=A5=E6=96=B9=E6=B3=95=E5=86=85?= =?UTF-8?q?=EF=BC=8C=E9=9C=80=E8=AE=A9=E5=88=B6=E9=80=A0=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E5=92=8C=E5=B7=A5=E5=8D=95=E7=9A=84=E6=95=B0=E6=8D=AE=E5=85=A5?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=EF=BC=8C=E4=BB=A5=E4=BE=BF=E7=94=9F?= =?UTF-8?q?=E6=88=90=E8=A1=A8=E9=9D=A2=E5=A4=96=E5=8D=8F=E5=B7=A5=E8=89=BA?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E5=A4=96=E5=8D=8F=E5=87=BA=E5=85=A5?= =?UTF-8?q?=E5=BA=93=E5=8D=95=E5=8F=8A=E5=85=B3=E8=81=94=E7=9A=84=E5=BA=93?= =?UTF-8?q?=E5=AD=98=EF=BC=88stock.move=EF=BC=89=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81=E5=8F=AF=E8=BD=AC=E7=A7=BB=E8=87=B3?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=B7=A5=E5=8D=95=E7=9A=84=E8=AF=A5=E8=A1=8C?= =?UTF-8?q?=E4=BB=A3=E7=A0=81production.workorder=5Fids=20=3D=20workorders?= =?UTF-8?q?=5Fvalues=E5=89=8D=E5=90=8E=E5=B7=A6=E5=8F=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/common.py | 6 ++- sf_bf_connect/models/process_status.py | 58 +++++++++++++++++----- sf_manufacturing/models/mrp_production.py | 17 +++---- sf_manufacturing/models/mrp_workorder.py | 8 ++- sf_manufacturing/models/stock.py | 60 +++++++++++++++++++++-- 5 files changed, 122 insertions(+), 27 deletions(-) diff --git a/sf_base/models/common.py b/sf_base/models/common.py index ff7262e3..e6efad84 100644 --- a/sf_base/models/common.py +++ b/sf_base/models/common.py @@ -65,6 +65,7 @@ class MrsProductionProcess(models.Model): category_id = fields.Many2one('sf.production.process.category') # workcenter_ids = fields.Many2many('mrp.workcenter', 'rel_workcenter_process', required=True) + class MrsProcessingTechnology(models.Model): _name = 'sf.processing.technology' _description = '加工工艺' @@ -128,8 +129,9 @@ class MrsProductionProcessParameter(models.Model): def name_get(self): result = [] for parameter in self: - name = parameter.process_id.name + '-' + parameter.name - result.append((parameter.id, name)) + if parameter.process_id: + name = parameter.process_id.name + '-' + parameter.name + result.append((parameter.id, name)) return result # 获取表面工艺的获取方式 diff --git a/sf_bf_connect/models/process_status.py b/sf_bf_connect/models/process_status.py index 3cc56751..8404e9ce 100644 --- a/sf_bf_connect/models/process_status.py +++ b/sf_bf_connect/models/process_status.py @@ -1,5 +1,6 @@ from odoo import api, fields, models, SUPERUSER_ID, _ from odoo.exceptions import ValidationError +from collections import defaultdict, namedtuple from datetime import datetime import logging from odoo.exceptions import UserError @@ -36,10 +37,42 @@ class StatusChange(models.Model): logging.info('函数已经执行=============4') self.with_context(context)._action_confirm() - # self.env.cr.commit() + self.env.cr.commit() print(self.mrp_production_ids) - process_parameter_workorder = self.env['mrp.workorder'].search( - [('surface_technics_parameters_id', '!=', False), ('production_id', '=', 58)]) + # 判断外协工序是否连续有多个外协工序为同一个供应商(产品为表面工艺服务的供应商), + # 如果有的话,则将连续的多个外协工序(ID),绑定同一张外协出入库单,单独的供应商工序则生成单独的外协出入库单 + # 如果没有连续的外协工序为同一个供应商,则根据规则生成多张外协出入库单,并绑定不同的工序ID + + #以下代码可转移至生成工单的该行代码production.workorder_ids = workorders_values前后左右 + for item in self.mrp_production_ids: + process_parameter_workorder = self.env['mrp.workorder'].search( + [('surface_technics_parameters_id', '!=', False), ('production_id', '=', 83)]) + if process_parameter_workorder: + consecutive_workorders = [] + m =0 + sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id) + for i in range(len(sorted_workorders) - 1): + if sorted_workorders[i].supplier_id == sorted_workorders[i + 1].supplier_id and \ + sorted_workorders[i].id == sorted_workorders[i + 1].id - 1: + consecutive_workorders.append(sorted_workorders[i]) + consecutive_workorders.append(sorted_workorders[i + 1]) + m+1 + else: + + if m != len(sorted_workorders): + if consecutive_workorders: + self.env['stock.move'].create_outcontract_stock_move(consecutive_workorders,item) + # 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单,并将前面的consecutive_workorders和m置为初始值 + consecutive_workorders = [] + m =0 + self.env['stock.move'].create_outcontract_stock_move(consecutive_workorders, item) + if m == len(sorted_workorders): + self.env['stock.move'].create_outcontract_stock_move(consecutive_workorders, item) + + + + + if self.env.user.has_group('sale.group_auto_done_setting'): logging.info('函数已经执行=============5') self.action_done() @@ -152,17 +185,20 @@ class FinishStatusChange(models.Model): if self.user_has_groups('stock.group_reception_report') \ and self.picking_type_id.auto_show_reception_report: - lines = self.move_ids.filtered(lambda m: m.product_id.type == 'product' and m.state != 'cancel' and m.quantity_done and not m.move_dest_ids) + lines = self.move_ids.filtered(lambda + m: m.product_id.type == 'product' and m.state != 'cancel' and m.quantity_done and not m.move_dest_ids) if lines: # don't show reception report if all already assigned/nothing to assign - wh_location_ids = self.env['stock.location']._search([('id', 'child_of', self.picking_type_id.warehouse_id.view_location_id.id), ('usage', '!=', 'supplier')]) + wh_location_ids = self.env['stock.location']._search( + [('id', 'child_of', self.picking_type_id.warehouse_id.view_location_id.id), + ('usage', '!=', 'supplier')]) if self.env['stock.move'].search([ - ('state', 'in', ['confirmed', 'partially_available', 'waiting', 'assigned']), - ('product_qty', '>', 0), - ('location_id', 'in', wh_location_ids), - ('move_orig_ids', '=', False), - ('picking_id', 'not in', self.ids), - ('product_id', 'in', lines.product_id.ids)], limit=1): + ('state', 'in', ['confirmed', 'partially_available', 'waiting', 'assigned']), + ('product_qty', '>', 0), + ('location_id', 'in', wh_location_ids), + ('move_orig_ids', '=', False), + ('picking_id', 'not in', self.ids), + ('product_id', 'in', lines.product_id.ids)], limit=1): action = self.action_view_reception_report() action['context'] = {'default_picking_ids': self.ids} return action diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 75dfae84..b090c130 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -171,23 +171,22 @@ class MrpProduction(models.Model): workorders_values.append( self.env['mrp.workorder'].json_workorder_str('', production, route)) production.workorder_ids = workorders_values - process_parameter_workorder = self.env['mrp.workorder'].search( - [('surface_technics_parameters_id', '!=', False), ('production_id', '=', 58)]) - if process_parameter_workorder: - - # for st in process_parameter_workorder: + aa = self.env['mrp.workorder'].get_no_data(production.id) + if aa: consecutive_workorders = [] - sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id) + m =0 + sorted_workorders = sorted(aa, key=lambda w: w.id) for i in range(len(sorted_workorders) - 1): if sorted_workorders[i].supplier_id == sorted_workorders[i + 1].supplier_id and \ sorted_workorders[i].id == sorted_workorders[i + 1].id - 1: consecutive_workorders.append(sorted_workorders[i]) consecutive_workorders.append(sorted_workorders[i + 1]) + m+1 + process_parameter_workorder = self.env['mrp.workorder'].search( + [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id)]) for workorder in production.workorder_ids: workorder.duration_expected = workorder._get_duration_expected() - # 判断外协工序是否连续有多个外协工序为同一个供应商(产品为表面工艺服务的供应商), - # 如果有的话,则将连续的多个外协工序(ID),绑定同一张外协出入库单,单独的供应商工序则生成单独的外协出入库单 - # 如果没有连续的外协工序为同一个供应商,则根据规则生成多张外协出入库单,并绑定不同的工序ID + # 在之前的销售单上重新生成制造订单 def create_production1_values(self, production): diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 5c3fdf38..06b7911c 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -93,10 +93,14 @@ class ResMrpWorkOrder(models.Model): glb_file = fields.Binary("glb模型文件") is_subcontract = fields.Boolean(string='是否外协') surface_technics_parameters_id = fields.Many2one('sf.production.process.parameter', string="表面工艺可选参数") - stock_picking_in_ids = fields.One2many('stock.picking', 'workorder_in_id',string='库存外协入库单') - stock_picking_out_ids = fields.One2many('stock.picking', 'workorder_out_id', string='库存外协出库单') + picking_id = fields.Many2one('stock.picking', string='外协出入库单') supplier_id = fields.Integer('供应商Id') + def get_no_data(self, production_id): + process_parameter_workorder = self.search( + [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production_id)]) + return process_parameter_workorder + # 计算配料中心点和与x轴倾斜度方法 def getcenter(self): try: diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 767b8a1d..6525983b 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -3,7 +3,7 @@ from collections import defaultdict, namedtuple from odoo.addons.stock.models.stock_rule import ProcurementException from re import findall as regex_findall from re import split as regex_split -from odoo import SUPERUSER_ID, _, api, fields,models +from odoo import SUPERUSER_ID, _, api, fields, models from odoo.tools import float_compare from odoo.exceptions import UserError @@ -12,6 +12,13 @@ from odoo.exceptions import UserError class StockRule(models.Model): _inherit = 'stock.rule' + # @api.model + # def _run_pull(self, procurements): + # res = super(StockRule, self)._run_pull(procurements) + # # process_parameter_workorder = self.env['mrp.workorder'].search( + # # [('surface_technics_parameters_id', '!=', False), ('production_id', '=', self.production_id)]) + # stock_move = self.env['stock.move'].search([('raw_material_production_id', '=', self.id)]) + @api.model def _run_pull(self, procurements): moves_values_by_company = defaultdict(list) @@ -183,6 +190,54 @@ class StockRule(models.Model): subtype_id=self.env.ref('mail.mt_note').id) return True + def create_outcontract_stock_move(self, sorted_workorders, item): + outcontract_stock_move = self.env['stock.move'].search( + [('workorder_id', '=', sorted_workorders.id), ('production_id', '=', item.id)]) + if not outcontract_stock_move: + location_id = self.env.ref( + 'sf_manufacturing.stock_location_locations_virtual_outcontract').id, + location_dest_id = self.env['stock.location'].search( + [('barcode', '=', 'WH-PREPRODUCTION')]).id, + outcontract_picking_in = self.env['stock.rule'].create_outcontract_picking(item, + location_id, + location_dest_id) + outcontract_picking_in.write({'workorder_id': outcontract_picking_in.id}) + outcontract_picking_out = self.env['stock.rule'].create_outcontract_picking(item, + location_dest_id, + location_id) + outcontract_picking_out.write({'workorder_id': outcontract_picking_out.id}) + + # 生成外协出入库单 + def create_outcontract_picking(self, item, location_src_id, location_dest_id): + moves_values_by_company = defaultdict(list) + list2 = [] + Procurement = namedtuple('Procurement', ['product_id', 'product_qty', + 'product_uom', 'location_id', 'location_dest_id', 'name', 'origin', + 'company_id', + 'values']) + s = Procurement(product_id=item.bom_id.product_id, product_qty=1.0, product_uom=item.product_uom, + location_id=location_src_id, + location_dest_id=location_dest_id, + name=item.name, + origin=item.origin, + company_id=item.company_id, + values=item.values, + ) + item1 = list(item) + item1[0] = s + list2.append(tuple(item1)) + for procurement in list2: + move_values = self.env['stock.rule']._get_stock_move_values(*procurement) + moves_values_by_company[procurement.company_id.id].append(move_values) + for company_id, moves_values in moves_values_by_company.items(): + moves = self.env['stock.move'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create( + moves_values) + new_picking = True + picking = self.env['stock.picking'].create(moves._get_new_picking_values()) + moves.write({'picking_id': picking.id}) + moves._assign_picking_post_process(new=new_picking) + return picking + class ProductionLot(models.Model): _inherit = 'stock.lot' @@ -233,8 +288,7 @@ class ProductionLot(models.Model): class ResStockPicking(models.Model): _inherit = 'stock.picking' - workorder_in_id = fields.Many2one('mrp.workorder') - workorder_out_id = fields.Many2one('mrp.workorder') + workorder_id = fields.One2many('mrp.workorder', 'picking_id') class ResPurchaseOrder(models.Model):