from odoo import models, fields, api from odoo.exceptions import ValidationError from odoo.modules import get_resource_path from OCC.Extend.DataExchange import read_step_file from OCC.Extend.DataExchange import write_stl_file import logging import base64 import hashlib import os class ResProduct(models.Model): _inherit = 'product.template' # image_1920 = fields.Image(related='cutting_tool_parameter_image', store=True, # domain=[('cutting_tool_parameter_image', '!=', False)]) # @api.constrains('cutting_tool_parameter_length',) # def _check_length_or_width(self): # for record in self: # if record.cutting_tool == '刀片': # if record.cutting_tool_parameter_length <= 0 \ # and record.cutting_tool_parameter_width <= 0: # raise ValueError('该产品中有字段不能为零,请确认并重新输入!') # # # @api.constrains('cutting_tool_parameter_length', # 'cutting_tool_parameter_width') # def _check_length_or_width(self): # for record in self: # if record.cutting_tool == '刀片': # if record.cutting_tool_parameter_length <= 0 \ # and record.cutting_tool_parameter_width <= 0: # raise ValueError('该产品中有字段不能为零,请确认并重新输入!') # # if self.cutting_tool == '刀片': # # if self.cutting_tool_parameter_length == 0 \ # # or self.cutting_tool_parameter_width == 0: # # raise ValueError('该产品中有字段不能为零,请确认并重新输入!') # # @api.constrains('cutting_tool_parameter_height') # def _check_height(self): # if self.cutting_tool == '刀片': # if self.cutting_tool_parameter_height <= 0: # raise ValueError('该产品中高度不能为零,请确认并重新输入!') # # @api.constrains('cutting_tool_parameter_top_angle') # def _check_top_angle(self): # if self.cutting_tool == '刀片': # if self.cutting_tool_parameter_top_angle <= 0: # raise ValueError('该产品中顶角不能为零,请确认并重新输入!') # # @api.constrains('cutting_tool_parameter_r_angle') # def _check_r_angle(self): # if self.cutting_tool == '刀片': # if self.cutting_tool_parameter_r_angle <= 0: # raise ValueError('该产品中R角不能为零,请确认并重新输入!') # # @api.constrains('cutting_tool_parameter_radius') # def _check_radius(self): # if self.cutting_tool == '刀片': # if self.cutting_tool_parameter_radius <= 0: # raise ValueError('该产品中刀尖半径不能为零,请确认并重新输入!') # # @api.constrains('cutting_tool_parameter_handle_length', # 'cutting_tool_parameter_length1', # 'cutting_tool_parameter_diameter1') # # 'cutting_tool_parameter_body_accuracy', # # 'cutting_tool_parameter_detection_accuracy', # # 'cutting_tool_parameter_detection_hardness') # def _check_handle(self): # for record in self: # if record.cutting_tool == '刀柄': # if record.cutting_tool_parameter_handle_length == 0 \ # or record.cutting_tool_parameter_diameter1 == 0 \ # or record.cutting_tool_parameter_length1 == 0: # # or record.cutting_tool_parameter_detection_accuracy == 0 \ # # or record.cutting_tool_parameter_detection_hardness == 0 \ # # or record.cutting_tool_parameter_body_accuracy == 0: # raise ValueError('该产品中有字段不能为零,请确认并重新输入!') # # if self.cutting_tool == '刀柄': # # if self.cutting_tool_parameter_handle_length == 0 \ # # or self.cutting_tool_parameter_diameter1 == 0 \ # # or self.cutting_tool_parameter_length1 == 0 \ # # or self.cutting_tool_parameter_detection_accuracy == 0 \ # # or self.cutting_tool_parameter_detection_hardness == 0 \ # # or self.cutting_tool_parameter_body_accuracy == 0: # # raise ValueError('该产品中有字段不能为零,请确认并重新输入!') # # @api.constrains('cutting_tool_parameter_weight') # def _check_weight(self): # if self.cutting_tool == '刀柄': # if self.cutting_tool_parameter_weight == 0: # raise ValueError('该产品中重量不能为零,请确认并重新输入!') # @api.constrains('cutting_tool_parameter_c_diameter', # 'cutting_tool_parameter_l_total_length', # 'cutting_tool_parameter_d_diameter', # 'cutting_tool_parameter_wrench', # 'cutting_tool_parameter_screw', # 'cutting_tool_parameter_rounded_corner', # 'cutting_tool_parameter_hardness') # def _check_angle(self): # if self.cutting_tool in ['刀杆', '刀盘']: # if self.cutting_tool_parameter_c_diameter == 0 \ # or self.cutting_tool_parameter_l_total_length == 0 \ # or self.cutting_tool_parameter_d_diameter == 0 \ # or self.cutting_tool_parameter_wrench == 0 \ # or self.cutting_tool_parameter_screw == 0 \ # or self.cutting_tool_parameter_rounded_corner == 0 \ # or self.cutting_tool_parameter_hardness: # raise ValueError('该产品中有字段不能为零,请确认并重新输入!') # @api.constrains('cutting_tool_parameter_c_diameter', # 'cutting_tool_parameter_l_total_length', # 'cutting_tool_parameter_diameter1') # def _check_angle(self): # for record in self: # if record.cutting_tool == '整体式刀具' or record.cutting_tool == '刀片': # if record.cutting_tool_parameter_c_diameter == 0 \ # or record.cutting_tool_parameter_l_total_length == 0 \ # or record.cutting_tool_parameter_diameter1 == 0: # raise ValueError('该产品中有字段不能为零,请确认并重新输入!') # @api.constrains('cutting_tool_parameter_outer_diameter', # 'cutting_tool_parameter_inner_diameter', # 'cutting_tool_parameter_body_accuracy', # 'cutting_tool_parameter_handle_length', # 'cutting_tool_parameter_length1', # 'cutting_tool_parameter_diameter1') # def _check_angle(self): # for record in self: # if record.cutting_tool == '整体式刀具' or record.cutting_tool == '刀片': # if record.cutting_tool_parameter_front_angle == 0 \ # or record.cutting_tool_parameter_rear_angle == 0 \ # or record.cutting_tool_parameter_main_included_angle == 0: # raise ValueError('该产品中有字段不能为零,请确认并重新输入!') # @api.constrains('cutting_tool_parameter_front_angle', # 'cutting_tool_parameter_rear_angle', # 'cutting_tool_parameter_main_included_angle') # def _check_angle(self): # for record in self: # if record.cutting_tool == '整体式刀具' or record.cutting_tool == '刀片': # if record.cutting_tool_parameter_front_angle <= 0 \ # or record.cutting_tool_parameter_rear_angle <= 0 \ # or record.cutting_tool_parameter_main_included_angle <= 0: # raise ValueError('该产品中有字段不能为零,请确认并重新输入!') # # @api.constrains('cutting_tool_parameter_total_length', # 'cutting_tool_parameter_shank_length', # 'cutting_tool_parameter_blade_length', # 'cutting_tool_parameter_diameter') # def _check_length(self): # for record in self: # if record.cutting_tool == '整体式刀具': # if record.cutting_tool_parameter_total_length <= 0 \ # or record.cutting_tool_parameter_shank_length <= 0 \ # or record.cutting_tool_parameter_blade_length <= 0 \ # or record.cutting_tool_parameter_diameter <= 0: # raise ValueError('该产品中有字段不能为零,请确认并重新输入!') # @api.constrains('cutting_tool_parameter_total_length', # 'cutting_tool_parameter_shank_length', # 'cutting_tool_parameter_blade_length', # 'cutting_tool_parameter_diameter') # def _check_length(self): # for record in self: # if record.cutting_tool == '整体式刀具': # if record.cutting_tool_parameter_total_length == 0 \ # or record.cutting_tool_parameter_shank_length == 0 \ # or record.cutting_tool_parameter_blade_length == 0 \ # or record.cutting_tool_parameter_diameter == 0: # raise ValueError('该产品中有字段不能为零,请确认并重新输入!') # @api.constrains('cutting_tool_parameter_blade_number') # def _check_blade_number(self): # if self.cutting_tool in ['整体式刀具', '刀杆', '刀盘']: # if self.cutting_tool_parameter_blade_number <= 0: # raise ValueError('该产品中刃数不能为零,请确认并重新输入!') # # @api.constrains('cutting_tool_parameter_nut') # def _check_nut(self): # if self.cutting_tool in ['整体式刀具', '刀片', '刀柄', '夹头']: # if self.cutting_tool_parameter_nut <= 0: # raise ValueError('该产品中配对螺母不能为零,请确认并重新输入!') def _get_volume_uom_id_from_ir_config_parameter(self): product_length_in_feet_param = self.env['ir.config_parameter'].sudo().get_param('product.volume_in_cubic_feet') if product_length_in_feet_param == '1': return self.env.ref('uom.product_uom_cubic_foot') else: return self.env.ref('sf_dlm.product_uom_cubic_millimeter') # 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品 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 model_type = self.env['sf.model.type'].search([], limit=1) attachment = self.attachment_create(item['model_name'], item['model_data']) vals = { 'name': '%s-%s-%s' % ('P', order_id.name, i), 'model_long': item['model_long'] + model_type.embryo_tolerance, 'model_width': item['model_width'] + model_type.embryo_tolerance, 'model_height': item['model_height'] + model_type.embryo_tolerance, 'model_volume': (item['model_long'] + model_type.embryo_tolerance) * ( item['model_width'] + model_type.embryo_tolerance) * ( item['model_height'] + model_type.embryo_tolerance), 'product_model_type_id': model_type.id, 'model_processing_panel': 'R', 'model_machining_precision': item['model_machining_precision'], 'model_code': item['barcode'], 'length': item['model_long'], 'width': item['model_width'], 'height': item['model_height'], 'volume': item['model_long'] * item['model_width'] * item['model_height'], 'model_file': '' if not item['model_file'] else base64.b64decode(item['model_file']), 'model_name': attachment.name, 'upload_model_file': [(6, 0, [attachment.id])], # 'tag_ids': [(6, 0, [t.id for t in account_template.tag_ids])], # 'single_manufacturing': True, # 'tracking': 'serial', 'list_price': item['price'], # 'categ_id': self.env.ref('sf_dlm.product_category_finished_sf').id, '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_ids': self.get_production_process_id(item['surface_process_code']), 'model_process_parameters_ids': self.get_process_parameters_id(item['process_parameters_code']), 'model_remark': item['remark'], 'default_code': '%s-%s' % (order_number, i), # 'barcode': item['barcode'], 'active': True, # 'route_ids': self._get_routes('') } copy_product_id.sudo().write(vals) # product_id.product_tmpl_id.active = False return copy_product_id def _get_ids(self, param): type_ids = [] if not param: return [] for item in param: type_ids.append(item.id) return [(6, 0, type_ids)] def get_process_parameters_id(self, process_parameters_code): process_parameters_ids = [] for item in process_parameters_code: process_parameters = self.env['sf.production.process.parameter'].search([('code', '=', item)]) process_parameters_ids.append(process_parameters.id) return [(6, 0, process_parameters_ids)] def attachment_create(self, name, data): attachment = self.env['ir.attachment'].create({ 'datas': base64.b64decode(data), 'type': 'binary', 'public': True, 'description': '模型文件', 'name': name }) return attachment # 创建坯料 def no_bom_product_create(self, product_id, item, order_id, route_type, i): no_bom_copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy() no_bom_copy_product_id.product_tmpl_id.active = True materials_id = self.env['sf.production.materials'].search( [('materials_no', '=', item['texture_code'])]) materials_type_id = self.env['sf.materials.model'].search( [('materials_no', '=', item['texture_type_code'])]) model_type = self.env['sf.model.type'].search([], limit=1) supplier = self.env['mrp.bom'].get_supplier(materials_type_id) logging.info('no_bom_copy_product_supplier-vals:%s' % supplier) vals = { 'name': '%s-%s-%s [%s %s-%s * %s * %s]' % ('R', order_id.name, i, materials_id.name, materials_type_id.name, item['model_long'] + model_type.embryo_tolerance, item['model_width'] + model_type.embryo_tolerance, item['model_height'] + model_type.embryo_tolerance), 'length': item['model_long'] + model_type.embryo_tolerance, 'width': item['model_width'] + model_type.embryo_tolerance, 'height': item['model_height'] + model_type.embryo_tolerance, 'volume': (item['model_long'] + model_type.embryo_tolerance) * ( item['model_width'] + model_type.embryo_tolerance) * ( item['model_height'] + model_type.embryo_tolerance), 'embryo_model_type_id': model_type.id, 'list_price': item['price'], 'materials_id': materials_id.id, 'materials_type_id': materials_type_id.id, 'is_bfm': True, # 'route_ids': self._get_routes(route_type), # 'categ_id': self.env.ref('sf_dlm.product_category_embryo_sf').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 } # 外协和采购生成的坯料需要根据材料型号绑定供应商 if route_type == 'subcontract' or route_type == 'purchase': no_bom_copy_product_id.purchase_ok = True no_bom_copy_product_id.seller_ids = [ (0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0})] if route_type == 'subcontract': partner = self.env['res.partner'].search([('id', '=', supplier.partner_id.id)]) partner.is_subcontractor = True no_bom_copy_product_id.write(vals) logging.info('no_bom_copy_product_id-vals:%s' % vals) # product_id.product_tmpl_id.active = False return no_bom_copy_product_id @api.model_create_multi def create(self, vals_list): for vals in vals_list: if vals.get('upload_model_file'): if vals.get('is_bfm') is False and vals.get('categ_type') == '成品': for item in vals['upload_model_file']: logging.info('create-attachment:%s' % int(item[2][0])) attachment = self.env['ir.attachment'].sudo().search([('id', '=', int(item[2][0]))]) base64_data = base64.b64encode(attachment.datas) base64_datas = base64_data.decode('utf-8') model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest() report_path = attachment._full_path(attachment.store_fname) vals['model_file'] = self.transition_glb_file(report_path, model_code) logging.info('create-model_file:%s' % len(vals['model_file'])) self._sanitize_vals(vals) templates = super(ResProduct, self).create(vals_list) if "create_product_product" not in self._context: templates._create_variant_ids() # This is needed to set given values to first variant after creation for template, vals in zip(templates, vals_list): related_vals = {} for field_name in self._get_related_fields_variant_template(): if vals.get(field_name): related_vals[field_name] = vals[field_name] if related_vals: template.write(related_vals) return templates @api.onchange('upload_model_file') def onchange_model_file(self): for item in self: if item.upload_model_file: if len(item.upload_model_file) > 1: raise ValidationError('只允许上传一个文件') manufacturing_order = self.env['mrp.production'].search([('product_id', '=', self.id)]) if manufacturing_order: raise ValidationError('该产品已生成制造订单,无法进行修改') file_attachment_id = item.upload_model_file[0] # 附件路径 report_path = file_attachment_id._full_path(file_attachment_id.store_fname) base64_data = base64.b64encode(file_attachment_id.datas) base64_datas = base64_data.decode('utf-8') model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest() item.model_file = self.transition_glb_file(report_path, model_code) # 将attach的datas内容转为glb文件 def transition_glb_file(self, report_path, code): shapes = read_step_file(report_path) output_file = os.path.join('/tmp', str(code) + '.stl') write_stl_file(shapes, output_file, 'binary', 0.03, 0.5) # 转化为glb output_glb_file = os.path.join('/tmp', str(code) + '.glb') util_path = get_resource_path('sf_dlm', 'static/util') cmd = 'python3 %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file) os.system(cmd) # 转base64 with open(output_glb_file, 'rb') as fileObj: image_data = fileObj.read() base64_data = base64.b64encode(image_data) return base64_data # @api.onchange('cutting_tool_material_id') # def _get_cutting_tool_material_info(self): # for item in self: # if self.cutting_tool_type == '整体式刀具': # item.cutting_tool_parameter_brand_id = item.cutting_tool_model_id.brand.id # item.cutting_tool_parameter_total_length = item.cutting_tool_model_id.total_length # item.cutting_tool_parameter_shank_length = item.cutting_tool_model_id.shank_length # item.cutting_tool_parameter_blade_length = item.cutting_tool_model_id.blade_length # item.cutting_tool_parameter_diameter = item.cutting_tool_model_id.diameter # item.cutting_tool_parameter_nut = item.cutting_tool_model_id.nut # item.cutting_tool_parameter_blade_number = item.cutting_tool_model_id.blade_number # item.cutting_tool_parameter_material_model_id = item.cutting_tool_model_id.material_model.id # item.cutting_tool_parameter_front_angle = item.cutting_tool_model_id.front_angle # item.cutting_tool_parameter_rear_angle = item.cutting_tool_model_id.rear_angle # item.cutting_tool_parameter_main_included_angle = item.cutting_tool_model_id.main_included_angle # item.cutting_tool_parameter_chuck_model_ids = self._get_ids( # item.cutting_tool_model_id.chuck_model) # item.cutting_tool_parameter_scope = item.cutting_tool_model_id.scope # item.image_1920 = '' if not item.cutting_tool_model_id.image else item.cutting_tool_model_id.image # elif self.cutting_tool_type == '刀片': # item.cutting_tool_parameter_brand_id = item.cutting_tool_model_id.brand.id # item.cutting_tool_parameter_top_angle = item.cutting_tool_model_id.top_angle # item.cutting_tool_parameter_front_angle = item.cutting_tool_model_id.front_angle # item.cutting_tool_parameter_rear_angle = item.cutting_tool_model_id.rear_angle # item.cutting_tool_parameter_main_included_angle = item.cutting_tool_model_id.main_included_angle # item.cutting_tool_parameter_r_angle = item.cutting_tool_model_id.r_angle # item.cutting_tool_parameter_working_hardness = item.cutting_tool_model_id.hardness # item.cutting_tool_parameter_material_model_id = item.cutting_tool_model_id.material_model.id # item.cutting_tool_parameter_length = item.cutting_tool_model_id.length # item.cutting_tool_parameter_width = item.cutting_tool_model_id.width # item.cutting_tool_parameter_height = item.cutting_tool_model_id.height # item.cutting_tool_parameter_radius = item.cutting_tool_model_id.radius # item.cutting_tool_parameter_nut = item.cutting_tool_model_id.nut # item.cutting_tool_parameter_cutter_bar_ids = self._get_ids(item.cutting_tool_model_id.cutter_bar) # item.cutting_tool_parameter_cutter_pad_ids = self._get_ids(item.cutting_tool_model_id.cutter_pad) # item.image_1920 = '' if not item.cutting_tool_model_id.image else item.cutting_tool_model_id.image # elif self.cutting_tool_type == '刀杆': # item.cutting_tool_parameter_brand_id = item.cutting_tool_model_id.brand.id # item.cutting_tool_parameter_c_diameter = item.cutting_tool_model_id.c_diameter # item.cutting_tool_parameter_d_diameter = item.cutting_tool_model_id.d_diameter # item.cutting_tool_parameter_l_total_length = item.cutting_tool_model_id.total_length # item.cutting_tool_parameter_wrench = item.cutting_tool_model_id.wrench # item.cutting_tool_parameter_screw = item.cutting_tool_model_id.screw # item.cutting_tool_parameter_blade_ids = self._get_ids(item.cutting_tool_model_id.blade) # item.cutting_tool_parameter_scope = item.cutting_tool_model_id.scope # item.cutting_tool_parameter_material_model_id = item.cutting_tool_model_id.material_model.id # item.cutting_tool_parameter_rounded_corner = item.cutting_tool_model_id.radius # item.cutting_tool_parameter_accuracy_level = item.cutting_tool_model_id.accuracy # item.cutting_tool_parameter_blade_number = item.cutting_tool_model_id.blade_number # item.cutting_tool_parameter_hardness = item.cutting_tool_model_id.hardness # item.image_1920 = '' if not item.cutting_tool_model_id.image else item.cutting_tool_model_id.image # elif self.cutting_tool_type == '刀盘': # item.cutting_tool_parameter_brand_id = item.cutting_tool_model_id.brand.id # item.cutting_tool_parameter_c_diameter = item.cutting_tool_model_id.c_diameter # item.cutting_tool_parameter_d_diameter = item.cutting_tool_model_id.d_diameter # item.cutting_tool_parameter_l_total_length = item.cutting_tool_model_id.total_length # item.cutting_tool_parameter_wrench = item.cutting_tool_model_id.wrench # item.cutting_tool_parameter_screw = item.cutting_tool_model_id.screw # item.cutting_tool_parameter_blade_ids = item.cutting_tool_model_id.blade.id # item.cutting_tool_parameter_scope = item.cutting_tool_model_id.scope # item.cutting_tool_parameter_material_model_id = item.cutting_tool_model_id.material_model.id # item.cutting_tool_parameter_rounded_corner = item.cutting_tool_model_id.radius # item.cutting_tool_parameter_accuracy_level = item.cutting_tool_model_id.accuracy # item.cutting_tool_parameter_blade_number = item.cutting_tool_model_id.blade_number # item.cutting_tool_parameter_hardness = item.cutting_tool_model_id.hardness # item.image_1920 = '' if not item.cutting_tool_model_id.image else item.cutting_tool_model_id.image # elif self.cutting_tool_type == '刀柄': # item.cutting_tool_parameter_brand_id = item.cutting_tool_model_id.brand.id # item.cutting_tool_parameter_handle_length = item.cutting_tool_model_id.length # item.cutting_tool_parameter_length1 = item.cutting_tool_model_id.length1 # item.cutting_tool_parameter_diameter1 = item.cutting_tool_model_id.diameter1 # item.cutting_tool_parameter_body_accuracy = item.cutting_tool_model_id.body_accuracy # item.cutting_tool_parameter_nut = item.cutting_tool_model_id.nut # item.cutting_tool_parameter_clamping_range = item.cutting_tool_model_id.clamping_range # item.cutting_tool_parameter_weight = item.cutting_tool_model_id.weight # item.cutting_tool_parameter_material_model_id = item.cutting_tool_model_id.material_model.id # item.cutting_tool_parameter_chuck_model_ids = self._get_ids(item.cutting_tool_model_id.chuck_model) # item.cutting_tool_parameter_detection_accuracy = item.cutting_tool_model_id.detection_accuracy # item.cutting_tool_parameter_detection_hardness = item.cutting_tool_model_id.detection_hardness # item.cutting_tool_parameter_standard_speed = item.cutting_tool_model_id.standard_speed # item.image_1920 = '' if not item.cutting_tool_model_id.image else item.cutting_tool_model_id.image # elif self.cutting_tool_type == '夹头': # item.cutting_tool_parameter_brand_id = item.cutting_tool_model_id.brand.id # item.cutting_tool_parameter_outer_diameter = item.cutting_tool_model_id.diameter # item.cutting_tool_parameter_inner_diameter = item.cutting_tool_model_id.inner_diameter # item.cutting_tool_parameter_accuracy = item.cutting_tool_model_id.accuracy # item.cutting_tool_parameter_nut = item.cutting_tool_model_id.nut # item.cutting_tool_parameter_clamping_range = item.cutting_tool_model_id.clamping_range # item.cutting_tool_parameter_handle_model_ids = self._get_ids(item.cutting_tool_model_id.handle_model) # item.cutting_tool_parameter_material_model_id = item.cutting_tool_model_id.material_model.id # item.cutting_tool_parameter_height = item.cutting_tool_model_id.height # item.cutting_tool_parameter_feature = item.cutting_tool_model_id.feature # item.image_1920 = '' if not item.cutting_tool_model_id.image else item.cutting_tool_model_id.image # else: # item.cutting_tool_parameter_brand_id = False # item.cutting_tool_parameter_total_length = False # item.cutting_tool_parameter_shank_length = False # item.cutting_tool_parameter_blade_length = False # item.cutting_tool_parameter_diameter = False # item.cutting_tool_parameter_nut = False # item.cutting_tool_parameter_blade_number = False # item.cutting_tool_parameter_material_model_id = False # item.cutting_tool_parameter_front_angle = False # item.cutting_tool_parameter_rear_angle = False # item.cutting_tool_parameter_main_included_angle = False # item.cutting_tool_parameter_chuck_model_ids = False # item.cutting_tool_parameter_scope = False # item.cutting_tool_parameter_top_angle = False # item.cutting_tool_parameter_r_angle = False # item.cutting_tool_parameter_working_hardness = False # item.cutting_tool_parameter_length = False # item.cutting_tool_parameter_width = False # item.cutting_tool_parameter_height = False # item.cutting_tool_parameter_radius = False # item.cutting_tool_parameter_cutter_bar_ids = False # item.cutting_tool_parameter_cutter_pad_ids = False # item.cutting_tool_parameter_c_diameter = False # item.cutting_tool_parameter_d_diameter = False # item.cutting_tool_parameter_l_total_length = False # item.cutting_tool_parameter_wrench = False # item.cutting_tool_parameter_screw = False # item.cutting_tool_parameter_blade_ids = False # item.cutting_tool_parameter_rounded_corner = False # item.cutting_tool_parameter_accuracy_level = False # item.cutting_tool_parameter_hardness = False # item.cutting_tool_parameter_handle_length = False # item.cutting_tool_parameter_length1 = False # item.cutting_tool_parameter_diameter1 = False # item.cutting_tool_parameter_body_accuracy = False # item.cutting_tool_parameter_clamping_range = False # item.cutting_tool_parameter_weight = False # item.cutting_tool_parameter_detection_accuracy = False # item.cutting_tool_parameter_detection_hardness = False # item.cutting_tool_parameter_standard_speed = False # item.image_1920 = False class ResMrpBom(models.Model): _inherit = 'mrp.bom' def bom_create_line_has(self, embryo): vals = { 'bom_id': self.id, 'product_id': embryo.id, 'product_tmpl_id': embryo.product_tmpl_id.id, 'product_qty': 1, 'product_uom_id': 1 } return self.env['mrp.bom.line'].create(vals) # 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品后再次进行创建bom def bom_create(self, product, bom_type, product_type): bom_id = self.env['mrp.bom'].create({ 'product_tmpl_id': product.product_tmpl_id.id, 'type': bom_type, # 'subcontractor_id': '' or subcontract.partner_id.id, 'product_qty': 1, 'product_uom_id': 1 }) if bom_type == 'subcontract' and product_type is not False: subcontract = self.get_supplier(product.materials_type_id) bom_id.subcontractor_id = subcontract.partner_id.id return bom_id # 坯料BOM组件:选取当前坯料原材料, # 然后根据当前的坯料的体积得出需要的原材料重量(立方米m³) *材料密度 * 1000 = 所需原材料重量KG(公斤) # 坯料所需原材料公式:当前的坯料的体积(立方米m³) *材料密度 * 1000 = 所需原材料重量KG(公斤) def bom_create_line(self, embryo): # 选取当前坯料原材料 raw_bom_line = self.get_raw_bom(embryo) if raw_bom_line: bom_line = self.env['mrp.bom.line'].create({ 'bom_id': self.id, 'product_id': raw_bom_line.id, 'product_tmpl_id': raw_bom_line.product_tmpl_id.id, 'product_qty': round(embryo.volume * raw_bom_line.materials_type_id.density / 1000000), 'product_uom_id': raw_bom_line.uom_id.id, }) return bom_line else: return False # 查询材料型号默认排第一的供应商 def get_supplier(self, materials_type): seller_id = self.env['sf.supplier.sort'].search( [('materials_model_id', '=', materials_type.id)], limit=1, order='sequence asc') return seller_id # 匹配bom def get_bom(self, product): embryo_has = 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), ('is_bfm', '=', False) ], limit=1, order='volume desc' ) logging.info('get_bom-vals:%s' % embryo_has) if embryo_has: rate_of_waste = ((embryo_has.volume - product.model_volume) % embryo_has.volume) * 100 if rate_of_waste <= 20: return embryo_has 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 # @api.constrains('type') # def _check_type(self): # category = self.env['product.category'].search( # [('type', '=', self.type)]) # if category: # raise ValidationError("该类别已存在,请选择其他类别")