diff --git a/sf_base/models/common.py b/sf_base/models/common.py index e781d10d..f116b50f 100644 --- a/sf_base/models/common.py +++ b/sf_base/models/common.py @@ -73,7 +73,7 @@ class MrsMaterialModel(models.Model): price = fields.Float('单价/kg') apply = fields.Many2many('material.apply', string='材料应用') materials_code = fields.Char('材料代号') - hardness = fields.Float("硬度(hrc)") + hardness = fields.Integer("硬度(hrc)") rough_machining = fields.Float("粗加工Vc(m/min)") finish_machining = fields.Float("精加工Vc(m/min)") remark = fields.Text("备注") diff --git a/sf_base/models/tool_other_features.py b/sf_base/models/tool_other_features.py index 9d7c57ea..7bb94711 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,19 +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) - 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( @@ -83,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) @@ -106,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( @@ -182,11 +185,10 @@ class ToolMaterialsBasicParameters(models.Model): 'cutting_tool_type': obj['cutting_tool_type'], 'height': obj['height'], 'width': obj['width'], - 'blade_height': obj['blade_height'], 'total_length': obj['total_length'], - 'blade_width': obj['blade_width'], - 'blade_length': obj['blade_length'], - 'blade_height': obj['blade_height'], + 'knife_head_height': obj['knife_head_height'], + 'knife_head_width': obj['knife_head_width'], + 'knife_head_length': obj['knife_head_length'], 'cutter_arbor_diameter': obj['cutter_arbor_diameter'], 'main_included_angle': obj['main_included_angle'], 'relief_angle': obj['relief_angle'], @@ -297,7 +299,7 @@ class CuttingSpeed(models.Model): slope_milling_angle = fields.Integer('坡铣角度(°)') material_grade = fields.Char('材料牌号') tensile_strength = fields.Char('拉伸强度 (N/mm²)') - hardness = fields.Float('硬度(HRC)') + hardness = fields.Integer('硬度(HRC)') cutting_speed_n1 = fields.Char('径向切宽 ae=100%D1 ap=1*D1 切削速度Vc') cutting_speed_n2 = fields.Char('径向切宽 ae=50%D1 ap=1.5*D1 切削速度Vc') cutting_speed_n3 = fields.Char('径向切宽 ae=25%D1 ap=L1max 切削速度Vc') diff --git a/sf_dlm/static/util/stl2gltf.py b/sf_base/static/util/stl2gltf.py similarity index 100% rename from sf_dlm/static/util/stl2gltf.py rename to sf_base/static/util/stl2gltf.py 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 5f692988..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', 'sale', '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/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index b4fa41c8..1f304950 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -187,6 +187,23 @@ class ResMrpWorkOrder(models.Model): # 拼接工单对象属性值 def json_workorder_str(self, k, production, route): + # 计算预计时长duration_expected + if route.routing_type == '切割': + duration_expected = self.env['mrp.routing.workcenter'].sudo().search([('name', '=', '切割')]).time_cycle + elif route.routing_type == '获取CNC加工程序': + duration_expected = self.env['mrp.routing.workcenter'].sudo().search([('name', '=', '获取CNC加工程序')]).time_cycle + elif route.routing_type == '工件装夹': + duration_expected = self.env['mrp.routing.workcenter'].sudo().search([('name', '=', '工件装夹')]).time_cycle + elif route.routing_type == '前置三元定位检测': + duration_expected = self.env['mrp.routing.workcenter'].sudo().search([('name', '=', '前置三元定位检测')]).time_cycle + elif route.routing_type == 'CNC加工': + duration_expected = self.env['mrp.routing.workcenter'].sudo().search([('name', '=', 'CNC加工')]).time_cycle + elif route.routing_type == '后置三元质量检测': + duration_expected = self.env['mrp.routing.workcenter'].sudo().search([('name', '=', '后置三元质量检测')]).time_cycle + elif route.routing_type == '解除装夹': + duration_expected = self.env['mrp.routing.workcenter'].sudo().search([('name', '=', '解除装夹')]).time_cycle + else: + duration_expected = 60 workorders_values_str = [0, '', { 'product_uom_id': production.product_uom_id.id, 'qty_producing': 0, @@ -201,7 +218,7 @@ class ResMrpWorkOrder(models.Model): production.product_id), 'date_planned_start': False, 'date_planned_finished': False, - 'duration_expected': 60, + 'duration_expected': duration_expected, 'duration': 0, }] diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 6981103d..b6961fda 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from odoo import models, fields, api, _ from odoo.exceptions import ValidationError from odoo.modules import get_resource_path @@ -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): @@ -288,6 +277,10 @@ class ResProductMo(models.Model): self.cutting_tool_blade_length = self.specification_id.blade_length self.cutting_tool_cutter_head_diameter = self.specification_id.cutter_head_diameter self.cutting_tool_interface_diameter = self.specification_id.interface_diameter + else: + self.cutting_tool_knife_head_height = self.specification_id.knife_head_height + self.cutting_tool_knife_head_width = self.specification_id.knife_head_width + self.cutting_tool_knife_head_length = self.specification_id.knife_head_length elif self.cutting_tool_type == '刀柄': self.cutting_tool_total_length = self.specification_id.total_length self.cutting_tool_standard_speed = self.specification_id.standard_rotate_speed @@ -303,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, @@ -321,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: @@ -406,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', @@ -419,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( @@ -441,13 +431,13 @@ 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) cutting_tool_jump_accuracy = fields.Char('径跳精度(mm)') - cutting_tool_working_hardness = fields.Char('加工硬度(hrc)') + cutting_tool_working_hardness = fields.Integer('加工硬度(hrc)') cutting_tool_cutter_bar_ids = fields.Many2many( 'sf.cutting_tool.standard.library', relation='product_cutting_tool_library_cutter_bar_rel', @@ -469,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', @@ -489,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)') @@ -508,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('冷却类型') # 夹头参数 @@ -517,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', @@ -692,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': @@ -874,7 +863,7 @@ class ResProductMo(models.Model): # 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') + util_path = get_resource_path('sf_base', 'static/util') cmd = 'python3 %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file) os.system(cmd) # 转base64 @@ -884,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 @@ -995,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('直径') @@ -1008,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_plan/models/custom_plan.py b/sf_plan/models/custom_plan.py index e80a7783..9c94fa22 100644 --- a/sf_plan/models/custom_plan.py +++ b/sf_plan/models/custom_plan.py @@ -11,6 +11,7 @@ class sf_production_plan(models.Model): _name = 'sf.production.plan' # _inherit = 'mrp.production' _description = 'sf_production_plan' + _order = 'create_date desc' state = fields.Selection([ ('draft', '待排程'), @@ -41,18 +42,12 @@ class sf_production_plan(models.Model): actual_end_time = fields.Datetime(string='实际结束时间') shift = fields.Char(string='班次') - # 序号、坯料编号、坯料名称、材质、数量、长度、宽度、厚度、直径、计划开始时间、计划结束时间、状态(已产出与待产出)、操作、创建人、创建时间、客户名称、订单号、行号、长度、宽度、厚度、直径、交货数量、交货日期 # sequence = fields.Integer(string='序号', required=True, copy=False, readonly=True, index=True, # default=lambda self: self.env['ir.sequence'].sudo().next_by_code('sf.pl.plan')) sequence = fields.Integer(string='序号', copy=False, readonly=True, index=True) current_operation_name = fields.Char(string='当前工序名称', size=64, default='生产计划') - - - - - # state = fields.Selection([ # ('未排程', '未排程'), ('已排程', '已排程')], string='State', copy=False, index=True, readonly=True, # store=True, tracking=True) @@ -179,16 +174,62 @@ class sf_production_plan(models.Model): else: aa = self.env['mrp.production'].sudo().search([('name', '=', self.name)]) workorder_time = 0 - print(aa.workorder_ids) - print(type(aa.workorder_ids)) - if aa.workorder_ids: - for item in aa.workorder_ids: - current_workorder = self.env['mrp.workorder'].sudo().search([('id', '=', item.id)]) - workorder_time += current_workorder.duration_expected - print(workorder_time) + workorder_id_list = self.production_id.workorder_ids.ids + print(workorder_id_list) + print(type(self.production_id.workorder_ids)) + if self.production_id.workorder_ids: + for item in self.production_id.workorder_ids: + if item.name == 'CNC加工': + item.date_planned_start = self.date_planned_start + item.date_planned_finished = item.date_planned_start + timedelta( + minutes=self.env['mrp.routing.workcenter'].sudo().search( + [('name', '=', 'CNC加工')]).time_cycle) + item.duration_expected = self.env['mrp.routing.workcenter'].sudo().search( + [('name', '=', 'CNC加工')]).time_cycle + # print(item.id) + sequence = workorder_id_list.index(item.id) - 1 + # print('sequence', sequence) + # print('total', len(workorder_id_list)) + # 计算CNC加工之前工单的开始结束时间 + for i in range(sequence): + current_workorder_id = (item.id - (i + 1)) + current_workorder_obj = self.env['mrp.workorder'].sudo().search( + [('id', '=', current_workorder_id)]) + old_workorder_obj = self.env['mrp.workorder'].sudo().search( + [('id', '=', (current_workorder_id + 1))]) + work_order = self.env['mrp.workorder'].sudo().search( + [('production_id', '=', self.production_id.id), ('id', '=', current_workorder_id)]) + work_order.date_planned_finished = old_workorder_obj.date_planned_start + work_order.date_planned_start = old_workorder_obj.date_planned_start - timedelta( + minutes=self.env['mrp.routing.workcenter'].sudo().search( + [('name', '=', current_workorder_obj.name)]).time_cycle) + # work_order.duration_expected = self.env['mrp.routing.workcenter'].sudo().search([('name', '=', current_workorder_obj.name)]).time_cycle + # 计算CNC加工之后工单的开始结束时间 + for j in range(len(workorder_id_list) - sequence - 2): + current_workorder_id = (item.id + (j + 1)) + current_workorder_obj = self.env['mrp.workorder'].sudo().search( + [('id', '=', current_workorder_id)]) + old_workorder_obj = self.env['mrp.workorder'].sudo().search( + [('id', '=', (current_workorder_id - 1))]) + work_order = self.env['mrp.workorder'].sudo().search( + [('production_id', '=', self.production_id.id), ('id', '=', current_workorder_id)]) + try: + work_order.date_planned_start = old_workorder_obj.date_planned_finished + print('work_order.data_start', work_order.date_planned_start) + work_order.date_planned_finished = old_workorder_obj.date_planned_finished + timedelta( + minutes=self.env['mrp.routing.workcenter'].sudo().search( + [('name', '=', current_workorder_obj.name)]).time_cycle) + except ValueError as e: + print('时间设置失败,请检查是否为工序分配工作中心,%s' % e) + + current_workorder = self.env['mrp.workorder'].sudo().search([('id', '=', item.id)]) + workorder_time += current_workorder.duration_expected + print('workorder_time', workorder_time) self.date_planned_finished = self.date_planned_start + timedelta(minutes=workorder_time) self.state = 'done' - aa.schedule_state = '已排' + self.production_id.schedule_state = '已排' + # self.production_id.date_planned_start = self.date_planned_start + # self.production_id.date_planned_finished = self.date_planned_finished else: raise ValidationError("未找到工单") # self.date_planned_finished = self.date_planned_start + timedelta(days=3) diff --git a/sf_plan/static/src/xlsx/sf_production_plan.xlsx b/sf_plan/static/src/xlsx/sf_production_plan.xlsx index a82cab58..901d4beb 100644 Binary files a/sf_plan/static/src/xlsx/sf_production_plan.xlsx and b/sf_plan/static/src/xlsx/sf_production_plan.xlsx differ diff --git a/sf_plan_management/views/operations_rename_menu.xml b/sf_plan_management/views/operations_rename_menu.xml index 659df6dd..1af2ba72 100644 --- a/sf_plan_management/views/operations_rename_menu.xml +++ b/sf_plan_management/views/operations_rename_menu.xml @@ -50,39 +50,39 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - 应收应付 - - + + + + - - - + + + diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py index caadb6c2..e9f152a8 100644 --- a/sf_sale/models/quick_easy_order.py +++ b/sf_sale/models/quick_easy_order.py @@ -95,7 +95,7 @@ class QuickEasyOrder(models.Model): write_stl_file(shapes, output_file, 'binary', 0.03, 0.5) # 转化为glb output_glb_file = os.path.join('/tmp', str(model_code) + '.glb') - util_path = get_resource_path('sf_dlm', 'static/util') + util_path = get_resource_path('sf_base', 'static/util') cmd = 'python3 %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file) os.system(cmd) # 转base64 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, diff --git a/sf_tool_management/models/tool_material_search.py b/sf_tool_management/models/tool_material_search.py index 32b4d6a8..aad862b6 100644 --- a/sf_tool_management/models/tool_material_search.py +++ b/sf_tool_management/models/tool_material_search.py @@ -49,7 +49,7 @@ class SfToolMaterialSearch(models.Model): blade_rear_angle = fields.Float('刀片后角(°)') blade_main_included_angle = fields.Float('刀片主偏角(°)') blade_r_angle = fields.Float('刀片R角(°)') - blade_hardness = fields.Char('刀片加工硬度') + blade_hardness = fields.Integer('刀片加工硬度') blade_accuracy = fields.Char('刀片精度等级') blade_coating_material_id = fields.Char('刀片涂层材质') blade_radius = fields.Float('刀片刀尖半径(mm)') @@ -215,7 +215,7 @@ class SfToolMaterialSearch(models.Model): bar_screw = fields.Float('刀杆配备螺丝(mm)') bar_radius = fields.Float('刀杆刀尖圆角半径') bar_accuracy = fields.Char('刀杆精度等级') - bar_hardness = fields.Char('刀杆硬度(°)') + bar_hardness = fields.Integer('刀杆硬度(°)') bar_scope = fields.Char('刀杆适用范围') # 刀盘特有字段 @@ -237,7 +237,7 @@ class SfToolMaterialSearch(models.Model): pad_screw = fields.Float('刀盘配备螺丝(mm)') pad_radius = fields.Float('刀盘刀尖圆角半径') pad_accuracy = fields.Char('刀盘精度等级') - pad_hardness = fields.Char('刀盘硬度(°)') + pad_hardness = fields.Integer('刀盘硬度(°)') pad_scope = fields.Char('刀盘适用范围') # 刀柄特有字段 @@ -265,7 +265,7 @@ class SfToolMaterialSearch(models.Model): ) handle_clamping_range = fields.Float('刀柄夹持范围(mm)') handle_detection_accuracy = fields.Float('刀柄检测精度') - handle_detection_hardness = fields.Char('刀柄检测硬度') + handle_detection_hardness = fields.Integer('刀柄检测硬度') handle_standard_speed = fields.Float('刀柄标准转速') # 夹头特有字段