diff --git a/sf_base/models/common.py b/sf_base/models/common.py index f741c0ed..ff7262e3 100644 --- a/sf_base/models/common.py +++ b/sf_base/models/common.py @@ -119,6 +119,7 @@ class MrsProductionProcessParameter(models.Model): code = fields.Char("编码") name = fields.Char('名称') gain_way = fields.Selection([("自加工", "自加工"), ("外协", "外协")], default="", string="获取方式") + is_check = fields.Boolean(default=True) # price = fields.Float('单价') process_id = fields.Many2one('sf.production.process', string='表面工艺') materials_model_ids = fields.Many2many('sf.materials.model', 'applicable_material', string='适用材料') @@ -127,7 +128,7 @@ class MrsProductionProcessParameter(models.Model): def name_get(self): result = [] for parameter in self: - name = parameter.process_id.name + ',' + parameter.name + name = parameter.process_id.name + '-' + parameter.name result.append((parameter.id, name)) return result diff --git a/sf_dlm/models/product_template.py b/sf_dlm/models/product_template.py index 3e3bdfb2..1b6539df 100644 --- a/sf_dlm/models/product_template.py +++ b/sf_dlm/models/product_template.py @@ -15,7 +15,7 @@ class ResProductTemplate(models.Model): # 模型的长,宽,高,体积,精度,材料 model_name = fields.Char('模型名称') categ_type = fields.Selection( - [("成品", "成品"), ("胚料", "胚料"), ("原材料", "原材料"), ("表面工艺", "表面工艺"), ("服务", "服务")], + [("成品", "成品"), ("胚料", "胚料"), ("原材料", "原材料"), ("表面工艺", "表面工艺")], string='产品的类别', related='categ_id.type', store=True) model_long = fields.Float('模型长[mm]', digits=(16, 3)) diff --git a/sf_dlm/views/product_template_view.xml b/sf_dlm/views/product_template_view.xml index 8a01ce61..c071f40b 100644 --- a/sf_dlm/views/product_template_view.xml +++ b/sf_dlm/views/product_template_view.xml @@ -28,7 +28,7 @@ attrs="{'invisible': [('categ_type', '=', '表面工艺')]}"/> + attrs="{'invisible': ['|',('categ_type', '!=', '表面工艺'),('categ_type', '=', False)]}"/> diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index ec4c4e56..75dfae84 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -132,7 +132,7 @@ class MrpProduction(models.Model): # 表面工艺工序 # 获取表面工艺id surface_technics_arr = [] - #工序id + # 工序id route_workcenter_arr = [] for item in production.product_id.product_model_type_id.surface_technics_routing_tmpl_ids: surface_technics_arr.append(item.route_workcenter_id.surface_technics_id.id) @@ -149,6 +149,9 @@ class MrpProduction(models.Model): for param in production.product_id.model_process_parameters_ids: process_parameter = self.env['sf.production.process.parameter'].search( [('process_id.id', '=', pitem.id), ('id', '=', param.id)]) + # 产品为表面工艺服务的供应商 + product_production_process = self.env['product.template'].search( + [('server_product_process_parameters_id', '=', process_parameter.id)]) if process_parameter: for ritem in route_workcenter_arr: route_production_process = self.env['mrp.routing.workcenter'].search( @@ -157,7 +160,8 @@ class MrpProduction(models.Model): workorders_values.append( self.env['mrp.workorder']._json_workorder_surface_process_str( production, route_production_process, - process_parameter)) + process_parameter, + product_production_process.seller_ids[0].id)) elif production.product_id.categ_id.type == '胚料': embryo_routing_workcenter = self.env['sf.embryo.model.type.routing.sort'].search( [('embryo_model_type_id', '=', production.product_id.embryo_model_type_id.id)], @@ -167,8 +171,23 @@ 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: + consecutive_workorders = [] + 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]) 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 0efdc981..5c3fdf38 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -93,6 +93,9 @@ 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='库存外协出库单') + supplier_id = fields.Integer('供应商Id') # 计算配料中心点和与x轴倾斜度方法 def getcenter(self): @@ -160,7 +163,7 @@ class ResMrpWorkOrder(models.Model): return workorders_values_str # 拼接工单对象属性值(表面工艺) - def _json_workorder_surface_process_str(self, production, route, process_parameter): + def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id): workorders_values_str = [0, '', { 'product_uom_id': production.product_uom_id.id, 'qty_producing': 0, @@ -170,6 +173,7 @@ class ResMrpWorkOrder(models.Model): 'routing_type': '表面工艺', 'surface_technics_parameters_id': process_parameter.id, 'work_state': '', + 'supplier_id': supplier_id, 'is_subcontract': True if process_parameter.gain_way == '外协' else False, 'workcenter_id': self.env[ 'mrp.workcenter'].get_process_outsourcing_workcenter() if process_parameter.gain_way == '外协' else @@ -494,25 +498,25 @@ class ResMrpWorkOrder(models.Model): subcontract_workorder_count = self.env['mrp.workorder'].search_count( [('production_id', '=', workorder.production_id.id), ('is_subcontract', '=', True), ('state', '=', 'done')]) - if len(finish_workorder_count) == len(subcontract_workorder_count): - subcontract_workorder = self.env['mrp.workorder'].search( - [('production_id', '=', workorder.production_id.id), ('is_subcontract', '=', True), - ('state', '=', 'done')]) - for item in subcontract_workorder: - order_line_ids = [] - server_product = self.env['product.template'].search( - [('server_product_process_parameters_id', '=', item.surface_technics_parameters_id.id), - ('categ_type', '=', '服务'), ('detailed_type', '=', 'service')]) - order_line_ids.append((0, 0, { - 'product_id': server_product.id, - 'product_qty': 1, - 'product_uom': server_product.uom_id.id - })) - self.env['purchase.order'].create({ - 'partner_id': server_product.seller_ids[0].id, - 'state': 'draft', - 'order_line': order_line_ids, - }) + if finish_workorder_count > 0 and subcontract_workorder_count > 0: + subcontract_workorder = self.env['mrp.workorder'].search( + [('production_id', '=', workorder.production_id.id), ('is_subcontract', '=', True), + ('state', '=', 'done')]) + for item in subcontract_workorder: + order_line_ids = [] + server_product = self.env['product.template'].search( + [('server_product_process_parameters_id', '=', item.surface_technics_parameters_id.id), + ('categ_type', '=', '服务'), ('detailed_type', '=', 'service')]) + order_line_ids.append((0, 0, { + 'product_id': server_product.product_variant_id.id, + 'product_qty': 1, + 'product_uom': server_product.uom_id.id + })) + self.env['purchase.order'].create({ + 'partner_id': server_product.seller_ids.partner_id.id, + 'state': 'draft', + 'order_line': order_line_ids, + }) class CNCprocessing(models.Model): diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index ef1805eb..767b8a1d 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -3,8 +3,9 @@ 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, models +from odoo import SUPERUSER_ID, _, api, fields,models from odoo.tools import float_compare + from odoo.exceptions import UserError @@ -229,36 +230,29 @@ class ProductionLot(models.Model): return "%s-%03d" % (product.name, 1) +class ResStockPicking(models.Model): + _inherit = 'stock.picking' + + workorder_in_id = fields.Many2one('mrp.workorder') + workorder_out_id = fields.Many2one('mrp.workorder') + + class ResPurchaseOrder(models.Model): _inherit = 'purchase.order' - # def button_approve(self, force=False): - # result = super().button_approve(force=force) - # self._create_picking_RES() - # return result + # 外协出库、入库单 + def _prepare_picking_outcontract(self, sequence_code): + # if not self.group_id: + # self.group_id = self.group_id.create({ + # 'name': self.name, + # 'partner_id': self.partner_id.id + # }) + # if not self.partner_id.property_stock_supplier.id: + # raise UserError(_("You must set a Vendor Location for this partner %s", self.partner_id.name)) - # @api.depends('order_line.move_ids') - # def _compute_subcontracting_resupply_picking_count(self): - # for purchase in self: - # purchase.subcontracting_resupply_picking_count = len(purchase._get_subcontracting_resupplies_new()) - # - # def _get_subcontracting_resupplies_new(self): - # moves_subcontracted = self.order_line.move_ids.filtered(lambda m: m.is_subcontract) - # # subcontracted_productions = moves_subcontracted.move_orig_ids.production_id - # return moves_subcontracted.picking_id - - def _prepare_picking_RES(self): - if not self.group_id: - self.group_id = self.group_id.create({ - 'name': self.name, - 'partner_id': self.partner_id.id - }) - if not self.partner_id.property_stock_supplier.id: - raise UserError(_("You must set a Vendor Location for this partner %s", self.partner_id.name)) - picking_type_id_res = self.env['stock.picking.type'].search( - [('sequence_code', '=', 'RES'), ('barcode', '=', 'WH-RESUPPLY')]) + picking_type_id_oc = self.env['stock.picking.type'].search([('sequence_code', '=', sequence_code)]) return { - 'picking_type_id': picking_type_id_res.id if picking_type_id_res else self.picking_type_id.id, + 'picking_type_id': picking_type_id_oc.id if picking_type_id_oc else self.picking_type_id.id, 'partner_id': self.partner_id.id, 'user_id': False, 'date': self.date_order, @@ -268,17 +262,14 @@ class ResPurchaseOrder(models.Model): 'company_id': self.company_id.id, } - def _create_picking(self): + def _create_picking_outcontract(self): StockPicking = self.env['stock.picking'] for order in self.filtered(lambda po: po.state in ('purchase', 'done')): if any(product.type in ['product', 'consu'] for product in order.order_line.product_id): order = order.with_company(order.company_id) pickings = order.picking_ids.filtered(lambda x: x.state not in ('done', 'cancel')) if not pickings: - if order.order_line.product_id.categ_type == '胚料': - res = order._prepare_picking_RES() - else: - res = order._prepare_picking() + res = order._prepare_picking_outcontract() picking = StockPicking.with_user(SUPERUSER_ID).create(res) pickings = picking else: diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 702e9f9e..6c97ec0f 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -5,6 +5,10 @@ mrp.workorder + + + + @@ -113,8 +117,7 @@ ('is_user_working', '!=', False),('user_permissions','=',False),('name','=','获取CNC加工程序')]}"/>