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('加工面') 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) @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'])) feature_path = self.env['jikimo.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['jikimo.auto_quatotion.common'].sudo().get_process_time_db_path() ret = self.env['jikimo.auto_quatotion.common'].sudo().get_auto_quatotion(report_path, feature_path, process_time_db_path, model_code) logging.info("自动报价返回值: %s" % ret) shapes = ret['boxshape'].tolist() logging.info("自动报价boxshape: %s" % shapes) target_faces = ','.join(ret['target_faces']), # item.price = ret['price'] item.model_length = shapes[0] # 长 单位mm item.model_width = shapes[1] # 宽 item.model_height = shapes[2] # 高 item.model_volume = shapes[0] * shapes[1] * shapes[2] item.model_processing_side = target_faces[0] obj = super(QuickEasyOrder, self).create(vals) 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('mrs_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 # 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) else: item.model_file = False def distribute_to_factory(self, obj): """ 派单到工厂 :return: """ web_base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url', default=''), 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': 100, 'model_width': 100, 'model_height': 100, 'model_volume': 300, '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("分配工厂失败,请联系管理员")