281 lines
14 KiB
Python
281 lines
14 KiB
Python
from odoo import models, fields, api
|
|
from odoo.modules import get_resource_path
|
|
# from OCC.Extend.DataExchange import read_step_file
|
|
# from OCC.Extend.DataExchange import write_stl_file
|
|
from odoo.exceptions import ValidationError, UserError
|
|
from odoo.addons.sf_base.commons.common import Common
|
|
from datetime import datetime
|
|
import logging
|
|
import base64
|
|
import hashlib
|
|
import os
|
|
import json
|
|
import requests
|
|
|
|
|
|
class QuickEasyOrder(models.Model):
|
|
_name = 'quick.easy.order'
|
|
_description = '简易下单'
|
|
|
|
name = fields.Char('订单编号', default=lambda self: self.env['ir.sequence'].next_by_code('quick.easy.order'))
|
|
model_length = 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('体积(mm³)', digits=(16, 3))
|
|
model_processing_side = fields.Char('加工面', default='A')
|
|
model_feature = fields.Char('特征')
|
|
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='加工精度', default='0.10')
|
|
material_id = fields.Many2one('sf.production.materials', '材料', compute='_compute_material_model', store=True)
|
|
material_model_id = fields.Many2one('sf.materials.model', '型号', compute='_compute_material_model', store=True)
|
|
process_id = fields.Many2one('sf.production.process', string='表面工艺')
|
|
parameter_ids = fields.One2many('sf.production.process.parameter', 'process_id', string='可选参数')
|
|
quantity = fields.Integer('数量', default=1)
|
|
unit_price = fields.Float('单价')
|
|
price = fields.Float('总价')
|
|
model_file = fields.Binary('模型文件')
|
|
upload_model_file = fields.Many2many('ir.attachment', 'upload_qf_model_file_attachment_ref', string='模型文件')
|
|
delivery_time = fields.Date('交货日期')
|
|
customer_id = fields.Many2one('res.partner', string='客户', default=lambda self: self.env.user.partner_id.id)
|
|
state = fields.Selection([('草稿', '草稿'), ('待付款', '待付款'), ('待派单', '待派单'),
|
|
('待接单', '待接单'), ('加工中', '加工中'),
|
|
('物流中', '物流中'), ('已交付', '已交付')], string='订单状态', default='草稿',
|
|
readonly=True)
|
|
model_color_state = fields.Selection([
|
|
('success', '成功'),
|
|
('fail', '失败')], string='模型上色状态')
|
|
|
|
@api.depends('material_id', 'material_model_id')
|
|
def _compute_material_model(self):
|
|
for item in self:
|
|
materials = self.env['sf.production.materials'].search([], limit=1, order='id desc')
|
|
item.material_id = materials.id
|
|
item.material_model_id = self.env['sf.materials.model'].search(
|
|
[('materials_id', '=', materials.id)],
|
|
limit=1, order='id desc')
|
|
|
|
@api.model
|
|
def create(self, vals):
|
|
if vals.get('upload_model_file'):
|
|
logging.info('create-attachment:%s' % vals['upload_model_file'][0])
|
|
for item in vals['upload_model_file']:
|
|
print(len(item[2]))
|
|
if len(item[2]) > 0:
|
|
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']))
|
|
|
|
obj = super(QuickEasyOrder, self).create(vals)
|
|
self.model_coloring()
|
|
self.distribute_to_factory(obj)
|
|
return obj
|
|
|
|
# 将attach的datas内容转为glb文件
|
|
# def transition_glb_file(self, report_path, model_code):
|
|
# shapes = read_step_file(report_path)
|
|
# #output_file = os.path.join('C:/Users/43484/Desktop/机企猫工作文档', str(model_code) + '.stl')
|
|
# output_file = os.path.join('/tmp', str(model_code) + '.stl')
|
|
# write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
|
|
# # 转化为glb
|
|
# #output_glb_file = os.path.join('C:/Users/43484/Desktop/机企猫工作文档', str(model_code) + '.glb')
|
|
# output_glb_file = os.path.join('/tmp', str(model_code) + '.glb')
|
|
# util_path = get_resource_path('sf_dlm', 'static/util')
|
|
# cmd = 'python3 %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file)
|
|
# os.system(cmd)
|
|
# # 转base64
|
|
# with open(output_glb_file, 'rb') as fileObj:
|
|
# image_data = fileObj.read()
|
|
# base64_data = base64.b64encode(image_data)
|
|
# return base64_data
|
|
# return False
|
|
|
|
@api.onchange('upload_model_file')
|
|
def onchange_model_file(self):
|
|
for item in self:
|
|
if len(item.upload_model_file) > 1:
|
|
raise ValidationError('只允许上传一个文件')
|
|
if item.upload_model_file:
|
|
file_attachment_id = item.upload_model_file[0]
|
|
# 附件路径
|
|
report_path = file_attachment_id._full_path(file_attachment_id.store_fname)
|
|
logging.info("模型路径: %s" % report_path)
|
|
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()
|
|
logging.info("模型编码: %s" % model_code)
|
|
item.model_file = self.transition_glb_file(report_path, model_code)
|
|
ret = self.feature_recognition(report_path, model_code)
|
|
logging.info("自动报价返回值: %s" % ret)
|
|
boxshape = ret['boxshape'].tolist()
|
|
logging.info("自动报价boxshape: %s" % boxshape)
|
|
logging.info('自动报价feature_infos:%s' % ret['feature_infos'])
|
|
item.model_length = boxshape[0] # 长 单位mm
|
|
item.model_width = boxshape[1] # 宽
|
|
item.model_height = boxshape[2] # 高
|
|
item.model_volume = boxshape[0] * boxshape[1] * boxshape[2]
|
|
item.model_feature = json.dumps(ret['feature_infos'], ensure_ascii=False)
|
|
self._get_price(item)
|
|
else:
|
|
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):
|
|
"""
|
|
派单到工厂
|
|
:return:
|
|
"""
|
|
web_base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url', default='')
|
|
logging.info("web_base_url: %s" % web_base_url)
|
|
url = '/api/bfm_process_order/list'
|
|
res = {'order_number': obj.name, 'delivery_end_date': str(datetime.now()),
|
|
'delivery_name': 'XXXXX', 'delivery_telephone': 'XXXXX',
|
|
'delivery_address': 'XXXXX',
|
|
'bfm_process_order_list': []}
|
|
factory = self.env['res.partner'].sudo().search([], limit=1, order='id desc')
|
|
config_header = Common.get_headers(self, factory.sf_token, factory.sf_secret_key)
|
|
for item in obj:
|
|
attachment = item.upload_model_file[0]
|
|
base64_data = base64.b64encode(attachment.datas)
|
|
base64_datas = base64_data.decode('utf-8')
|
|
barcode = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
|
|
logging.info('model_file-size: %s' % len(item.model_file))
|
|
val = {
|
|
'model_long': item.model_length,
|
|
'model_width': item.model_width,
|
|
'model_height': item.model_height,
|
|
'model_volume': item.model_volume,
|
|
'model_machining_precision': item.machining_precision,
|
|
'model_name': attachment.name,
|
|
'model_data': base64_datas,
|
|
'model_file': base64.b64encode(item.model_file).decode('utf-8'),
|
|
'texture_code': item.material_id.materials_no,
|
|
'texture_type_code': item.material_model_id.materials_no,
|
|
# 'surface_process_code': self.env['jikimo.surface.process']._json_surface_process_code(item),
|
|
# 'process_parameters_code': self.env['jikimo.surface.process.item']._json_surface_process_item_code(
|
|
# item),
|
|
'price': item.price,
|
|
'number': item.quantity,
|
|
'total_amount': item.price,
|
|
'remark': '',
|
|
'barcode': barcode
|
|
}
|
|
res['bfm_process_order_list'].append(val)
|
|
res['bfm_process_order_list'] = json.dumps(res['bfm_process_order_list'])
|
|
try:
|
|
ret = requests.post((web_base_url[0] + url), json={}, data=res,
|
|
headers=config_header)
|
|
ret = ret.json()
|
|
if ret['status'] == 1:
|
|
self.write(
|
|
{'state': '待接单'})
|
|
else:
|
|
raise UserError(ret['message'])
|
|
except Exception as e:
|
|
if ret['status'] != 1:
|
|
raise UserError(e)
|
|
else:
|
|
raise UserError("分配工厂失败,请联系管理员")
|
|
|
|
# 特征识别
|
|
def feature_recognition(self, report_path, model_code):
|
|
feature_path = self.env['sf.auto_quatotion.common'].sudo().get_feature_full_path()
|
|
# price_path = self.env['jikimo.auto_quatotion.common'].get_price_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):
|
|
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'])
|
|
order = self.search([('id', '=', self.id)])
|
|
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.code
|
|
vals['delivery_days'] = 15
|
|
if order.model_file:
|
|
attachment = self.env['ir.attachment'].sudo().search(
|
|
[('id', '=', order.upload_model_file[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("自动报价失败,请联系管理员")
|