diff --git a/sf_base/models/tool_other_features.py b/sf_base/models/tool_other_features.py index cb7e8eaf..0889f087 100644 --- a/sf_base/models/tool_other_features.py +++ b/sf_base/models/tool_other_features.py @@ -11,33 +11,33 @@ class ToolMaterialsBasicParameters(models.Model): store=True) # 整体式刀具参数 - total_length = fields.Char('总长度(mm)', size=20) + total_length = fields.Float('总长度(mm)') blade_number = fields.Selection( [('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8')], string='刃数(个)') - neck_diameter = fields.Char('颈部直径(mm)', size=20) - neck_length = fields.Char('颈部长度(mm)', size=20) - handle_diameter = fields.Char('柄部直径(mm)', size=20) - handle_length = fields.Char('柄部长度(mm)', size=20) - blade_tip_diameter = fields.Char('刀尖直径(mm)', size=20) + neck_diameter = fields.Float('颈部直径(mm)') + neck_length = fields.Float('颈部长度(mm)') + handle_diameter = fields.Float('柄部直径(mm)') + handle_length = fields.Float('柄部长度(mm)') + blade_tip_diameter = fields.Integer('刀尖直径(mm)') blade_tip_working_size = fields.Char('刀尖处理尺寸(R半径mm/倒角)', size=20) blade_tip_taper = fields.Integer('刀尖锥度(°)') - blade_diameter = fields.Char('刃部直径(mm)', size=20) - blade_length = fields.Char('刃部长度(mm)', size=20) + blade_diameter = fields.Float('刃部直径(mm)') + blade_length = fields.Float('刃部长度(mm)') blade_helix_angle = fields.Integer('刃部螺旋角(°)') - blade_width = fields.Char('刃部宽度(mm)', size=20) - blade_depth = fields.Char('刃部深度(mm)', size=20) - pitch = fields.Char('牙距(mm)', size=20) - cutting_depth = fields.Char('切削深度(mm)', size=20) + blade_width = fields.Float('刃部宽度(mm)') + blade_depth = fields.Float('刃部深度(mm)') + pitch = fields.Float('牙距(mm)') + cutting_depth = fields.Float('切削深度(mm)') # 刀片参数 - length = fields.Char('长度(mm)', size=20) - thickness = fields.Char('厚度(mm)', size=20) - width = fields.Char('宽度(mm)', size=20) - cutting_blade_length = fields.Char('切削刃长(mm)', size=20) + length = fields.Float('长度(mm)') + thickness = fields.Float('厚度(mm)') + width = fields.Float('宽度(mm)') + cutting_blade_length = fields.Float('切削刃长(mm)') relief_angle = fields.Integer('后角(°)') blade_tip_circular_arc_radius = fields.Char('刀尖圆弧半径(mm)', size=20) - inscribed_circle_diameter = fields.Char('内接圆直径(mm)', size=20) - install_aperture_diameter = fields.Char('安装孔直径(mm)', size=20) + inscribed_circle_diameter = fields.Float('内接圆直径(mm)') + install_aperture_diameter = fields.Float('安装孔直径(mm)') chip_breaker_groove = fields.Selection([('无', '无'), ('单面', '单面'), ('双面', '双面')], string='有无断屑槽') blade_teeth_model = fields.Selection( @@ -54,22 +54,22 @@ class ToolMaterialsBasicParameters(models.Model): blade_tip_dip_angle = fields.Integer('刀尖倾角(°)') side_cutting_edge_angle = fields.Integer('侧切削角(°)') thread_model = fields.Selection([('无', '无'), ('外螺纹', '外螺纹'), ('内螺纹', '内螺纹')], string='螺纹类型', default='无') - thread_num = fields.Char('每英寸螺纹数(tpi)', size=20) + thread_num = fields.Float('每英寸螺纹数(tpi)') blade_tip_height_tolerance = fields.Char('刀尖高度公差(mm)', size=20) inscribed_circle_tolerance = fields.Char('内接圆公差(mm)', size=20) thickness_tolerance = fields.Char('厚度公差(mm)', size=20) # 刀杆参数 - height = fields.Char('高度(mm)', size=20) - blade_height = fields.Char('刃部高度(mm)', size=20) - knife_head_height = fields.Char('刀头高度(mm)', size=20) - knife_head_width = fields.Char('刀头宽度(mm)', size=20) - knife_head_length = fields.Char('刀头长度(mm)', size=20) - cut_depth_max = fields.Char('最大切削深度(mm)', size=20) - cutter_arbor_diameter = fields.Char('刀杆直径(mm)', size=20) - min_machining_aperture = fields.Char('最小加工孔径(mm)', size=20) - install_blade_tip_num = fields.Char('可装刀片数/齿数(个)', size=20) + height = fields.Float('高度(mm)') + blade_height = fields.Float('刃部高度(mm)') + knife_head_height = fields.Float('刀头高度(mm)') + knife_head_width = fields.Float('刀头宽度(mm)') + knife_head_length = fields.Float('刀头长度(mm)') + cut_depth_max = fields.Float('最大切削深度(mm)') + cutter_arbor_diameter = fields.Float('刀杆直径(mm)') + min_machining_aperture = fields.Integer('最小加工孔径(mm)') + install_blade_tip_num = fields.Integer('可装刀片数/齿数(个)') cutting_blade_model = fields.Char('切削类型', size=20) - is_cooling_hole = fields.Boolean('有无冷却孔', default=False) + is_cooling_hole = fields.Boolean('有无冷却孔') locating_slot_code = fields.Char('定位槽代号', size=20) installing_structure = fields.Char('安装结构', size=20) blade_ids = fields.Many2many( @@ -86,20 +86,20 @@ class ToolMaterialsBasicParameters(models.Model): screw = fields.Char('适配螺钉型号', size=50) spanner = fields.Char('适配扳手型号', size=50) # 刀盘参数 - cutter_head_diameter = fields.Char('刀盘直径(mm)', size=20) - interface_diameter = fields.Char('接口直径(mm)', size=20) + cutter_head_diameter = fields.Float('刀盘直径(mm)') + interface_diameter = fields.Float('接口直径(mm)') # 刀柄参数 - flange_shank_length = fields.Char('法兰柄长(mm)', size=20) - handle_external_diameter = fields.Char('柄部外径(mm)', size=20) - handle_inside_diameter = fields.Char('柄部内径(mm)', size=20) - min_clamping_diameter = fields.Char('最小夹持直径(mm)', size=20) - max_clamping_diameter = fields.Char('最大夹持直径(mm)', size=20) + flange_shank_length = fields.Float('法兰柄长(mm)') + handle_external_diameter = fields.Float('柄部外径(mm)') + handle_inside_diameter = fields.Float('柄部内径(mm)') + min_clamping_diameter = fields.Float('最小夹持直径(mm)') + max_clamping_diameter = fields.Float('最大夹持直径(mm)') clamping_mode = fields.Char('夹持方式', size=20) - max_load_capacity = fields.Char('最大负载能力(kg)', size=20) + max_load_capacity = fields.Float('最大负载能力(kg)') taper = fields.Integer('锥度(°)') tool_changing_time = fields.Integer('换刀时间(s)') - standard_rotate_speed = fields.Char('标准转速(n/min)', size=20) - max_rotate_speed = fields.Char('最大转速(n/min)', size=20) + standard_rotate_speed = fields.Integer('标准转速(n/min)') + max_rotate_speed = fields.Integer('最大转速(n/min)') diameter_slip_accuracy = fields.Char('径跳精度(mm)', size=20) cooling_model = fields.Char('冷却类型', size=20) is_rough_machining = fields.Boolean('可粗加工', default=False) @@ -109,12 +109,12 @@ class ToolMaterialsBasicParameters(models.Model): is_safe_lock = fields.Boolean('有无安全锁', default=False) # 夹头参数 er_size_model = fields.Char('ER尺寸型号', size=20) - outer_diameter = fields.Char('外径(mm)', size=20) - inner_diameter = fields.Char('内径(mm)', size=20) + outer_diameter = fields.Float('外径(mm)') + inner_diameter = fields.Float('内径(mm)') run_out_accuracy = fields.Char('跳动精度(mm)', size=20) - top_diameter = fields.Char('顶部直径(mm)', size=20) - weight = fields.Char('重量(kg)', size=20) - clamping_length = fields.Char('夹持长度(mm)', size=20) + top_diameter = fields.Float('顶部直径(mm)') + weight = fields.Float('重量(kg)', size=20) + clamping_length = fields.Float('夹持长度(mm)') clamping_tolerance = fields.Char('夹持公差(mm)', size=20) cooling_jacket = fields.Char('适用冷却套型号', size=50) handle_ids = fields.Many2many( diff --git a/sf_base/views/tool_basic_param.xml b/sf_base/views/tool_basic_param.xml index a512de10..dfe3eaf7 100644 --- a/sf_base/views/tool_basic_param.xml +++ b/sf_base/views/tool_basic_param.xml @@ -84,11 +84,11 @@ - + sf.tool.materials.basic.parameters.tree sf.tool.materials.basic.parameters - + diff --git a/sf_dlm/__init__.py b/sf_dlm/__init__.py index 8b137891..0650744f 100644 --- a/sf_dlm/__init__.py +++ b/sf_dlm/__init__.py @@ -1 +1 @@ - +from . import models diff --git a/sf_dlm/__manifest__.py b/sf_dlm/__manifest__.py index ed9e2053..7878467b 100644 --- a/sf_dlm/__manifest__.py +++ b/sf_dlm/__manifest__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. { - 'name': '机企猫智能工厂 产品管理', + 'name': '机企猫智能工厂 产品', 'version': '1.0', 'summary': '智能工厂产品模块', 'sequence': 1, @@ -10,16 +10,12 @@ """, 'category': 'sf', 'website': 'https://www.sf.jikimo.com', - 'depends': ['mrp', 'base', 'sf_manufacturing', 'web_widget_model_viewer', 'mrp_subcontracting', - 'purchase_stock', - 'uom', 'jikimo_frontend', 'product'], + 'depends': ['sf_base', 'web_widget_model_viewer', 'mrp_subcontracting', 'purchase_stock', 'uom', ], 'data': [ 'data/product_data.xml', 'data/uom_data.xml', 'security/ir.model.access.csv', - # 'wizard/cutting_tool_specification_wizard.xml', 'views/product_template_view.xml', - 'views/product_workorder.xml' ], 'demo': [ ], diff --git a/sf_dlm/models/__init__.py b/sf_dlm/models/__init__.py index f6ca84cc..604ef9a2 100644 --- a/sf_dlm/models/__init__.py +++ b/sf_dlm/models/__init__.py @@ -1,4 +1,3 @@ -# from . import product_template from . import product_supplierinfo diff --git a/sf_dlm/models/product_supplierinfo.py b/sf_dlm/models/product_supplierinfo.py index 25dd7398..a5ef52ae 100644 --- a/sf_dlm/models/product_supplierinfo.py +++ b/sf_dlm/models/product_supplierinfo.py @@ -1,4 +1,113 @@ -from odoo import models +# -*- coding: utf-8 -*- +from odoo import models, fields + + +class ResProductCategory(models.Model): + _inherit = "product.category" + + type = fields.Selection( + [("成品", "成品"), ("坯料", "坯料"), ("原材料", "原材料"), ("表面工艺", "表面工艺"), ("刀具", "刀具"), + ("夹具", "夹具"), ("功能刀具", "功能刀具")], + default="", string="类型") + + +class ResProductProduct(models.Model): + _inherit = 'product.product' + + single_manufacturing = fields.Boolean(string="单个制造") + is_bfm = fields.Boolean('业务平台是否自动创建', default=False) + + +class ResProducTemplate(models.Model): + _inherit = 'product.template' + + single_manufacturing = fields.Binary('模型文件') + + +class ResMrpBomMo(models.Model): + _inherit = 'mrp.bom' + + subcontractor_id = fields.Many2one('res.partner', string='外包商') + + 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: + qty = 1 + if round(embryo.volume * raw_bom_line.materials_type_id.density / 1000000) > 1: + qty = round(embryo.volume * raw_bom_line.materials_type_id.density / 1000000) + 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': qty, + '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 class ResSupplierInfo(models.Model): @@ -8,5 +117,5 @@ class ResSupplierInfo(models.Model): for supplier in self: boms = supplier.product_id.variant_bom_ids boms |= supplier.product_tmpl_id.bom_ids.filtered(lambda b: not b.product_id or b.product_id in ( - supplier.product_id or supplier.product_tmpl_id.product_variant_ids)) + supplier.product_id or supplier.product_tmpl_id.product_variant_ids)) supplier.is_subcontractor = supplier.partner_id in boms.subcontractor_id diff --git a/sf_dlm/models/product_template.py b/sf_dlm/models/product_template.py deleted file mode 100644 index c6719361..00000000 --- a/sf_dlm/models/product_template.py +++ /dev/null @@ -1,407 +0,0 @@ -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('该产品中配对螺母不能为零,请确认并重新输入!') - - - # @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("该类别已存在,请选择其他类别") diff --git a/sf_dlm/views/product_template_view.xml b/sf_dlm/views/product_template_view.xml index b212ddef..6331d841 100644 --- a/sf_dlm/views/product_template_view.xml +++ b/sf_dlm/views/product_template_view.xml @@ -1,559 +1,6 @@ - - - - - - - - - - - - - - - - product.template.form.inherit.sf - product.template - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - product.template.only.form.inherit.sf - product.template - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - product.category.form.inherit.sf diff --git a/sf_dlm/views/product_workorder.xml b/sf_dlm/views/product_workorder.xml deleted file mode 100644 index 4c5f2a10..00000000 --- a/sf_dlm/views/product_workorder.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - production.workorder.dlm - mrp.workorder - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/sf_dlm_management/__init__.py b/sf_dlm_management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/sf_dlm_management/__manifest__.py b/sf_dlm_management/__manifest__.py new file mode 100644 index 00000000..b10fa76d --- /dev/null +++ b/sf_dlm_management/__manifest__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +{ + 'name': '机企猫智能工厂 产品管理', + 'version': '1.0', + 'summary': '智能工厂产品模块', + 'sequence': 1, + 'description': """ + """, + 'category': 'sf', + 'website': 'https://www.sf.jikimo.com', + 'depends': ['sf_sale', 'sf_dlm','sf_manufacturing'], + 'data': [ + 'views/product_template_management_view.xml', + ], + 'demo': [ + ], + 'qweb': [ + ], + 'license': 'LGPL-3', + 'installable': True, + 'application': False, + 'auto_install': False, +} diff --git a/sf_dlm_management/data/product_data.xml b/sf_dlm_management/data/product_data.xml new file mode 100644 index 00000000..b7c9bfbf --- /dev/null +++ b/sf_dlm_management/data/product_data.xml @@ -0,0 +1,116 @@ + + + + + 坯料 + 坯料 + + + 成品 + 成品 + + + + 原材料 + 原材料 + + + + 表面工艺 + 表面工艺 + + + + 刀具 + 刀具 + + + + 夹具 + 夹具 + + + + 功能刀具 + 功能刀具 + + + + 功能刀具 + + + delivery + product + false + + + + serial + + + + CNC加工产品模板 + + + + delivery + product + false + + + + + serial + + + + 坯料自加工模板 + + + + delivery + product + false + + + + + serial + + + + + 坯料外协加工模板 + + + + delivery + product + true + + + + serial + false + + + 坯料采购模板 + + + + delivery + product + true + + + + serial + false + + + \ No newline at end of file diff --git a/sf_dlm_management/models/__init__.py b/sf_dlm_management/models/__init__.py new file mode 100644 index 00000000..a4da1521 --- /dev/null +++ b/sf_dlm_management/models/__init__.py @@ -0,0 +1,7 @@ +#from . import product_template +#from . import product_supplierinfo + + + + +# \ No newline at end of file diff --git a/sf_dlm_management/views/product_template_management_view.xml b/sf_dlm_management/views/product_template_management_view.xml new file mode 100644 index 00000000..f2bfb732 --- /dev/null +++ b/sf_dlm_management/views/product_template_management_view.xml @@ -0,0 +1,528 @@ + + + + + product.template.form.inherit.sf + product.template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + product.template.only.form.inherit.sf + product.template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sf_manufacturing/models/model_type.py b/sf_manufacturing/models/model_type.py index 71161b59..cfa5bea8 100644 --- a/sf_manufacturing/models/model_type.py +++ b/sf_manufacturing/models/model_type.py @@ -1,13 +1,7 @@ from odoo import fields, models,api -class ResProductCategory(models.Model): - _inherit = "product.category" - type = fields.Selection( - [("成品", "成品"), ("坯料", "坯料"), ("原材料", "原材料"), ("表面工艺", "表面工艺"), ("刀具", "刀具"), - ("夹具", "夹具"), ("功能刀具", "功能刀具")], - default="", string="类型") class ModelType(models.Model): diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index b1efb4a3..29f5c063 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -1,9 +1,10 @@ +# -*- coding: utf-8 -*- from odoo import models, fields, api, _ from odoo.exceptions import ValidationError from odoo.modules import get_resource_path from odoo.addons.sf_base.commons.common import Common -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file import logging import base64 import hashlib @@ -14,22 +15,9 @@ import json class ResProductMo(models.Model): _inherit = 'product.template' + model_file = fields.Binary('模型文件') - - # categ_type = fields.Selection( - # [("成品", "成品"), ("坯料", "坯料"), ("原材料", "原材料"), ("表面工艺", "表面工艺"), ("刀具", "刀具"), - # ("夹具", "夹具")], - # string='产品的类别', compute='_compute_categ_id', - # store=True) - # - # @api.depends('categ_id') - # def _compute_categ_id(self): - # for record in self: - # if record: - # record.categ_type = record.categ_id.type - categ_type = fields.Selection(string='产品的类别', related='categ_id.type', store=True) - model_name = fields.Char('模型名称') model_long = fields.Float('模型长(mm)', digits=(16, 3)) model_width = fields.Float('模型宽(mm)', digits=(16, 3)) @@ -46,10 +34,11 @@ class ResProductMo(models.Model): length = fields.Float('长(mm)', digits=(16, 3)) width = fields.Float('宽(mm)', digits=(16, 3)) height = fields.Float('高(mm)', digits=(16, 3)) - single_manufacturing = fields.Boolean(string="单个制造") + # single_manufacturing = fields.Boolean(string="单个制造") model_code = fields.Char('模型编码') is_bfm = fields.Boolean('业务平台是否自动创建', default=False) upload_model_file = fields.Many2many('ir.attachment', 'upload_model_file_attachment_ref', string='上传模型文件') + model_file = fields.Binary('模型文件') product_model_type_id = fields.Many2one('sf.model.type', string='产品模型类型') embryo_model_type_id = fields.Many2one('sf.model.type', string='坯料模型类型') materials_id = fields.Many2one('sf.production.materials', string='材料') @@ -81,7 +70,7 @@ class ResProductMo(models.Model): # 整体式刀具特有字段 cutting_tool_total_length = fields.Float('总长度(mm)', digits=(6, 1)) cutting_tool_shank_length = fields.Float('柄部长度(mm)', digits=(6, 1)) - cutting_tool_blade_length = fields.Char('刃部长度(mm)') + cutting_tool_blade_length = fields.Float('刃部长度(mm)') cutting_tool_blade_number = fields.Selection( [('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8')], '刃数(个)') # 整体式刀具新增字段 @@ -92,23 +81,23 @@ class ResProductMo(models.Model): cutting_tool_blade_tip_taper = fields.Integer('刀尖锥度(°)') cutting_tool_blade_helix_angle = fields.Integer('刃部螺旋角(°)') cutting_tool_blade_type = fields.Char('刃部类型') - cutting_tool_pitch = fields.Char('牙距(mm)', size=20) - cutting_tool_blade_width = fields.Char('刃部宽度(mm)', size=20) - cutting_tool_blade_depth = fields.Char('刃部深度(mm)', size=20) - cutting_tool_cut_depth = fields.Char('切削深度(mm)', size=20) - cutting_tool_cut_depth_max = fields.Char('最大切削深度(mm)', size=20) + cutting_tool_pitch = fields.Float('牙距(mm)') + cutting_tool_blade_width = fields.Float('刃部宽度(mm)') + cutting_tool_blade_depth = fields.Float('刃部深度(mm)') + cutting_tool_cut_depth = fields.Float('切削深度(mm)') + cutting_tool_cut_depth_max = fields.Float('最大切削深度(mm)') cutting_tool_coarse_medium_fine = fields.Selection([('粗', '粗'), ('中', '中'), ('精', '精')], '粗/中/精') cutting_tool_run_out_accuracy_max = fields.Float('端跳精度max', digits=(6, 1)) cutting_tool_run_out_accuracy_min = fields.Float('端跳精度min', digits=(6, 1)) cutting_tool_blade_tip_working_size = fields.Char('刀尖处理尺寸(R半径mm/倒角)', size=20) fit_blade_shape_id = fields.Many2many('maintenance.equipment.image', 'rel_fit_blade_shape_product_template', - '适配刀片形状', domain=[('type', '=', '刀片形状')]) + '适配刀片形状', domain=[('type', '=', '刀片形状')]) suitable_machining_method_ids = fields.Many2many('maintenance.equipment.image', 'rel_machining_product_template', '适合加工方式', domain=[('type', '=', '加工能力')]) blade_tip_characteristics_id = fields.Many2many('maintenance.equipment.image', - 'rel_blade_tip_product_template', '刀尖特征', - domain=[('type', '=', '刀尖特征')]) + 'rel_blade_tip_product_template', '刀尖特征', + domain=[('type', '=', '刀尖特征')]) handle_type_ids = fields.Many2many('maintenance.equipment.image', 'rel_handle_product_template', '柄部类型', domain=[('type', '=', '柄部类型')]) cutting_direction_ids = fields.Many2many('maintenance.equipment.image', 'rel_cutting_product_template', @@ -116,7 +105,7 @@ class ResProductMo(models.Model): suitable_coolant_ids = fields.Many2many('maintenance.equipment.image', 'rel_coolant_product_template', '适合冷却液', domain=[('type', '=', '冷却液')]) compaction_way_ids = fields.Many2many('maintenance.equipment.image', 'rel_compaction_product_template', - '压紧方式', domain=[('type', '=', '压紧方式')]) \ + '压紧方式', domain=[('type', '=', '压紧方式')]) @api.onchange('cutting_tool_material_id') def _onchange_cutting_tool_material_id(self): @@ -162,29 +151,29 @@ class ResProductMo(models.Model): item.cutting_speed_ids = False item.feed_per_tooth_ids = False - # def choice(self): - # if self.cutting_tool_type == '整体式刀具': - # tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_integral_tree') - # elif self.cutting_tool_type == '刀片': - # tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_blade_tree') - # elif self.cutting_tool_type == '刀杆': - # tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_cutter_bar_tree') - # elif self.cutting_tool_type == '刀盘': - # tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_tree') - # elif self.cutting_tool_type == '刀柄': - # tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_tree') - # else : - # tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_tree') - # return { - # 'name': _('规格'), - # 'view_mode': 'list', - # 'view_id': tree_view.id, - # 'type': 'ir.actions.act_window', - # 'res_model': 'sf.tool.materials.basic.parameters', - # 'target': 'new', - # 'domain': [('cutting_tool_type', '=', self.cutting_tool_type), - # ('standard_library_id', '=', self.cutting_tool_model_id.id)], - # } + def choice(self): + if self.cutting_tool_type == '整体式刀具': + tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_integral_tree') + elif self.cutting_tool_type == '刀片': + tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_blade_tree') + elif self.cutting_tool_type == '刀杆': + tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_cutter_bar_tree') + elif self.cutting_tool_type == '刀盘': + tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_tree') + elif self.cutting_tool_type == '刀柄': + tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_tree') + else: + tree_view = self.env.ref('sf_base.view_sf_tool_materials_basic_parameters_tree') + return { + 'name': _('规格'), + 'view_mode': 'list', + 'view_id': tree_view.id, + 'type': 'ir.actions.act_window', + 'res_model': 'sf.tool.materials.basic.parameters', + 'target': 'new', + 'domain': [('cutting_tool_type', '=', self.cutting_tool_type), + ('standard_library_id', '=', self.cutting_tool_model_id.id)], + } @api.onchange('specification_id') def _onchange_specification(self): @@ -307,7 +296,7 @@ class ResProductMo(models.Model): [])] if not self.cutting_tool_model_id.suitable_machining_method_ids else [ (6, 0, self.cutting_tool_model_id.suitable_machining_method_ids.ids)] self.blade_tip_characteristics_id = [(6, 0, - [])] if not self.cutting_tool_model_id.blade_tip_characteristics_id else [ + [])] if not self.cutting_tool_model_id.blade_tip_characteristics_id else [ (6, 0, self.cutting_tool_model_id.blade_tip_characteristics_id.ids)] self.handle_type_ids = [(6, 0, @@ -325,7 +314,6 @@ class ResProductMo(models.Model): [])] if not self.cutting_tool_model_id.compaction_way_ids else [ (6, 0, self.cutting_tool_model_id.compaction_way_ids.ids)] - # @api.constrains('suitable_machining_method_ids') # def _check_suitable_machining_method_ids(self): # for record in self: @@ -410,10 +398,8 @@ class ResProductMo(models.Model): # raise ValidationError("端跳精度最大(max)不能为0") cutting_tool_diameter = fields.Float('直径(mm)') - cutting_tool_front_angle = fields.Integer('前角(°)') cutting_tool_rear_angle = fields.Integer('后角(°)') cutting_tool_main_included_angle = fields.Integer('主偏角(°)') - # cutting_tool_material_model_id = fields.Many2one('sf.materials.model', '材料型号') # 适用夹头型号可以多选 cutting_tool_chuck_ids = fields.Many2many( 'sf.cutting_tool.standard.library', @@ -423,11 +409,11 @@ class ResProductMo(models.Model): domain="[('cutting_tool_type', '=', '夹头')]", string='适用夹头型号') # 刀片参数 - cutting_tool_cut_blade_length = fields.Char('切削刃长(mm)', size=20) + cutting_tool_cut_blade_length = fields.Float('切削刃长(mm)') cutting_tool_blade_tip_circular_arc_radius = fields.Char('刀尖圆弧半径(mm)', size=20) cutting_tool_top_angle = fields.Integer('顶角(°)') - cutting_tool_inscribed_circle_diameter = fields.Char('内接圆直径(mm)', size=20) - cutting_tool_install_aperture_diameter = fields.Char('安装孔直径(mm)', size=20) + cutting_tool_inscribed_circle_diameter = fields.Float('内接圆直径(mm)') + cutting_tool_install_aperture_diameter = fields.Float('安装孔直径(mm)') cutting_tool_chip_breaker_groove = fields.Selection([('无', '无'), ('单面', '单面'), ('双面', '双面')], string='有无断屑槽') cutting_tool_bladed_teeth_model = fields.Selection( @@ -445,7 +431,7 @@ class ResProductMo(models.Model): cutting_tool_side_cutting_edge_angle = fields.Integer('侧切削角(°)') cutting_tool_thread_model = fields.Selection([('无', '无'), ('外螺纹', '外螺纹'), ('内螺纹', '内螺纹')], string='螺纹类型') - cutting_tool_thread_num = fields.Char('每英寸螺纹数(tpi)', size=20) + cutting_tool_thread_num = fields.Float('每英寸螺纹数(tpi)') cutting_tool_blade_tip_height_tolerance = fields.Char('刀尖高度公差(mm)', size=20) cutting_tool_inscribed_circle_tolerance = fields.Char('内接圆公差(mm)', size=20) cutting_tool_thickness_tolerance = fields.Char('厚度公差(mm)', size=20) @@ -473,9 +459,9 @@ class ResProductMo(models.Model): cutting_tool_knife_head_width = fields.Float('刀头宽度(mm)') cutting_tool_knife_head_length = fields.Float('刀头长度(mm)') cutting_tool_blade_diameter = fields.Float('刃径/刃部直径(mm)') - cutting_tool_cutter_arbor_diameter = fields.Char('刀杆直径(mm)', size=20) - cutting_tool_min_machining_aperture = fields.Char('最小加工孔径(mm)', size=20) - cutting_tool_install_blade_tip_num = fields.Char('可装刀片数/齿数(个)', size=20) + cutting_tool_cutter_arbor_diameter = fields.Float('刀杆直径(mm)') + cutting_tool_min_machining_aperture = fields.Integer('最小加工孔径(mm)') + cutting_tool_install_blade_tip_num = fields.Integer('可装刀片数/齿数(个)', size=20) cutting_tool_installing_structure = fields.Char('安装结构', size=20) cutting_tool_blade_ids = fields.Many2many( 'sf.cutting_tool.standard.library', @@ -493,8 +479,8 @@ class ResProductMo(models.Model): cutting_tool_is_cooling_hole = fields.Boolean('有无冷却孔', default=False) cutting_tool_locating_slot_code = fields.Char('定位槽代号', size=20) # 刀盘参数 - cutting_tool_cutter_head_diameter = fields.Char('刀盘直径(mm)', size=20) - cutting_tool_interface_diameter = fields.Char('接口直径(mm)', size=20) + cutting_tool_cutter_head_diameter = fields.Float('刀盘直径(mm)') + cutting_tool_interface_diameter = fields.Float('接口直径(mm)') # 刀柄参数 cutting_tool_shank_outer_diameter = fields.Float('柄部外径(mm)') @@ -512,7 +498,7 @@ class ResProductMo(models.Model): cutting_tool_is_high_speed_cutting = fields.Boolean('可高速切削', default=False) cutting_tool_change_time = fields.Integer('换刀时间(s)') cutting_tool_clamping_way = fields.Char('夹持方式') - cutting_tool_standard_speed = fields.Char('标准转速(n/min)') + cutting_tool_standard_speed = fields.Integer('标准转速(n/min)') cutting_tool_speed_max = fields.Integer('最大转速(n/min)') cutting_tool_cooling_type = fields.Char('冷却类型') # 夹头参数 @@ -521,7 +507,7 @@ class ResProductMo(models.Model): cutting_tool_outer_diameter = fields.Float('外径(mm)') cutting_tool_inner_diameter = fields.Float('内径(mm)') cooling_suit_type_ids = fields.Char('适用冷却套型号') - cutting_tool_max_load_capacity = fields.Char('最大负载能力(kg)') + cutting_tool_max_load_capacity = fields.Float('最大负载能力(kg)') cutting_tool_er_size_model = fields.Char('ER尺寸型号') cutting_tool_handle_ids = fields.Many2many( 'sf.cutting_tool.standard.library', @@ -696,7 +682,6 @@ class ResProductMo(models.Model): item.fixture_apply_machine_tool_type_ids = self._get_ids( item.fixture_model_id.apply_machine_tool_type_ids) - 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': @@ -888,95 +873,10 @@ class ResProductMo(models.Model): return base64_data -class ResMrpBomMo(models.Model): - _inherit = 'mrp.bom' - - subcontractor_id = fields.Many2one('res.partner', string='外包商') - - 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: - qty = 1 - if round(embryo.volume * raw_bom_line.materials_type_id.density / 1000000) > 1: - qty = round(embryo.volume * raw_bom_line.materials_type_id.density / 1000000) - 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': qty, - '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 - - class SfMaintenanceEquipmentAndProductTemplate(models.Model): _inherit = 'maintenance.equipment' _description = '设备' + product_template_ids = fields.One2many('maintenance.equipment.tool', 'equipment_id', string='机床刀位') @api.model_create_multi @@ -999,8 +899,7 @@ class SfMaintenanceEquipmentTool(models.Model): _description = '机床刀位' equipment_id = fields.Many2one('maintenance.equipment', string='设备') - product_template_id = fields.Many2one('product.template', string='功能刀具名称', - domain="[('categ_type', '=', '刀具')]") + product_template_id = fields.Many2one('product.template', string='功能刀具名称', domain="[('categ_type', '=', '刀具')]") image_1920 = fields.Binary('图片', related='product_template_id.image_1920') categ_type = fields.Char(string='功能刀具类型') diameter = fields.Char('直径') @@ -1012,3 +911,5 @@ class SfMaintenanceEquipmentTool(models.Model): alarm_value = fields.Char('报警值') used_value = fields.Char('已使用值') code = fields.Char('机床刀位号') + + diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 8066fa41..99a2b69d 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -101,7 +101,6 @@ - @@ -120,6 +119,22 @@ context="{'default_workcenter_id': workcenter_id}" class="btn-danger" attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('name','=','获取CNC加工程序')]}"/> + + + + + + + + + + + + + + + + diff --git a/sf_sale/views/sale_order_view.xml b/sf_sale/views/sale_order_view.xml index 93545342..ba32f029 100644 --- a/sf_sale/views/sale_order_view.xml +++ b/sf_sale/views/sale_order_view.xml @@ -71,5 +71,19 @@ + + product.template.form.inherit.sf + product.template + + + + + + + + + + + \ No newline at end of file diff --git a/sf_tool_management/__manifest__.py b/sf_tool_management/__manifest__.py index 345baa00..d59c6b34 100644 --- a/sf_tool_management/__manifest__.py +++ b/sf_tool_management/__manifest__.py @@ -10,9 +10,9 @@ """, 'category': 'sf', 'website': 'https://www.sf.jikimo.com', - 'depends': ['account', 'sf_base', 'mrp', 'sf_manufacturing', 'sf_maintenance'], + 'depends': ['sf_base', 'sf_manufacturing'], 'data': [ - #'security/group_security.xml', + # 'security/group_security.xml', 'security/ir.model.access.csv', # 'views/tool_base_views.xml', # # 'views/menu_view.xml', @@ -27,11 +27,10 @@ 'web.assets_qweb': [ ], - 'web.assets_backend':[ + 'web.assets_backend': [ 'sf_tool_management/static/src/change.scss' ] - }, 'license': 'LGPL-3', 'installable': True,