from odoo import models, fields, api from odoo.exceptions import ValidationError import logging class ResProductTemplate(models.Model): _inherit = 'product.template' # 模型的长,宽,高,体积,精度,材料 model_long = fields.Float('模型长[mm]', digits=(16, 3)) model_width = fields.Float('模型宽[mm]', digits=(16, 3)) model_height = fields.Float('模型高[mm]', digits=(16, 3)) model_volume = fields.Float('模型体积[m³]') model_machining_precision = fields.Selection([ ('±0.10mm', '±0.10mm'), ('±0.05mm', '±0.05mm'), ('±0.03mm', '±0.03mm'), ('±0.02mm', '±0.02mm'), ('±0.01mm', '±0.01mm')], string='加工精度') model_type_id = fields.Many2one('sf.model.type', string='模型类型') model_processing_panel = fields.Char('模型加工面板') model_surface_process_id = fields.Many2one('sf.production.process', string='表面工艺') model_process_parameters_id = fields.Many2one('sf.processing.technology', string='工艺参数') model_price = fields.Float('模型单价', digits=(16, 3)) model_remark = fields.Char('模型备注说明') length = fields.Float('长[mm]', digits=(16, 3)) width = fields.Float('宽[mm]', digits=(16, 3)) height = fields.Float('高[mm]', digits=(16, 3)) materials_id = fields.Many2one('sf.production.materials', string='材料') materials_type_id = fields.Many2one('sf.materials.model', string='材料型号') # volume = fields.Float(compute='_compute_volume', store=True) single_manufacturing = fields.Boolean(string="单个制造") # @api.depends('long', 'width', 'height') # def _compute_volume(self): # self.volume = self.long * self.width * self.height single_manufacturing = fields.Boolean(string="单个制造") @api.model def _get_route(self): route_manufacture = self.env.ref('stock.warehouse0', raise_if_not_found=False).manufacture_pull_id.route_id.id route_mto = self.env.ref('stock.warehouse0', raise_if_not_found=False).mto_pull_id.route_id.id if route_manufacture and route_mto: return [route_manufacture, route_mto] return [] route_ids = fields.Many2many(default=lambda self: self._get_route()) # @api.depends('long', 'width', 'height') # def _compute_volume(self): # self.volume = self.long * self.width * self.height # @api.depends('model_long', 'model_width', 'model_height') # def _compute_model_volume(self): # self.model_volume = self.model_long * self.model_width * self.model_height # 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品 def product_create(self, product_id, item, order_id, order_number, i): copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy() copy_product_id.product_tmpl_id.active = True logging.info('product_create:%s' % item) vals = { 'name': '%s-%s' % (order_id.name, i), 'model_long': item['model_long'], 'model_width': item['model_width'], 'model_height': item['model_height'], 'length': item['long'], 'width': item['width'], 'height': item['height'], 'volume': item['long'] * item['width'] * item['height'], 'model_price': item['price'], 'length': item['model_long'], 'width': item['model_width'], 'height': item['model_height'], 'volume': item['model_long'] * item['model_width'] * item['model_height'], 'model_price': item['price'], 'tracking': 'serial', 'single_manufacturing': True, 'list_price': item['price'], 'materials_id': self.env['sf.production.materials'].search( [('materials_no', '=', item['texture_code'])]).id, 'materials_type_id': self.env['sf.materials.model'].search( [('materials_no', '=', item['texture_type_code'])]).id, # 'model_surface_process_id': self.env['sf.production.process'].search( # [('process_encode', '=', item['surface_process_code'])]).id, # 'model_process_parameters_id': self.env['sf.processing.technology'].search( # [('process_encode', '=', item['process_parameters_code'])]).id, 'model_remark': item['remark'], # 'default_code': '%s-%s' % (order_number, i), # 'barcode': item['barcode'], 'active': True } logging.info('product_create1:%s' % item) copy_product_id.sudo().write(vals) return copy_product_id def no_bom_product_create(self, product_id, item, order_id): copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy() copy_product_id.product_tmpl_id.active = True logging.info('no_bom_product_create:%s' % item) materials_id = self.env['sf.production.materials'].search( [('materials_no', '=', item['texture_code'])]).id materials_type_id = self.env['sf.materials.model'].search( [('materials_no', '=', item['texture_type_code'])]).id vals = { 'name': '%s %s %s %s * %s * %s' % ( order_id.name, materials_id.name, materials_type_id.name, item['model_long'], item['model_width'], item['model_height']), 'model_long': item['model_long'], 'model_width': item['model_width'], 'model_height': item['model_height'], 'model_volume': item['model_long'] * item['model_width'] * item['model_height'], 'length': item['model_long'], 'width': item['model_width'], 'height': item['model_height'], 'volume': item['model_long'] * item['model_width'] * item['model_height'], 'model_price': item['price'], 'tracking': 'serial', 'single_manufacturing': True, 'list_price': item['price'], 'materials_id': materials_id.id, 'materials_type_id': materials_type_id.id, # 'model_surface_process_id': self.env['sf.production.process'].search( # [('process_encode', '=', item['surface_process_code'])]).id, # 'model_process_parameters_id': self.env['sf.processing.technology'].search( # [('process_encode', '=', item['process_parameters_code'])]).id, 'active': True } logging.info('product_create1:%s' % item) copy_product_id.sudo().write(vals) return copy_product_id # 根据模型类型默认给模型的长高宽加配置的长度; @api.onchange('model_type_id') def add_product_size(self): if not self.model_type_id: return model_type = self.env['sf.model.type'].search( [('id', '=', self.model_type_id.id), ('embryo_tolerance', '=', True)]) if model_type: self.model_long = self.model_long + 1 self.model_width = self.model_width + 1 self.model_height = self.model_width + 1 # for item in self: # print(item.model_long) # print(item.model_width) # print(item.model_height) # item.model_long = item.model_long + 1 # item.model_width = item.model_width + 1 # item.model_height = item.model_width + 1 else: return class ResMrpBom(models.Model): _inherit = 'mrp.bom' # 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品后再次进行创建bom def bom_create(self, product, bom_type): bom_id = self.env['mrp.bom'].create({ 'product_tmpl_id': product.product_tmpl_id.id, 'type': bom_type, 'product_qty': 1, 'product_uom_id': 1 }) return bom_id # 生成产品BOM匹配胚料,胚料的匹配规则: # 一、匹配的胚料类别需要带有胚料的标签; # 二、胚料的材料型号与生成产品的材料型号一致; # 三、胚料的长宽高均要大于模型的长宽高; # 四、如果匹配成功多个胚料,则选取体积最小的胚料; def bom_create_Line(self, product): logging.info('bom_create_Line:%s' % product) embryo = self.env['product.product'].search( [('categ_id.is_embryo', '=', True), ('materials_type_id', '=', product.materials_type_id.id), # 创建新的胚料,根据胚料材料型号的获取方式( # 自加工,外协,采购) 的配置, 选择不同的库存路线,一种材料型号配置一个路线相关的配置: # 材料型号配置不同的获取方式: (自加工, 外协, 采购); # 原材料重量KG(公斤)= 胚料的体积(立方米m³) * 材料密度 * 1000 def bom_create_Line(self, embryo, materials): bom_line = self.get_raw_bom(embryo, materials) vals = { 'bom_id': self.id, 'product_id': bom_line.id, 'product_tmpl_id': bom_line.product_tmpl_id.id, 'product_qty': bom_line.volume * bom_line.materials_type_id.density * 1000, 'product_uom_id': bom_line.uom_id.id } return self.env['mrp.bom.line'].create(vals) def get_bom(self, product): embryo = self.env['product.product'].search( [('categ_id.type', '=', '胚料'), ('materials_type_id', '=', product.materials_type_id.id), ('length', '>', product.length), ('width', '>', product.width), ('height', '>', product.height) ], limit=1, order='volume desc' ) logging.info('bom_create_Line1:%s' % product) return self.env['mrp.bom.line'].create(vals) if embryo: rate_of_waste = ((embryo.volume - product.model_volume) % embryo.volume) * 100 if rate_of_waste <= 20: return embryo else: return # 查bom的原材料 def get_raw_bom(self, product): raw_bom = self.env['product.product'].search( [('categ_id.type', '=', '原材料'), ('materials_type_id', '=', product.materials_type_id.id)]) return raw_bom class ResProductCategory(models.Model): _inherit = "product.category" type = fields.Selection( [("成品", "成品"), ("胚料", "胚料"), ("原材料", "原材料")], default="", string="类型") # @api.constrains('type') # def _check_type(self): # category = self.env['product.category'].search( # [('type', '=', self.type)]) # if category: # raise ValidationError("该类别已存在,请选择其他类别")