1.去掉上色和特征识别方法,

2.转换模型需自动识别模型长宽高
3.优化页面:下拉框关闭创建
4.权限修改为不可编辑
This commit is contained in:
jinling.yang
2024-04-17 13:19:07 +08:00
parent c535808d5f
commit f04cbac8d9
3 changed files with 59 additions and 118 deletions

View File

@@ -2,19 +2,14 @@ import logging
import base64 import base64
import hashlib import hashlib
import os import os
import platform
import json
from datetime import datetime from datetime import datetime
import requests from stl import mesh
from odoo import http # from OCC.Core.GProp import GProp_GProps
from odoo.http import request
from OCC.Extend.DataExchange import read_step_file from OCC.Extend.DataExchange import read_step_file
from OCC.Extend.DataExchange import write_stl_file from OCC.Extend.DataExchange import write_stl_file
from odoo import models, fields, api from odoo import models, fields, api
from odoo.modules import get_resource_path from odoo.modules import get_resource_path
from odoo.exceptions import ValidationError, UserError from odoo.exceptions import ValidationError, UserError
from odoo.addons.sf_base.commons.common import Common
from . import parser_and_calculate_work_time as pc
class QuickEasyOrder(models.Model): class QuickEasyOrder(models.Model):
@@ -36,7 +31,7 @@ class QuickEasyOrder(models.Model):
('0.02', '±0.02mm'), ('0.02', '±0.02mm'),
('0.01', '±0.01mm')], string='加工精度', default='0.10') ('0.01', '±0.01mm')], string='加工精度', default='0.10')
material_id = fields.Many2one('sf.production.materials', '材料') material_id = fields.Many2one('sf.production.materials', '材料')
material_model_id = fields.Many2one('sf.materials.model', '型号') material_model_id = fields.Many2one('sf.materials.model', '型号', domain="[('materials_id', '=', material_id)]")
# process_id = fields.Many2one('sf.production.process', string='表面工艺') # process_id = fields.Many2one('sf.production.process', string='表面工艺')
parameter_ids = fields.Many2many('sf.production.process.parameter', 'process_item_order_rel', string='可选参数') parameter_ids = fields.Many2many('sf.production.process.parameter', 'process_item_order_rel', string='可选参数')
quantity = fields.Integer('数量', default=1) quantity = fields.Integer('数量', default=1)
@@ -83,9 +78,7 @@ class QuickEasyOrder(models.Model):
model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest() model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
report_path = attachment._full_path(attachment.store_fname) report_path = attachment._full_path(attachment.store_fname)
vals['model_file'] = self.transition_glb_file(report_path, model_code) vals['model_file'] = self.transition_glb_file(report_path, model_code)
logging.info('create-model_file:%s' % len(vals['model_file']))
obj = super(QuickEasyOrder, self).create(vals) obj = super(QuickEasyOrder, self).create(vals)
self.model_coloring(obj)
logging.info('---------开始派单到工厂-------') logging.info('---------开始派单到工厂-------')
self.distribute_to_factory(obj) self.distribute_to_factory(obj)
obj.state = '待接单' obj.state = '待接单'
@@ -122,15 +115,42 @@ class QuickEasyOrder(models.Model):
base64_data = base64.b64encode(file_attachment_id.datas) base64_data = base64.b64encode(file_attachment_id.datas)
base64_datas = base64_data.decode('utf-8') base64_datas = base64_data.decode('utf-8')
model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest() model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
logging.info("模型编码: %s" % model_code) # 读取文件
item.model_file = self.transition_glb_file(report_path, model_code) shapes = read_step_file(report_path)
# # 第一种获取体积方式
# props = GProp_GProps()
# # brepgprop_VolumeProperties(shapes, props)
# volume = props.Mass()
# # print(volume)
# item.model_volume = volume
# # 长宽高/体积
# output_file = os.path.join('C:/Users/43484/Desktop/机企猫工作文档', str(library_of_models.code) + '.stl')
output_file = os.path.join('/tmp', str(model_code) + '.stl')
your_mesh = mesh.Mesh.from_file(output_file)
volume, cog, inertia = your_mesh.get_mass_properties()
xyz = (your_mesh.max_ - your_mesh.min_)
item.model_length = xyz[0] # 长 单位mm
item.model_width = xyz[1] # 宽
item.model_height = xyz[2] # 高
item.model_volume = volume
write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
# 转化为glb
# output_glb_file = os.path.join('C:/Users/43484/Desktop/机企猫工作文档', str(library_of_models.code) + '.glb')
output_glb_file = os.path.join('/tmp', str(model_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)
item.model_file = base64_data
else: else:
item.model_length = False
item.model_width = False
item.model_height = False
item.model_volume = False
item.model_file = False item.model_file = False
item.model_feature = False
item.model_length = 0
item.model_width = 0
item.model_height = 0
item.model_volume = 0
def distribute_to_factory(self, obj): def distribute_to_factory(self, obj):
""" """
@@ -201,7 +221,7 @@ class QuickEasyOrder(models.Model):
self_machining_bom = self.env['mrp.bom'].bom_create(self_machining_embryo, 'normal', False) self_machining_bom = self.env['mrp.bom'].bom_create(self_machining_embryo, 'normal', False)
# 创建坯料里bom的组件 # 创建坯料里bom的组件
self_machining_bom_line = self_machining_bom.bom_create_line(self_machining_embryo) self_machining_bom_line = self_machining_bom.bom_create_line(self_machining_embryo)
if self_machining_bom_line is False: if not self_machining_bom_line:
self.cr.rollback() self.cr.rollback()
return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配') return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配')
# 产品配置bom # 产品配置bom
@@ -212,12 +232,16 @@ class QuickEasyOrder(models.Model):
outsource_embryo = self.env['product.template'].sudo().no_bom_product_create(outsource_id, item, outsource_embryo = self.env['product.template'].sudo().no_bom_product_create(outsource_id, item,
order_id, order_id,
'subcontract', i) 'subcontract', i)
if outsource_embryo == -3:
self.cr.rollback()
return UserError(
'该订单模型的材料型号在您分配的工厂里暂未设置获取方式和供应商,请先配置再进行分配')
# 创建坯料的bom # 创建坯料的bom
outsource_bom = self.env['mrp.bom'].bom_create(outsource_embryo, 'subcontract', True) outsource_bom = self.env['mrp.bom'].bom_create(outsource_embryo, 'subcontract', True)
# 创建坯料的bom的组件 # 创建坯料的bom的组件
outsource_bom_line = outsource_bom.with_user( outsource_bom_line = outsource_bom.with_user(
self.env.ref("base.user_admin")).bom_create_line(outsource_embryo) self.env.ref("base.user_admin")).bom_create_line(outsource_embryo)
if outsource_bom_line is False: if not outsource_bom_line:
self.cr.rollback() self.cr.rollback()
return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配') return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配')
# 产品配置bom # 产品配置bom
@@ -227,6 +251,10 @@ class QuickEasyOrder(models.Model):
purchase_embryo = self.env['product.template'].sudo().no_bom_product_create(purchase_id, item, purchase_embryo = self.env['product.template'].sudo().no_bom_product_create(purchase_id, item,
order_id, order_id,
'purchase', i) 'purchase', i)
if purchase_embryo == -3:
self.cr.rollback()
return UserError(
'该订单模型的材料型号在您分配的工厂里暂未设置获取方式和供应商,请先配置再进行分配')
# 产品配置bom # 产品配置bom
product_bom_purchase = self.env['mrp.bom'].bom_create(product, 'normal', False) product_bom_purchase = self.env['mrp.bom'].bom_create(product, 'normal', False)
product_bom_purchase.bom_create_line_has(purchase_embryo) product_bom_purchase.bom_create_line_has(purchase_embryo)
@@ -234,93 +262,3 @@ class QuickEasyOrder(models.Model):
except Exception as e: except Exception as e:
# self.cr.rollback() # self.cr.rollback()
return UserError('工厂创建销售订单和产品失败,请联系管理员') return UserError('工厂创建销售订单和产品失败,请联系管理员')
# 特征识别
def feature_recognition(self, report_path, model_code):
feature_path = self.env['sf.auto_quatotion.common'].sudo().get_feature_full_path()
process_time_db_path = self.env['sf.auto_quatotion.common'].sudo().get_process_time_db_path()
ret = self.env['sf.auto_quatotion.common'].sudo().get_auto_quatotion(report_path, feature_path,
process_time_db_path,
model_code)
return ret
# 模型上色
def model_coloring(self, order):
url = '/api/library_of_models/create'
config = self.env['res.config.settings'].get_values()
config_header = Common.get_headers(self, config['token'], config['sf_secret_key'])
logging.info('order: %s' % order.name)
if order:
attachment = order.upload_model_file[0]
base64_data = base64.b64encode(attachment.datas)
base64_datas = base64_data.decode('utf-8')
model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
logging.info('model_file-size: %s' % len(order.model_file))
logging.info('attachment.datas-size: %s' % len(attachment.datas))
vals = {
'model_code': model_code,
'model_data': base64_data,
'model_name': attachment.name,
'model_long': order.model_length,
'model_width': order.model_width,
'model_height': order.model_height,
'model_volume': order.model_volume,
'model_order_no': order.name,
'remark': '订单号:%s 客户:%s' % (order.name, order.customer_id.name)
}
try:
ret = requests.post((config['sf_url'] + url), json={}, data=vals, headers=config_header,
timeout=60)
ret = ret.json()
# result = json.loads(ret['result'])
if ret['status'] == 1:
order.model_color_state = 'success'
else:
order.model_color_state = 'fail'
raise UserError(ret['message'])
except Exception as e:
order.model_color_state = 'fail'
raise UserError("模型上色失败")
# 自动报价
def _get_price(self, order):
url = '/api/automatic_quotes'
config = self.env['res.config.settings'].sudo().get_values()
config_header = Common.get_headers(self, config['token'], config['sf_secret_key'])
logging.info("报价接口..........% s" % order.name)
try:
if order:
vals = {}
# mrs合作伙伴token
vals['token'] = config['token']
vals['accuracy'] = order.machining_precision
vals['number'] = order.quantity
vals['process_code'] = 0
vals['texture_code'] = order.material_model_id.materials_no
vals['delivery_days'] = 15
if order.model_file:
for item in order.upload_model_file:
if item.ids[0]:
logging.info('create-attachment:%s' % int(item.ids[0]))
attachment = self.env['ir.attachment'].sudo().search([('id', '=', int(item.ids[0]))])
vals['attachment_id'] = attachment.id
else:
vals['attachment_id'] = ''
vals['feature_infos'] = order.model_feature
vals['model_long'] = order.model_length
vals['model_width'] = order.model_width
vals['model_height'] = order.model_height
logging.info('vals:%s' % vals)
ret = requests.post((config['sf_url'] + url), json={}, data=vals, headers=config_header)
result = json.dumps(json.loads(ret.text), ensure_ascii=False, indent=4, separators=(',', ':'))
logging.info('报价接口返回:%s' % result)
price_result = json.loads(result)
# random.randint(0, 10000)
order.write({'price': price_result.get('price')})
else:
raise UserError("订单不存在")
except Exception as e:
if ret['status'] != 1:
raise UserError(e)
else:
raise UserError("自动报价失败,请联系管理员")

View File

@@ -1,7 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_quick_easy_order,quick_easy_order,model_quick_easy_order,base.group_system,1,1,1,0 access_quick_easy_order,quick_easy_order,model_quick_easy_order,base.group_system,1,1,1,0
access_quick_easy_order_group_sale_salemanager,quick_easy_order_group_sale_salemanager,model_quick_easy_order,sf_base.group_sale_salemanager,1,1,1,0 access_quick_easy_order_group_sale_salemanager,quick_easy_order_group_sale_salemanager,model_quick_easy_order,sf_base.group_sale_salemanager,1,0,1,0
access_quick_easy_order_group_sale_director,quick_easy_order_group_sale_director,model_quick_easy_order,sf_base.group_sale_director,1,1,1,0 access_quick_easy_order_group_sale_director,quick_easy_order_group_sale_director,model_quick_easy_order,sf_base.group_sale_director,1,0,1,0
access_sf_auto_quatotion_common,sf_auto_quatotion_common,model_sf_auto_quatotion_common,base.group_system,1,1,1,1 access_sf_auto_quatotion_common,sf_auto_quatotion_common,model_sf_auto_quatotion_common,base.group_system,1,1,1,1
access_sale_order_manager,sale_order_manager,model_sale_order,sf_base.group_sale_salemanager,1,1,1,0 access_sale_order_manager,sale_order_manager,model_sale_order,sf_base.group_sale_salemanager,1,1,1,0
access_sale_order_director,sale_order_director,model_sale_order,sf_base.group_sale_director,1,1,1,0 access_sale_order_director,sale_order_director,model_sale_order,sf_base.group_sale_director,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_quick_easy_order quick_easy_order model_quick_easy_order base.group_system 1 1 1 0
3 access_quick_easy_order_group_sale_salemanager quick_easy_order_group_sale_salemanager model_quick_easy_order sf_base.group_sale_salemanager 1 1 0 1 0
4 access_quick_easy_order_group_sale_director quick_easy_order_group_sale_director model_quick_easy_order sf_base.group_sale_director 1 1 0 1 0
5 access_sf_auto_quatotion_common sf_auto_quatotion_common model_sf_auto_quatotion_common base.group_system 1 1 1 1
6 access_sale_order_manager sale_order_manager model_sale_order sf_base.group_sale_salemanager 1 1 1 0
7 access_sale_order_director sale_order_director model_sale_order sf_base.group_sale_director 1 1 1 0

View File

@@ -47,15 +47,17 @@
</h1> </h1>
<group> <group>
<group> <group>
<field name="customer_id" /> <field name="customer_id" context="{'is_customer': True }"
<field name="material_id"/> options="{'no_create': True}"/>
<field name="material_model_id"/> <field name="material_id" options="{'no_create': True}"/>
<field name="material_model_id" options="{'no_create': True}"/>
<!-- <field name="process_id"/>--> <!-- <field name="process_id"/>-->
<field name="parameter_ids" widget="many2many_tags" string="表面工艺参数"/> <field name="parameter_ids" widget="many2many_tags" string="表面工艺参数"
options="{'no_create': True}"/>
<field name="machining_precision"/> <field name="machining_precision"/>
<field name="quantity"/> <field name="quantity" options="{'format': false}"/>
<field name="unit_price"/> <field name="unit_price"/>
<field name="price"/> <field name="price" options="{'format': false}"/>
</group> </group>
<group> <group>
<field name="upload_model_file" widget="many2many_binary"/> <field name="upload_model_file" widget="many2many_binary"/>
@@ -75,7 +77,8 @@
<field name="model_height" class="o_address_zip" <field name="model_height" class="o_address_zip"
options="{'format': false}"/> options="{'format': false}"/>
</div> </div>
<field name="model_volume" attrs="{'invisible': [('model_file', '=', False)]}"/> <field name="model_volume" attrs="{'invisible': [('model_file', '=', False)]}"
options="{'format': false}"/>
<field name="processing_time"/> <field name="processing_time"/>
</group> </group>
</group> </group>