978 lines
57 KiB
Python
978 lines
57 KiB
Python
# -*- coding: utf-8 -*-
|
|
import logging
|
|
import requests
|
|
import base64
|
|
import hashlib
|
|
import os
|
|
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
|
|
|
|
|
|
class ResProductMo(models.Model):
|
|
_inherit = 'product.template'
|
|
|
|
model_file = fields.Binary('模型文件')
|
|
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))
|
|
model_height = fields.Float('模型高(mm)', digits=(16, 3))
|
|
model_volume = fields.Float('模型体积(m³)')
|
|
model_machining_precision = fields.Selection([
|
|
('0.10', '±0.10mm'),
|
|
('0.05', '±0.05mm'),
|
|
('0.03', '±0.03mm'),
|
|
('0.02', '±0.02mm'),
|
|
('0.01', '±0.01mm')], string='加工精度')
|
|
model_processing_panel = fields.Char('模型加工面板')
|
|
model_remark = fields.Char('模型备注说明')
|
|
length = fields.Float('长(mm)', digits=(16, 3))
|
|
width = fields.Float('宽(mm)', digits=(16, 3))
|
|
height = fields.Float('高(mm)', digits=(16, 3))
|
|
# 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='材料')
|
|
materials_type_id = fields.Many2one('sf.materials.model', string='材料型号',
|
|
domain="[('materials_id', '=', materials_id)]")
|
|
server_product_process_parameters_id = fields.Many2one('sf.production.process.parameter',
|
|
string='表面工艺参数(服务产品)')
|
|
model_process_parameters_ids = fields.Many2many('sf.production.process.parameter', 'process_parameter_rel',
|
|
string='表面工艺参数')
|
|
|
|
cutting_tool_material_id = fields.Many2one('sf.cutting.tool.material', string='刀具物料')
|
|
cutting_tool_type = fields.Char(string="刀具物料类型", related='cutting_tool_material_id.name', store=True)
|
|
|
|
cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='型号名称')
|
|
specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='物料号')
|
|
|
|
cutting_tool_type_id = fields.Many2one('sf.cutting.tool.type', string='类型',
|
|
domain="[('cutting_tool_material_id.name', '=', cutting_tool_type)]")
|
|
|
|
brand_id = fields.Many2one('sf.machine.brand', '品牌')
|
|
|
|
tool_length = fields.Float('长度(mm)')
|
|
tool_width = fields.Float('宽度(mm)')
|
|
tool_height = fields.Float('高度(mm)')
|
|
tool_thickness = fields.Float('厚度(mm)')
|
|
tool_weight = fields.Float('重量(kg)')
|
|
tool_hardness = fields.Integer('硬度(hrc)')
|
|
coating_material = fields.Char('涂层材质')
|
|
# 整体式刀具特有字段
|
|
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.Float('刃部长度(mm)')
|
|
cutting_tool_blade_number = fields.Selection(
|
|
[('0', '0'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8')],
|
|
string='刃数(个)', default='0')
|
|
# 整体式刀具新增字段
|
|
cutting_tool_neck_length = fields.Float('颈部长度(mm)', digits=(6, 1))
|
|
cutting_tool_neck_diameter = fields.Float('颈部直径(mm)', digits=(6, 1))
|
|
cutting_tool_shank_diameter = fields.Float('柄部直径(mm)', digits=(6, 1))
|
|
cutting_tool_blade_tip_diameter = fields.Float('刀尖直径(mm)', digits=(6, 1))
|
|
cutting_tool_blade_tip_taper = fields.Integer('刀尖锥度(°)')
|
|
cutting_tool_blade_helix_angle = fields.Integer('刃部螺旋角(°)')
|
|
cutting_tool_blade_type = fields.Char('刃部类型')
|
|
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.Many2one('maintenance.equipment.image',
|
|
'适配刀片形状', domain=[('type', '=', '刀片形状')])
|
|
suitable_machining_method_ids = fields.Many2many('maintenance.equipment.image',
|
|
'rel_machining_product_template', '适合加工方式',
|
|
domain=[('type', '=', '加工能力')])
|
|
blade_tip_characteristics_id = fields.Many2one('maintenance.equipment.image', '刀尖特征',
|
|
domain=[('type', '=', '刀尖特征')])
|
|
handle_type_id = fields.Many2one('maintenance.equipment.image', '柄部类型', domain=[('type', '=', '柄部类型')])
|
|
cutting_direction_ids = fields.Many2many('maintenance.equipment.image', 'rel_cutting_product_template',
|
|
'走刀方向', domain=[('type', '=', '走刀方向')])
|
|
suitable_coolant_ids = fields.Many2many('maintenance.equipment.image', 'rel_coolants_product_template',
|
|
'适合冷却方式', domain=[('type', '=', '冷却方式')])
|
|
compaction_way_id = fields.Many2one('maintenance.equipment.image',
|
|
'压紧方式', domain=[('type', '=', '压紧方式')])
|
|
|
|
name = fields.Char('产品名称', compute='_compute_tool_name', store=True, required=False)
|
|
|
|
@api.depends('cutting_tool_model_id', 'specification_id')
|
|
def _compute_tool_name(self):
|
|
for item in self:
|
|
if item.cutting_tool_model_id and item.specification_id:
|
|
name = '%s%s' % (item.cutting_tool_model_id.name, item.specification_id.name)
|
|
item.name = name
|
|
|
|
@api.onchange('cutting_tool_model_id')
|
|
def _onchange_cutting_tool_model_id(self):
|
|
for item in self:
|
|
if item:
|
|
item.specification_id = False
|
|
item.cutting_tool_chuck_id = item.cutting_tool_model_id.chuck_id
|
|
|
|
@api.onchange('cutting_tool_material_id')
|
|
def _onchange_cutting_tool_material_id(self):
|
|
for item in self:
|
|
if item.cutting_tool_material_id.id != item.cutting_tool_model_id.cutting_tool_material_id.id:
|
|
item.cutting_tool_model_id = False
|
|
item.specification_id = False
|
|
item.cutting_tool_type_id = False
|
|
item.brand_id = False
|
|
item.tool_hardness = False
|
|
item.cutting_tool_run_out_accuracy_max = False
|
|
item.cutting_tool_run_out_accuracy_min = False
|
|
item.materials_type_id = False
|
|
item.cutting_tool_blade_type = False
|
|
item.cutting_tool_total_length = False
|
|
item.cutting_tool_clamping_way = False
|
|
item.cutting_tool_blade_diameter = False
|
|
item.cutting_tool_shank_length = False
|
|
item.cutting_tool_blade_length = False
|
|
item.cutting_tool_blade_number = False
|
|
item.cutting_tool_neck_length = False
|
|
item.cutting_tool_neck_diameter = False
|
|
item.cutting_tool_shank_diameter = False
|
|
item.cutting_tool_blade_tip_diameter = False
|
|
item.cutting_tool_blade_tip_taper = False
|
|
item.cutting_tool_blade_helix_angle = False
|
|
item.cutting_tool_blade_type = False
|
|
item.cutting_tool_pitch = False
|
|
item.cutting_tool_blade_width = False
|
|
item.cutting_tool_blade_depth = False
|
|
item.cutting_tool_cut_depth = False
|
|
item.cutting_tool_coarse_medium_fine = False
|
|
item.cutting_tool_run_out_accuracy_max = False
|
|
item.cutting_tool_run_out_accuracy_min = False
|
|
item.cutting_tool_blade_tip_working_size = False
|
|
item.fit_blade_shape_id = False
|
|
item.suitable_machining_method_ids = False
|
|
item.blade_tip_characteristics_id = False
|
|
item.handle_type_id = False
|
|
item.cutting_direction_ids = False
|
|
item.suitable_coolant_ids = False
|
|
item.compaction_way_id = False
|
|
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 name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
|
|
# # if self._context.get('is_sale_order_line'):
|
|
# # domain = [('sale_ok', '=', True), ('categ_type', '=', '成品')]
|
|
# # return self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)
|
|
# return super(product.template, self)._name_search(name, args, operator, limit, name_get_uid)
|
|
|
|
@api.onchange('specification_id')
|
|
def _onchange_specification(self):
|
|
if self.specification_id:
|
|
self.cutting_speed_ids = False
|
|
self.feed_per_tooth_ids = False
|
|
self.cutting_tool_type_id = self.cutting_tool_model_id.cutting_tool_type_id.id
|
|
self.brand_id = self.cutting_tool_model_id.brand_id.id
|
|
self.tool_hardness = self.cutting_tool_model_id.tool_hardness
|
|
self.cutting_tool_blade_type = self.cutting_tool_model_id.blade_type
|
|
self.cutting_tool_coarse_medium_fine = self.cutting_tool_model_id.integral_coarse_medium_fine
|
|
self.materials_type_id = self.cutting_tool_model_id.material_model_id.id
|
|
self.coating_material = self.cutting_tool_model_id.coating_material
|
|
if self.cutting_tool_type == '整体式刀具':
|
|
self.cutting_tool_total_length = self.specification_id.total_length
|
|
self.cutting_tool_run_out_accuracy_max = self.cutting_tool_model_id.integral_run_out_accuracy_max
|
|
self.cutting_tool_run_out_accuracy_min = self.cutting_tool_model_id.integral_run_out_accuracy_min
|
|
self.cutting_tool_blade_diameter = self.specification_id.blade_diameter
|
|
self.cutting_tool_blade_length = self.specification_id.blade_length
|
|
self.cutting_tool_blade_number = self.specification_id.blade_number
|
|
self.cutting_tool_blade_type = self.cutting_tool_model_id.blade_type
|
|
self.cutting_tool_shank_diameter = self.specification_id.handle_diameter
|
|
self.cutting_tool_shank_length = self.specification_id.handle_length
|
|
self.cutting_tool_neck_length = self.specification_id.neck_length
|
|
self.cutting_tool_neck_diameter = self.specification_id.neck_diameter
|
|
self.cutting_tool_blade_tip_diameter = self.specification_id.blade_tip_diameter
|
|
self.cutting_tool_blade_tip_taper = self.specification_id.blade_tip_taper
|
|
self.cutting_tool_blade_helix_angle = self.specification_id.blade_helix_angle
|
|
self.cutting_tool_blade_tip_working_size = self.specification_id.blade_tip_working_size
|
|
self.cutting_tool_pitch = self.specification_id.pitch
|
|
self.cutting_tool_blade_width = self.specification_id.blade_width
|
|
self.cutting_tool_blade_depth = self.specification_id.blade_depth
|
|
self.cutting_tool_cut_depth_max = self.specification_id.cut_depth_max
|
|
self.cutting_speed_ids = self.cutting_tool_model_id.cutting_speed_ids
|
|
self.feed_per_tooth_ids = self.cutting_tool_model_id.feed_per_tooth_ids.filtered(
|
|
lambda r: int(r.blade_diameter) == int(self.specification_id.blade_diameter))
|
|
elif self.cutting_tool_type == '夹头':
|
|
self.cutting_tool_clamping_diameter_min = self.specification_id.min_clamping_diameter
|
|
self.cutting_tool_clamping_diameter_max = self.specification_id.max_clamping_diameter
|
|
self.cutting_tool_taper = self.specification_id.taper
|
|
self.cutting_tool_top_diameter = self.specification_id.top_diameter
|
|
self.cutting_tool_outer_diameter = self.specification_id.outer_diameter
|
|
self.cutting_tool_inner_diameter = self.specification_id.inner_diameter
|
|
self.tool_weight = self.specification_id.weight
|
|
self.cutting_tool_jump_accuracy = self.specification_id.run_out_accuracy
|
|
self.cutting_tool_max_load_capacity = self.specification_id.max_load_capacity
|
|
self.cutting_tool_er_size_model = self.specification_id.er_size_model
|
|
self.cutting_tool_handle_id = self.cutting_tool_model_id.handle_id.id
|
|
self.cooling_suit_type_ids = self.specification_id.cooling_jacket
|
|
elif self.cutting_tool_type == '刀片':
|
|
self.cutting_tool_total_length = self.specification_id.total_length
|
|
self.tool_length = self.specification_id.length
|
|
self.tool_thickness = self.specification_id.thickness
|
|
self.tool_width = self.specification_id.width
|
|
self.cutting_tool_cut_blade_length = self.specification_id.cutting_blade_length
|
|
self.cutting_tool_blade_tip_circular_arc_radius = self.specification_id.blade_tip_circular_arc_radius
|
|
self.cutting_tool_blade_tip_height_tolerance = self.specification_id.blade_tip_height_tolerance
|
|
self.cutting_tool_inscribed_circle_diameter = self.specification_id.inscribed_circle_diameter
|
|
self.cutting_tool_inscribed_circle_tolerance = self.specification_id.inscribed_circle_tolerance
|
|
self.cutting_tool_install_aperture_diameter = self.specification_id.install_aperture_diameter
|
|
self.cutting_tool_chip_breaker_groove = self.specification_id.chip_breaker_groove
|
|
self.cutting_tool_chip_breaker_type_code = self.specification_id.chip_breaker_type_code
|
|
self.cutting_tool_blade_blade_number = self.specification_id.blade_blade_number
|
|
self.cutting_tool_blade_width = self.specification_id.blade_width
|
|
self.cutting_tool_rear_angle = self.specification_id.relief_angle
|
|
self.cutting_tool_main_included_angle = self.specification_id.main_included_angle
|
|
self.cutting_tool_top_angle = self.specification_id.top_angle
|
|
self.cutting_tool_pitch = self.specification_id.pitch
|
|
self.cutting_tool_bladed_teeth_model = self.specification_id.blade_teeth_model
|
|
self.cutting_tool_thickness_tolerance = self.specification_id.thickness_tolerance
|
|
self.cutting_tool_thread_model = self.specification_id.thread_model
|
|
self.cutting_tool_thread_num = self.specification_id.thread_num
|
|
self.cutting_tool_cutter_bar_ids = self.cutting_tool_model_id.cutter_bar_ids.ids
|
|
self.cutting_tool_cutter_pad_ids = self.cutting_tool_model_id.cutter_pad_ids.ids
|
|
self.cutting_speed_ids = self.cutting_tool_model_id.cutting_speed_ids
|
|
self.feed_per_tooth_ids = self.cutting_tool_model_id.feed_per_tooth_ids
|
|
elif self.cutting_tool_type in ('刀盘', '刀杆'):
|
|
self.cutting_tool_blade_diameter = self.specification_id.blade_diameter
|
|
self.cutting_tool_total_length = self.specification_id.total_length
|
|
self.tool_length = self.specification_id.length
|
|
self.tool_thickness = self.specification_id.thickness
|
|
self.tool_width = self.specification_id.width
|
|
self.cutting_tool_cut_blade_length = self.specification_id.cutting_blade_length
|
|
self.cutting_tool_blade_tip_circular_arc_radius = self.specification_id.blade_tip_circular_arc_radius
|
|
self.cutting_tool_blade_tip_height_tolerance = self.specification_id.blade_tip_height_tolerance
|
|
self.cutting_tool_inscribed_circle_diameter = self.specification_id.inscribed_circle_diameter
|
|
self.cutting_tool_inscribed_circle_tolerance = self.specification_id.inscribed_circle_tolerance
|
|
self.cutting_tool_install_aperture_diameter = self.specification_id.install_aperture_diameter
|
|
self.cutting_tool_chip_breaker_groove = self.specification_id.chip_breaker_groove
|
|
self.cutting_tool_chip_breaker_type_code = self.specification_id.chip_breaker_type_code
|
|
self.cutting_tool_blade_blade_number = self.specification_id.blade_blade_number
|
|
self.cutting_tool_blade_width = self.specification_id.blade_width
|
|
self.cutting_tool_rear_angle = self.specification_id.relief_angle
|
|
self.cutting_tool_main_included_angle = self.specification_id.main_included_angle
|
|
self.cutting_tool_top_angle = self.specification_id.top_angle
|
|
self.cutting_tool_screw = self.specification_id.screw
|
|
self.cutting_tool_wrench = self.specification_id.spanner
|
|
self.cutting_tool_blade_id = self.specification_id.blade_id.id
|
|
self.cutting_tool_is_cooling_hole = self.specification_id.is_cooling_hole
|
|
self.cutting_tool_locating_slot_code = self.specification_id.locating_slot_code
|
|
self.cutting_tool_install_blade_tip_num = self.specification_id.install_blade_tip_num
|
|
self.cutting_tool_installing_structure = self.specification_id.installing_structure
|
|
self.cutting_tool_cut_depth_max = self.specification_id.cut_depth_max
|
|
if self.cutting_tool_type == '刀盘':
|
|
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_cutter_arbor_diameter = self.specification_id.cutter_arbor_diameter
|
|
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
|
|
self.cutting_tool_tool_shim = self.specification_id.tool_shim
|
|
self.cutting_tool_cotter_pin = self.specification_id.cotter_pin
|
|
self.cutting_tool_pressing_plate = self.specification_id.pressing_plate
|
|
self.cutting_tool_min_machining_aperture = self.specification_id.min_machining_aperture
|
|
self.cutting_tool_rear_angle = self.specification_id.relief_angle
|
|
elif self.cutting_tool_type == '刀柄':
|
|
self.cutting_tool_total_length = self.specification_id.total_length
|
|
self.cutting_tool_shank_diameter = self.specification_id.shank_diameter
|
|
self.cutting_tool_shank_length = self.specification_id.shank_length
|
|
self.cutting_tool_speed_max = self.specification_id.max_rotate_speed
|
|
self.cutting_tool_change_time = self.specification_id.tool_changing_time
|
|
self.cutting_tool_total_length = self.specification_id.total_length
|
|
self.cutting_tool_clamping_diameter_max = self.specification_id.max_clamping_diameter
|
|
self.cutting_tool_clamping_diameter_min = self.specification_id.min_clamping_diameter
|
|
self.cutting_tool_flange_length = self.specification_id.flange_shank_length
|
|
self.cutting_tool_flange_diameter = self.specification_id.flange_diameter
|
|
self.cutting_tool_fit_chuck_size = self.specification_id.fit_chuck_size
|
|
self.cutting_tool_dynamic_balance_class = self.specification_id.dynamic_balance_class
|
|
self.cutting_tool_is_high_speed_cutting = self.specification_id.is_quick_cutting
|
|
self.cutting_tool_is_safety_lock = self.specification_id.is_safe_lock
|
|
self.cutting_tool_fit_nut_model = self.specification_id.nut
|
|
self.cutting_tool_wrench = self.specification_id.spanner
|
|
self.cutting_tool_jump_accuracy = self.specification_id.diameter_slip_accuracy
|
|
self.cutting_tool_taper_shank_model = self.specification_id.taper_shank_model
|
|
self.cutting_tool_cooling_type = self.specification_id.cooling_model
|
|
self.cutting_tool_clamping_way = self.specification_id.clamping_mode
|
|
self.suitable_machining_method_ids = [(6, 0, [])] 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 = self.cutting_tool_model_id.blade_tip_characteristics_id.id
|
|
|
|
self.handle_type_id = self.cutting_tool_model_id.handle_type_id.id
|
|
|
|
self.cutting_direction_ids = [(6, 0,
|
|
[])] if not self.cutting_tool_model_id.cutting_direction_ids else [
|
|
(6, 0, self.cutting_tool_model_id.cutting_direction_ids.ids)]
|
|
|
|
self.suitable_coolant_ids = [(6, 0,
|
|
[])] if not self.cutting_tool_model_id.suitable_coolant_ids else [
|
|
(6, 0, self.cutting_tool_model_id.suitable_coolant_ids.ids)]
|
|
self.compaction_way_id = self.cutting_tool_model_id.compaction_way_id.id
|
|
self.fit_blade_shape_id = self.cutting_tool_model_id.fit_blade_shape_id.id
|
|
self.image_1920 = self.cutting_tool_model_id.image
|
|
else:
|
|
self.cutting_tool_type_id = False
|
|
self.brand_id = False
|
|
self.tool_hardness = False
|
|
self.cutting_tool_run_out_accuracy_max = False
|
|
self.cutting_tool_run_out_accuracy_min = False
|
|
self.materials_type_id = False
|
|
self.cutting_tool_blade_type = False
|
|
self.cutting_tool_total_length = False
|
|
self.cutting_tool_clamping_way = False
|
|
self.cutting_tool_blade_diameter = False
|
|
self.cutting_tool_shank_length = False
|
|
self.cutting_tool_blade_length = False
|
|
self.cutting_tool_blade_number = False
|
|
self.cutting_tool_neck_length = False
|
|
self.cutting_tool_neck_diameter = False
|
|
self.cutting_tool_shank_diameter = False
|
|
self.cutting_tool_blade_tip_diameter = False
|
|
self.cutting_tool_blade_tip_taper = False
|
|
self.cutting_tool_blade_helix_angle = False
|
|
self.cutting_tool_blade_type = False
|
|
self.cutting_tool_pitch = False
|
|
self.cutting_tool_blade_width = False
|
|
self.cutting_tool_blade_depth = False
|
|
self.cutting_tool_cut_depth = False
|
|
self.cutting_tool_coarse_medium_fine = False
|
|
self.cutting_tool_run_out_accuracy_max = False
|
|
self.cutting_tool_run_out_accuracy_min = False
|
|
self.cutting_tool_blade_tip_working_size = False
|
|
self.fit_blade_shape_id = False
|
|
self.suitable_machining_method_ids = False
|
|
self.blade_tip_characteristics_id = False
|
|
self.handle_type_id = False
|
|
self.cutting_direction_ids = False
|
|
self.suitable_coolant_ids = False
|
|
self.compaction_way_id = False
|
|
self.cutting_speed_ids = False
|
|
self.feed_per_tooth_ids = False
|
|
|
|
# @api.constrains('fit_blade_shape_id', 'suitable_machining_method_ids', 'blade_tip_characteristics_id',
|
|
# 'handle_type_id', 'cutting_direction_ids', 'suitable_coolant_ids', 'compaction_way_id')
|
|
# def _check_cutting_tool_ability(self):
|
|
# if self.cutting_tool_type in ['整体式刀具', '刀片', '刀杆', '刀盘']:
|
|
# if self.cutting_tool_type in ['刀片', '刀杆', '刀盘']:
|
|
# if not self.fit_blade_shape_id:
|
|
# raise ValidationError("请选择适配刀片形状")
|
|
# if self.cutting_tool_type in ['刀杆', '刀盘']:
|
|
# if not self.compaction_way_id:
|
|
# raise ValidationError("请选择压紧方式")
|
|
# if self.cutting_tool_type == '刀片':
|
|
# if not self.suitable_coolant_ids:
|
|
# raise ValidationError("请选择适合冷却方式")
|
|
# elif self.cutting_tool_type == '整体式刀具':
|
|
# if not self.handle_type_id:
|
|
# raise ValidationError("请选择柄部类型")
|
|
# if not self.suitable_coolant_ids:
|
|
# raise ValidationError("请选择适合冷却方式")
|
|
# if not self.suitable_machining_method_ids:
|
|
# raise ValidationError("请选择适合加工方式")
|
|
# if not self.blade_tip_characteristics_id:
|
|
# raise ValidationError("请选择刀尖特征")
|
|
# if not self.cutting_direction_ids:
|
|
# raise ValidationError("请选择走刀方向")
|
|
|
|
cutting_speed_ids = fields.One2many('sf.cutting.speed', 'product_template_id', string='切削速度Vc')
|
|
feed_per_tooth_ids = fields.One2many('sf.feed.per.tooth', 'product_template_id', string='每齿走刀量fz')
|
|
cutting_tool_diameter = fields.Float('刀具直径(mm)')
|
|
cutting_tool_rear_angle = fields.Integer('后角(°)')
|
|
cutting_tool_main_included_angle = fields.Integer('主偏角(°)')
|
|
# 适用夹头型号可以多选
|
|
cutting_tool_chuck_id = fields.Many2one(
|
|
'sf.cutting_tool.standard.library',
|
|
domain="[('cutting_tool_type', '=', '夹头')]",
|
|
string='适用夹头型号')
|
|
# 刀片参数
|
|
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.Float('内接圆直径(mm)')
|
|
cutting_tool_install_aperture_diameter = fields.Float('安装孔直径(mm)')
|
|
cutting_tool_chip_breaker_groove = fields.Selection([('无', '无'), ('单面', '单面'), ('双面', '双面')],
|
|
string='有无断屑槽')
|
|
cutting_tool_chip_breaker_type_code = fields.Char('断屑槽型代号')
|
|
cutting_tool_bladed_teeth_model = fields.Selection(
|
|
[('无', '无'), ('V牙型', 'V牙型'), ('米制全牙型', '米制全牙型'), ('美制全牙型', '美制全牙型'),
|
|
('惠氏全牙型', '惠氏全牙型'), ('BSPT全牙型', 'BSPT全牙型'), ('NPT全牙型', 'NPT全牙型'),
|
|
('UNJ全牙型', 'UNJ全牙型'), ('DIN405圆牙型', 'DIN405圆牙型'), ('ACME梯形', 'ACME梯形'),
|
|
('石油管螺纹刀片', '石油管螺纹刀片'), ('矮牙ACME梯形', '矮牙ACME梯形'),
|
|
('Trapeze30° 103', 'Trapeze30° 103')], string='刀片牙型', default='无')
|
|
cutting_tool_blade_blade_number = fields.Selection(
|
|
[('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'),
|
|
('7', '7'), ('8', '8'), ('9', '9'), ('10', '10')],
|
|
string='刀片的刃数(个)')
|
|
|
|
cutting_tool_thread_model = fields.Selection([('无', '无'), ('外螺纹', '外螺纹'), ('内螺纹', '内螺纹')],
|
|
string='螺纹类型')
|
|
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.Integer('加工硬度(hrc)')
|
|
cutting_tool_cutter_bar_ids = fields.Many2many(
|
|
'sf.cutting_tool.standard.library',
|
|
relation='product_cutting_tool_library_cutter_bar_rel',
|
|
column1='model_id_1',
|
|
column2='model_id_2',
|
|
domain="[('cutting_tool_type', '=', '刀杆')]",
|
|
string='适用刀杆型号'
|
|
)
|
|
cutting_tool_cutter_pad_ids = fields.Many2many(
|
|
'sf.cutting_tool.standard.library',
|
|
relation='product_cutting_tool_library_cutter_pad_rel',
|
|
column1='model_id_1',
|
|
column2='model_id_2',
|
|
domain="[('cutting_tool_type', '=', '刀盘')]",
|
|
string='适用刀盘型号' # 使用空列表作为默认值
|
|
)
|
|
# 刀杆/参数
|
|
cutting_tool_knife_head_height = fields.Float('刀头高度(mm)')
|
|
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.Float('刀杆直径(mm)')
|
|
cutting_tool_min_machining_aperture = fields.Integer('最小加工孔径(mm)')
|
|
cutting_tool_install_blade_tip_num = fields.Integer('可装刀片数/齿数(个)')
|
|
cutting_tool_installing_structure = fields.Char('安装结构', size=20)
|
|
cutting_tool_blade_id = fields.Many2one(
|
|
'sf.cutting_tool.standard.library',
|
|
domain="[('cutting_tool_type', '=', '刀片')]",
|
|
string='适用刀片型号' # 使用空列表作为默认值
|
|
)
|
|
cutting_tool_tool_shim = fields.Char('适配刀垫型号', size=50)
|
|
cutting_tool_cotter_pin = fields.Char('适配销钉型号', size=50)
|
|
cutting_tool_pressing_plate = fields.Char('适配压板型号', size=50)
|
|
cutting_tool_screw = fields.Char('适配螺钉型号', size=50)
|
|
cutting_tool_wrench = fields.Char('适配扳手型号')
|
|
cutting_tool_is_cooling_hole = fields.Boolean('有无冷却孔', default=False)
|
|
cutting_tool_locating_slot_code = fields.Char('定位槽代号', size=20)
|
|
# 刀盘参数
|
|
cutting_tool_cutter_head_diameter = fields.Float('刀盘直径(mm)')
|
|
cutting_tool_interface_diameter = fields.Float('接口直径(mm)')
|
|
|
|
# 刀柄参数
|
|
cutting_tool_clamping_diameter_max = fields.Float('最大夹持直径')
|
|
cutting_tool_clamping_diameter_min = fields.Float('最小夹持直径')
|
|
cutting_tool_flange_length = fields.Float('法兰柄长(mm)')
|
|
cutting_tool_flange_diameter = fields.Float('法兰直径(mm)')
|
|
cutting_tool_is_safety_lock = fields.Boolean('有无安全锁', default=False)
|
|
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_fit_chuck_size = fields.Char('适配夹头尺寸')
|
|
cutting_tool_taper_shank_model = fields.Char('锥柄型号')
|
|
cutting_tool_standard_speed = fields.Integer('标准转速(n/min)')
|
|
cutting_tool_speed_max = fields.Integer('最大转速(n/min)')
|
|
cutting_tool_cooling_type = fields.Char('冷却类型')
|
|
cutting_tool_dynamic_balance_class = fields.Char('动平衡等级')
|
|
cutting_tool_fit_nut_model = fields.Char('适用锁紧螺母型号')
|
|
|
|
# 夹头参数
|
|
cutting_tool_taper = fields.Integer('锥度(°)')
|
|
cutting_tool_top_diameter = fields.Float('顶部直径')
|
|
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.Float('最大负载能力(kg)')
|
|
cutting_tool_er_size_model = fields.Char('尺寸型号')
|
|
# cutting_tool_handle_ids = fields.Many2many(
|
|
# 'sf.cutting_tool.standard.library',
|
|
# relation='product_cutting_tool_library_chuck_handle_rel',
|
|
# column1='model_id_1',
|
|
# column2='model_id_2',
|
|
# domain="[('cutting_tool_type', '=', '刀柄')]",
|
|
# string='适用刀柄型号'
|
|
# )
|
|
|
|
cutting_tool_handle_id = fields.Many2one(
|
|
'sf.cutting_tool.standard.library',
|
|
domain="[('cutting_tool_type', '=', '刀柄')]",
|
|
string='适用刀柄型号'
|
|
)
|
|
|
|
# 注册状态
|
|
register_state = fields.Selection([('未注册', '未注册'), ('已注册', '已注册'), ('注册失败', '注册失败')],
|
|
string='注册状态', default='未注册')
|
|
industry_code = fields.Char('行业编码', readonly=True)
|
|
|
|
# bfm下单
|
|
manual_quotation = fields.Boolean('人工编程', default=False, readonly=True)
|
|
part_number = fields.Char(string='零件图号', readonly=True)
|
|
|
|
@api.constrains('tool_length')
|
|
def _check_tool_length_size(self):
|
|
if self.tool_length > 1000000:
|
|
raise ValidationError("长度不能超过1000000")
|
|
|
|
@api.constrains('tool_width')
|
|
def _check_tool_width_size(self):
|
|
if self.tool_width > 1000000:
|
|
raise ValidationError("宽度不能超过1000000")
|
|
|
|
@api.constrains('tool_height')
|
|
def _check_tool_height_size(self):
|
|
if self.tool_height > 1000000:
|
|
raise ValidationError("高度不能超过1000000")
|
|
|
|
@api.constrains('tool_thickness')
|
|
def _check_tool_thickness_size(self):
|
|
if self.tool_thickness > 1000000:
|
|
raise ValidationError("厚度不能超过1000000")
|
|
|
|
def _json_apply_machine_tool_type_item_code(self, item):
|
|
code_arr = []
|
|
for i in item.product_id.fixture_apply_machine_tool_type_ids:
|
|
code_arr.append(i.code)
|
|
return code_arr
|
|
|
|
def _json_cutter_bar_item_code(self, item):
|
|
code_arr = []
|
|
for i in item.product_id.cutting_tool_cutter_bar_ids:
|
|
code_arr.append(i.code)
|
|
return code_arr
|
|
|
|
def _json_cutter_pad_item_code(self, item):
|
|
code_arr = []
|
|
for i in item.product_id.cutting_tool_cutter_pad_ids:
|
|
code_arr.append(i.code)
|
|
return code_arr
|
|
|
|
def _get_ids(self, param):
|
|
type_ids = []
|
|
if not param:
|
|
return []
|
|
for item in param:
|
|
type_ids.append(item.id)
|
|
return [(6, 0, type_ids)]
|
|
|
|
@api.onchange('categ_id')
|
|
def _onchange_categ_id(self):
|
|
if self.categ_type in ('刀具', '夹具'):
|
|
self.invoice_policy = 'delivery'
|
|
self.detailed_type = 'product'
|
|
self.sale_ok = False
|
|
|
|
def _get_volume_uom_id_from_ir_config_parameter(self):
|
|
product_length_in_feet_param = self.env['ir.config_parameter'].sudo().get_param('product.volume_in_cubic_feet')
|
|
if product_length_in_feet_param == '1':
|
|
return self.env.ref('uom.product_uom_cubic_foot')
|
|
else:
|
|
return self.env.ref('sf_dlm.product_uom_cubic_millimeter')
|
|
|
|
# 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品
|
|
def product_create(self, product_id, item, order_id, order_number, i):
|
|
copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy()
|
|
copy_product_id.product_tmpl_id.active = True
|
|
model_type = self.env['sf.model.type'].search([], limit=1)
|
|
attachment = self.attachment_create(item['model_name'], item['model_data'])
|
|
vals = {
|
|
'name': '%s-%s-%s' % ('P', order_id.name, i),
|
|
'model_long': item['model_long'] + model_type.embryo_tolerance,
|
|
'model_width': item['model_width'] + model_type.embryo_tolerance,
|
|
'model_height': item['model_height'] + model_type.embryo_tolerance,
|
|
'model_volume': (item['model_long'] + model_type.embryo_tolerance) * (
|
|
item['model_width'] + model_type.embryo_tolerance) * (
|
|
item['model_height'] + model_type.embryo_tolerance),
|
|
'product_model_type_id': model_type.id,
|
|
# 'model_processing_panel': 'R',
|
|
'model_machining_precision': item['model_machining_precision'],
|
|
'model_code': item['barcode'],
|
|
'length': item['model_long'],
|
|
'width': item['model_width'],
|
|
'height': item['model_height'],
|
|
'volume': item['model_long'] * item['model_width'] * item['model_height'],
|
|
'model_file': '' if not item['model_file'] else base64.b64decode(item['model_file']),
|
|
'model_name': attachment.name,
|
|
'upload_model_file': [(6, 0, [attachment.id])],
|
|
'list_price': item['price'],
|
|
'materials_id': self.env['sf.production.materials'].search(
|
|
[('materials_no', '=', item['texture_code'])]).id,
|
|
'materials_type_id': self.env['sf.materials.model'].search(
|
|
[('materials_no', '=', item['texture_type_code'])]).id,
|
|
'model_process_parameters_ids': [(6, 0, [])] if not item.get(
|
|
'process_parameters_code') else self.get_process_parameters_id(item['process_parameters_code']),
|
|
'model_remark': item['remark'],
|
|
'single_manufacturing': True,
|
|
'default_code': '%s-%s' % (order_number, i),
|
|
'manual_quotation': item['manual_quotation'] or False,
|
|
'part_number': item.get('part_number') or '',
|
|
'active': True,
|
|
}
|
|
copy_product_id.sudo().write(vals)
|
|
product_id.product_tmpl_id.active = False
|
|
return copy_product_id
|
|
|
|
def _get_ids(self, param):
|
|
type_ids = []
|
|
if not param:
|
|
return []
|
|
for item in param:
|
|
type_ids.append(item.id)
|
|
return [(6, 0, type_ids)]
|
|
|
|
def get_process_parameters_id(self, process_parameters_code):
|
|
process_parameters_ids = []
|
|
for item in process_parameters_code:
|
|
process_parameters = self.env['sf.production.process.parameter'].search([('code', '=', item)])
|
|
process_parameters_ids.append(process_parameters.id)
|
|
return [(6, 0, process_parameters_ids)]
|
|
|
|
def attachment_create(self, name, data):
|
|
attachment = self.env['ir.attachment'].create({
|
|
'datas': base64.b64decode(data),
|
|
'type': 'binary',
|
|
'public': True,
|
|
'description': '模型文件',
|
|
'name': name
|
|
})
|
|
return attachment
|
|
|
|
# 创建坯料
|
|
def no_bom_product_create(self, product_id, item, order_id, route_type, i, finish_product):
|
|
no_bom_copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy()
|
|
# if finish_product.model_process_parameters_ids:
|
|
# surface_technology = self.env['stock.route'].sudo().search([('name', '=', '表面工艺外协')])
|
|
# if surface_technology:
|
|
# no_bom_copy_product_id.route_ids |= surface_technology
|
|
no_bom_copy_product_id.product_tmpl_id.active = True
|
|
materials_id = self.env['sf.production.materials'].search(
|
|
[('materials_no', '=', item['texture_code'])])
|
|
materials_type_id = self.env['sf.materials.model'].search(
|
|
[('materials_no', '=', item['texture_type_code'])])
|
|
model_type = self.env['sf.model.type'].search([], limit=1)
|
|
supplier = self.env['mrp.bom'].get_supplier(materials_type_id)
|
|
logging.info('no_bom_copy_product_supplier-vals:%s' % supplier)
|
|
vals = {
|
|
'name': '%s-%s-%s [%s %s-%s * %s * %s]' % ('R',
|
|
order_id.name, i, materials_id.name, materials_type_id.name,
|
|
item['model_long'] + model_type.embryo_tolerance,
|
|
item['model_width'] + model_type.embryo_tolerance,
|
|
item['model_height'] + model_type.embryo_tolerance),
|
|
'length': item['model_long'] + model_type.embryo_tolerance,
|
|
'width': item['model_width'] + model_type.embryo_tolerance,
|
|
'height': item['model_height'] + model_type.embryo_tolerance,
|
|
'volume': (item['model_long'] + model_type.embryo_tolerance) * (
|
|
item['model_width'] + model_type.embryo_tolerance) * (
|
|
item['model_height'] + model_type.embryo_tolerance),
|
|
'embryo_model_type_id': model_type.id,
|
|
'list_price': item['price'],
|
|
'materials_id': materials_id.id,
|
|
'materials_type_id': materials_type_id.id,
|
|
'is_bfm': True,
|
|
'active': True
|
|
}
|
|
# 外协和采购生成的坯料需要根据材料型号绑定供应商
|
|
if route_type == 'subcontract' or route_type == 'purchase':
|
|
no_bom_copy_product_id.purchase_ok = True
|
|
if supplier:
|
|
no_bom_copy_product_id.seller_ids = [
|
|
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0})]
|
|
if route_type == 'subcontract':
|
|
partner = self.env['res.partner'].search([('id', '=', supplier.partner_id.id)])
|
|
partner.is_subcontractor = True
|
|
else:
|
|
return -3
|
|
no_bom_copy_product_id.write(vals)
|
|
return no_bom_copy_product_id
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
for vals in vals_list:
|
|
if vals.get('upload_model_file'):
|
|
if vals.get('is_bfm') is False and vals.get('categ_type') == '成品':
|
|
for item in vals['upload_model_file']:
|
|
logging.info('create-attachment:%s' % int(item[2][0]))
|
|
attachment = self.env['ir.attachment'].sudo().search([('id', '=', int(item[2][0]))])
|
|
base64_data = base64.b64encode(attachment.datas)
|
|
base64_datas = base64_data.decode('utf-8')
|
|
model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
|
|
report_path = attachment._full_path(attachment.store_fname)
|
|
vals['model_file'] = self.transition_glb_file(report_path, model_code)
|
|
logging.info('create-model_file:%s' % len(vals['model_file']))
|
|
self._sanitize_vals(vals)
|
|
templates = super(ResProductMo, self).create(vals_list)
|
|
# 产品名称唯一性校验
|
|
for item in templates:
|
|
if len(self.search([('name', '=', item.name)])) > 1:
|
|
raise ValidationError('产品名称【%s】已存在' % item.name)
|
|
if "create_product_product" not in self._context:
|
|
templates._create_variant_ids()
|
|
|
|
# This is needed to set given values to first variant after creation
|
|
for template, vals in zip(templates, vals_list):
|
|
related_vals = {}
|
|
for field_name in self._get_related_fields_variant_template():
|
|
if vals.get(field_name):
|
|
related_vals[field_name] = vals[field_name]
|
|
if related_vals:
|
|
template.write(related_vals)
|
|
return templates
|
|
|
|
@api.onchange('upload_model_file')
|
|
def onchange_model_file(self):
|
|
for item in self:
|
|
if item.upload_model_file:
|
|
if len(item.upload_model_file) > 1:
|
|
raise ValidationError('只允许上传一个文件')
|
|
manufacturing_order = self.env['mrp.production'].search([('product_id', '=', self.id)])
|
|
if manufacturing_order:
|
|
raise ValidationError('该产品已生成制造订单,无法进行修改')
|
|
file_attachment_id = item.upload_model_file[0]
|
|
# 附件路径
|
|
report_path = file_attachment_id._full_path(file_attachment_id.store_fname)
|
|
base64_data = base64.b64encode(file_attachment_id.datas)
|
|
base64_datas = base64_data.decode('utf-8')
|
|
model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
|
|
item.model_file = self.transition_glb_file(report_path, model_code)
|
|
|
|
# 将attach的datas内容转为glb文件
|
|
def transition_glb_file(self, report_path, code):
|
|
shapes = read_step_file(report_path)
|
|
output_file = os.path.join('/tmp', str(code) + '.stl')
|
|
write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
|
|
# 转化为glb
|
|
output_glb_file = os.path.join('/tmp', str(code) + '.glb')
|
|
util_path = get_resource_path('sf_base', 'static/util')
|
|
cmd = 'python3 %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file)
|
|
os.system(cmd)
|
|
# 转base64
|
|
with open(output_glb_file, 'rb') as fileObj:
|
|
image_data = fileObj.read()
|
|
base64_data = base64.b64encode(image_data)
|
|
return base64_data
|
|
|
|
|
|
class ResProductFixture(models.Model):
|
|
_inherit = 'product.template'
|
|
_description = '夹具产品信息'
|
|
|
|
fixture_model_id = fields.Many2one('sf.fixture.model', '夹具型号')
|
|
specification_fixture_id = fields.Many2one('sf.fixture.materials.basic.parameters', '夹具规格')
|
|
|
|
fixture_material_id = fields.Many2one('sf.fixture.material', string="夹具物料")
|
|
fixture_material_type = fields.Char(string="夹具物料类型", related='fixture_material_id.name')
|
|
multi_mounting_type_id = fields.Many2one('sf.multi_mounting.type', string="联装类型")
|
|
model_file = fields.Binary(string="3D模型图")
|
|
|
|
# 夹具物料基本参数
|
|
diameter = fields.Float('直径(mm)', digits=(16, 2))
|
|
|
|
# '零点卡盘' 字段
|
|
weight = fields.Float('重量(mm)', digits=(16, 2))
|
|
orientation_dish_diameter = fields.Float('定位盘直径(mm)', digits=(16, 2))
|
|
clamping_diameter = fields.Float('装夹直径(mm)', digits=(16, 2))
|
|
clamping_num = fields.Selection([('1', '1'), ('2', '2'), ('4', '4'), ('6', '6'), ('8', '8')], string='装夹单元数')
|
|
chucking_power_max = fields.Float('最大夹持力(KN)', digits=(16, 2))
|
|
repeated_positioning_accuracy = fields.Char('重复定位精度(mm)', size=20)
|
|
boolean_transposing_hole = fields.Boolean('是否有转位孔')
|
|
unlocking_method = fields.Selection(
|
|
[('手动', '手动'), ('气动', '气动'), ('液压', '液压'), ('电动', '电动'), ('其他', '其他')], string='解锁方式')
|
|
boolean_chip_blowing_function = fields.Boolean('是否有吹屑功能')
|
|
carrying_capacity_max = fields.Float('最大承载重量(kg)', digits=(16, 2))
|
|
rigidity = fields.Integer('硬度HRC')
|
|
materials_model_id = fields.Many2one('sf.materials.model', '夹具材质')
|
|
machine_tool_type_id = fields.Many2one('sf.machine_tool.type', '适用机床型号')
|
|
|
|
# ’零点托盘‘ 字段
|
|
connector_diameter = fields.Selection([('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('8', '8')],
|
|
string='连接头直径(mm)')
|
|
way_to_install = fields.Selection(
|
|
[('接口式', '接口式'), ('螺栓固定', '螺栓固定'), ('磁吸式', '磁吸式'), ('其他', '其他')], string='安装方式')
|
|
type_of_drive = fields.Selection(
|
|
[('气动式', '气动式'), ('液压式', '液压式'), ('机械式', '机械式'), ('电动式', '电动式'), ('其他', '其他')],
|
|
string='驱动方式')
|
|
|
|
# ’气动夹具‘ 字段
|
|
gripper_length_min = fields.Float('夹持工件最小长度(mm)', digits=(16, 2))
|
|
gripper_width_min = fields.Float('夹持工件最小宽度(mm)', digits=(16, 2))
|
|
gripper_height_min = fields.Float('夹持工件最小高度(mm)', digits=(16, 2))
|
|
gripper_diameter_min = fields.Float('夹持工件最小直径(mm)', digits=(16, 2))
|
|
gripper_length_max = fields.Float('夹持工件最大长度(mm)', digits=(16, 2))
|
|
gripper_width_max = fields.Float('夹持工件最大宽度(mm)', digits=(16, 2))
|
|
gripper_height_max = fields.Float('夹持工件最大高度(mm)', digits=(16, 2))
|
|
gripper_diameter_max = fields.Float('夹持工件最大直径(mm)', digits=(16, 2))
|
|
rated_air_pressure = fields.Float('额定气压(Mpa)', digits=(16, 2))
|
|
interface_materials_model_id = fields.Many2one('sf.materials.model', '接口类型')
|
|
|
|
# ‘虎钳夹具' 字段
|
|
transverse_groove = fields.Float('横向配合槽n(mm)', digits=(16, 2))
|
|
longitudinal_fitting_groove = fields.Float('纵向配合槽l(mm)', digits=(16, 2))
|
|
|
|
# '磁吸夹具' 字段
|
|
height_tolerance_value = fields.Char('高度公差(mm)')
|
|
rated_adsorption_force = fields.Float('额定吸附力(N/cm²)', digits=(16, 2))
|
|
magnetic_field_height = fields.Float('磁场高度(mm)', digits=(16, 2))
|
|
magnetic_pole_plate_grinding_allowance = fields.Float('磁极板磨削余量(mm)', digits=(16, 2))
|
|
|
|
# '转接板(锁板)夹具' 字段
|
|
screw_size = fields.Float('螺牙大小(mm)', digits=(16, 2))
|
|
via_hole_diameter = fields.Float('过孔直径(mm)', digits=(16, 2))
|
|
|
|
# '三爪卡盘' 字段
|
|
mounting_hole_depth = fields.Float('安装孔深度(mm)', digits=(16, 2))
|
|
centering_diameter = fields.Float('定心直径(mm)', digits=(16, 2))
|
|
|
|
@api.onchange('specification_fixture_id')
|
|
def _onchange_specification_fixture_id(self):
|
|
if self.specification_fixture_id:
|
|
self.length = self.specification_fixture_id.length
|
|
self.width = self.specification_fixture_id.width
|
|
self.height = self.specification_fixture_id.height
|
|
self.weight = self.specification_fixture_id.weight
|
|
self.diameter = self.specification_fixture_id.diameter
|
|
self.orientation_dish_diameter = self.specification_fixture_id.orientation_dish_diameter
|
|
self.clamping_diameter = self.specification_fixture_id.clamping_diameter
|
|
self.clamping_num = self.specification_fixture_id.clamping_num
|
|
self.chucking_power_max = self.specification_fixture_id.chucking_power_max
|
|
self.repeated_positioning_accuracy = self.specification_fixture_id.repeated_positioning_accuracy
|
|
self.boolean_transposing_hole = self.specification_fixture_id.boolean_transposing_hole
|
|
self.unlocking_method = self.specification_fixture_id.unlocking_method
|
|
self.boolean_chip_blowing_function = self.specification_fixture_id.boolean_chip_blowing_function
|
|
self.carrying_capacity_max = self.specification_fixture_id.carrying_capacity_max
|
|
self.rigidity = self.specification_fixture_id.rigidity
|
|
self.materials_model_id = self.specification_fixture_id.materials_model_id
|
|
self.machine_tool_type_id = self.specification_fixture_id.machine_tool_type_id
|
|
self.connector_diameter = self.specification_fixture_id.connector_diameter
|
|
self.way_to_install = self.specification_fixture_id.way_to_install
|
|
self.type_of_drive = self.specification_fixture_id.type_of_drive
|
|
self.gripper_length_min = self.specification_fixture_id.gripper_length_min
|
|
self.gripper_width_min = self.specification_fixture_id.gripper_width_min
|
|
self.gripper_height_min = self.specification_fixture_id.gripper_height_min
|
|
self.gripper_diameter_min = self.specification_fixture_id.gripper_diameter_min
|
|
self.gripper_length_max = self.specification_fixture_id.gripper_length_max
|
|
self.gripper_width_max = self.specification_fixture_id.gripper_width_max
|
|
self.gripper_height_max = self.specification_fixture_id.gripper_height_max
|
|
self.gripper_diameter_max = self.specification_fixture_id.gripper_diameter_max
|
|
self.rated_air_pressure = self.specification_fixture_id.rated_air_pressure
|
|
self.interface_materials_model_id = self.specification_fixture_id.interface_materials_model_id
|
|
self.transverse_groove = self.specification_fixture_id.transverse_groove
|
|
self.longitudinal_fitting_groove = self.specification_fixture_id.longitudinal_fitting_groove
|
|
self.height_tolerance_value = self.specification_fixture_id.height_tolerance_value
|
|
self.rated_adsorption_force = self.specification_fixture_id.rated_adsorption_force
|
|
self.magnetic_field_height = self.specification_fixture_id.magnetic_field_height
|
|
self.magnetic_pole_plate_grinding_allowance = self.specification_fixture_id.magnetic_pole_plate_grinding_allowance
|
|
self.screw_size = self.specification_fixture_id.screw_size
|
|
self.via_hole_diameter = self.specification_fixture_id.via_hole_diameter
|
|
self.mounting_hole_depth = self.specification_fixture_id.mounting_hole_depth
|
|
self.centering_diameter = self.specification_fixture_id.centering_diameter
|
|
|
|
|
|
class SfMaintenanceEquipmentAndProductTemplate(models.Model):
|
|
_inherit = 'maintenance.equipment'
|
|
_description = '设备'
|
|
|
|
product_template_ids = fields.One2many('maintenance.equipment.tool', 'equipment_id', string='机床刀位')
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
vals = []
|
|
for value in vals_list:
|
|
res = super(SfMaintenanceEquipmentAndProductTemplate, self).create(value)
|
|
number = value.get('number_of_knife_library')
|
|
for i in range(1, number + 1):
|
|
self.env['maintenance.equipment.tool'].create({
|
|
'equipment_id': res.id,
|
|
'code': "T%02d" % i
|
|
})
|
|
vals.append(res)
|
|
return vals[0]
|
|
|
|
base_coordinate_fixture_model_id = fields.Many2one('sf.fixture.model', '基坐标卡盘型号',
|
|
domain=[('fixture_material_id', '=', '零点卡盘')])
|
|
base_coordinate_g_coordinate = fields.Char('G坐标')
|
|
base_coordinate_x = fields.Float('x轴', digits=(12, 3))
|
|
base_coordinate_y = fields.Float('y轴', digits=(12, 3))
|
|
base_coordinate_z = fields.Float('z轴', digits=(12, 3))
|
|
|
|
# ==========获取机床基坐标接口==========
|
|
def get_equipment_base_coordinate(self):
|
|
headers = {'Authorization': 'Ba F2CF5DCC-1A00-4234-9E95-65603F70CC8A'}
|
|
crea_url = "https://x24467i973.zicp.fun/AutoDeviceApi/EquipmentBaseCoordinate"
|
|
params = {"DeviceId": self.name}
|
|
r = requests.get(crea_url, params=params, headers=headers)
|
|
ret = r.json()
|
|
logging.info('register_equipment_tool:%s' % ret)
|
|
self.write({
|
|
'base_coordinate_fixture_model_id': ret['base_coordinate_fixture_model_id'],
|
|
'base_coordinate_g_coordinate': ret['base_coordinate_g_coordinate'],
|
|
'base_coordinate_x': ret['base_coordinate_x'],
|
|
'base_coordinate_y': ret['base_coordinate_y'],
|
|
'base_coordinate_z': ret['base_coordinate_z'],
|
|
})
|
|
if ret['Succeed']:
|
|
return "机床基坐标获取成功"
|
|
else:
|
|
raise ValidationError("机床基坐标获取失败")
|
|
|
|
|
|
class SfMaintenanceEquipmentTool(models.Model):
|
|
_name = 'maintenance.equipment.tool'
|
|
_description = '机床刀位'
|
|
|
|
equipment_id = fields.Many2one('maintenance.equipment', string='设备')
|
|
|
|
code = fields.Char('机床刀位号')
|
|
name = fields.Char('刀位号', compute='_compute_name')
|
|
|
|
# 待删除字段
|
|
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('直径')
|
|
precision = fields.Char('粗\中\精')
|
|
tool_code = fields.Char('功能刀具编码')
|
|
hilt_name = fields.Char('刀柄名称')
|
|
hilt_code = fields.Char('刀柄编码')
|
|
life_value_max = fields.Char('最大寿命值')
|
|
alarm_value = fields.Char('报警值')
|
|
used_value = fields.Char('已使用值')
|
|
|
|
@api.depends('code')
|
|
def _compute_name(self):
|
|
for record in self:
|
|
if record.code:
|
|
record.name = record.code
|