import base64 import requests import logging from itertools import groupby from odoo import models, api, fields from odoo.exceptions import UserError from odoo.addons.sf_base.commons.common import Common class MrpProduction(models.Model): _inherit = 'mrp.production' @api.model_create_multi def create(self, vals_list): """ 生成编程单 """ productions = super().create(vals_list) # 定义变量存储编程单 grouped_product_programming_no = {} # 定义产品拼接成的制造订单名称 grouped_product_production_name = {} if productions and productions[0].origin: # 查出所有的制造订单,为了适配通过补货生成的制造订单 all_productions = self.env['mrp.production'].search([('origin', '=', productions[0].origin)]) # 将不同产品的制造订单进行分组 grouped_product_productions = {k: list(g) for k, g in groupby(all_productions, key=lambda x: x.product_id.id)} for product_id, grouped_productions in grouped_product_productions.items(): # 产品对应的编程单号 if product_id not in grouped_product_programming_no: # 使用列表推导式获取非空的programming_no programming_nos = [p.programming_no for p in grouped_productions if p.programming_no if p.programming_no is not False] if programming_nos: grouped_product_programming_no[product_id] = programming_nos[0] grouped_product_production_name[product_id] = ','.join(list(map(lambda p:p.name, grouped_productions))) # 同一个产品的制造订单只请求一次CNC编程 for production in productions: # 如果是委外产生的制造订单,则不请求编程 if production.subcontractor_id: continue # 没有模型ID的制造订单不请求编程 if not production.model_id: continue if not production.programming_no and production.production_type in ['自动化产线加工','人工线下加工']: if production.product_id.id not in grouped_product_programming_no: production.fetchCNC(grouped_product_production_name[production.product_id.id]) grouped_product_programming_no[production.product_id.id] = production.programming_no else: production.write({ 'programming_no': grouped_product_programming_no[production.product_id.id], 'programming_state': '编程中' }) return productions # cnc程序获取 def fetchCNC(self, production_names): cnc = self.env['mrp.production'].search([('id', '=', self.id)]) quick_order = False if cnc.product_id.default_code: quick_order = self.env['quick.easy.order'].search( [('name', '=', cnc.product_id.default_code.rsplit('-', 1)[0])]) programme_way = False if cnc.manual_quotation is True: programme_way = 'manual operation' else: programme_way = 'auto' if cnc.production_type == '人工线下加工': programme_way = 'manual operation' if quick_order: programme_way = 'manual operation' try: res = { 'production_no': production_names, 'machine_tool_code': '', 'product_name': cnc.product_id.name, 'remanufacture_type': '', 'model_code': cnc.product_id.model_code, 'material_code': self.env['sf.production.materials'].search( [('id', '=', cnc.product_id.materials_id.id)]).materials_no, 'material_type_code': self.env['sf.materials.model'].search( [('id', '=', cnc.product_id.materials_type_id.id)]).materials_no, 'machining_processing_panel': cnc.product_id.model_processing_panel, 'machining_precision': '', 'embryo_long': cnc.product_id.bom_ids[0].bom_line_ids.product_id.length, 'embryo_height': cnc.product_id.bom_ids[0].bom_line_ids.product_id.height, 'embryo_width': cnc.product_id.bom_ids[0].bom_line_ids.product_id.width, 'order_no': cnc.origin, 'model_order_no': cnc.product_id.default_code, 'user': cnc.env.user.name, 'programme_way': programme_way, # 'model_file': '' if not cnc.product_id.model_file else base64.b64encode( # cnc.product_id.model_file).decode('utf-8'), # 'glb_url': cnc.product_id.glb_url, 'part_name': cnc.product_id.part_name, 'part_number': cnc.product_id.part_number, 'machining_drawings': base64.b64encode(cnc.product_id.machining_drawings).decode( 'utf-8') if cnc.product_id.machining_drawings else '', 'machining_drawings_name': cnc.product_id.machining_drawings_name, 'machining_drawings_mimetype': cnc.product_id.machining_drawings_mimetype, # 'model_id': cnc.product_id.model_id, } # 打印出除了 model_file 之外的所有键值对 for key, value in res.items(): if key != 'model_file': logging.info('%s: %s' % (key, value)) configsettings = self.env['res.config.settings'].get_values() config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key']) url = '/api/intelligent_programming/create' config_url = configsettings['sf_url'] + url res['token'] = configsettings['token'] # res_str = json.dumps(res) ret = requests.post(config_url, json={}, data=res, headers=config_header) ret = ret.json() logging.info('fetchCNC-ret:%s' % ret) if ret['status'] == 1: self.write( {'programming_no': ret['programming_no'], 'programming_state': '编程中', 'work_state': '编程中'}) # 生成编程记录 self.programming_record_ids.create({ 'number': len(self.programming_record_ids) + 1, 'production_id': self.id, 'reason': '首次下发', 'programming_method': False, 'current_programming_count': False, 'target_production_id': False, 'apply_time': fields.Datetime.now(), 'send_time': False, }) else: raise UserError(ret['message']) except Exception as e: logging.info('fetchCNC error:%s' % e) raise UserError("cnc程序获取编程单失败,请联系管理员")