diff --git a/sf_base/models/base.py b/sf_base/models/base.py index a6e1d4cc..75d0d6c5 100644 --- a/sf_base/models/base.py +++ b/sf_base/models/base.py @@ -77,7 +77,7 @@ class MachineTool(models.Model): b_axis = fields.Integer('B轴') c_axis = fields.Integer('C轴') remark = fields.Text('备注') - is_binding = fields.Boolean('是否绑定机床', default=False) + is_binding = fields.Boolean('是否绑定工作中心', default=False) precision = fields.Float('加工精度') control_system_id = fields.Many2one('sf.machine.control_system', string="控制系统") diff --git a/sf_bf_connect/controllers/controllers.py b/sf_bf_connect/controllers/controllers.py index 5227592f..4e9e44aa 100644 --- a/sf_bf_connect/controllers/controllers.py +++ b/sf_bf_connect/controllers/controllers.py @@ -8,7 +8,7 @@ from odoo.http import request class Sf_Bf_Connect(http.Controller): - @http.route('/api/bfm_process_order/list', type='http', auth='none', methods=['GET', 'POST'], csrf=False, + @http.route('/api/bfm_process_order/list', type='http', auth='sf_token', methods=['GET', 'POST'], csrf=False, cors="*") def get_bfm_process_order_list(self, **kw): """ @@ -44,9 +44,7 @@ class Sf_Bf_Connect(http.Controller): # else: product = request.env['product.template'].sudo().product_create(product_id, item, order_id, kw['order_number'], i) - # order_id.with_user(request.env.ref("base.user_admin")).sale_order_create_line(product, item) - logging.info('order_id:%s' % order_id) - logging.info('product:%s' % product) + i += 1 bom_data = request.env['mrp.bom'].with_user(request.env.ref("base.user_admin")).get_bom(product) logging.info('bom_data:%s' % bom_data) if bom_data: @@ -102,7 +100,6 @@ class Sf_Bf_Connect(http.Controller): product_bom_purchase.with_user(request.env.ref("base.user_admin")).bom_create_line_has( purchase_embryo) order_id.with_user(request.env.ref("base.user_admin")).sale_order_create_line(product, item) - i += 1 res['factory_order_no'] = order_id.name except Exception as e: logging.info('get_bfm_process_order_list error:%s' % e) diff --git a/sf_bf_connect/models/http.py b/sf_bf_connect/models/http.py index 23c66406..281c820e 100644 --- a/sf_bf_connect/models/http.py +++ b/sf_bf_connect/models/http.py @@ -34,7 +34,7 @@ class Http(models.AbstractModel): raise AuthenticationError('无效的token') timestamp_str = int(time.time()) # 设置API接口请求时间,不能超过5秒 - deltime = datetime.timedelta(seconds=5) + deltime = datetime.timedelta(seconds=60) if abs(int(datas['HTTP_TIMESTAMP'])-timestamp_str) > deltime.seconds: raise AuthenticationError('请求已过期') # 获得sha1_str加密字符串 diff --git a/sf_dlm/__manifest__.py b/sf_dlm/__manifest__.py index 27518d9f..1e1f979b 100644 --- a/sf_dlm/__manifest__.py +++ b/sf_dlm/__manifest__.py @@ -10,9 +10,10 @@ """, 'category': 'sf', 'website': 'https://www.sf.jikimo.com', - 'depends': ['mrp', 'base', 'sf_manufacturing', 'web_widget_model_viewer', 'purchase', 'mrp_subcontracting'], + 'depends': ['mrp', 'base', 'sf_manufacturing', 'web_widget_model_viewer', 'purchase', 'mrp_subcontracting', 'uom'], 'data': [ 'data/product_data.xml', + 'data/uom_data.xml', 'views/product_template_view.xml' ], 'demo': [ diff --git a/sf_dlm/data/uom_data.xml b/sf_dlm/data/uom_data.xml new file mode 100644 index 00000000..de698554 --- /dev/null +++ b/sf_dlm/data/uom_data.xml @@ -0,0 +1,11 @@ + + + + + + 立方毫米 + + 1000 + bigger + + diff --git a/sf_dlm/models/product_template.py b/sf_dlm/models/product_template.py index 885e0c26..41d134a3 100644 --- a/sf_dlm/models/product_template.py +++ b/sf_dlm/models/product_template.py @@ -3,9 +3,10 @@ from odoo.exceptions import ValidationError import logging import base64 import os -from OCC.Extend.DataExchange import read_step_file, write_stl_file +# from OCC.Extend.DataExchange import read_step_file, write_stl_file from odoo.modules import get_resource_path + class ResProductTemplate(models.Model): _inherit = 'product.template' @@ -34,7 +35,16 @@ class ResProductTemplate(models.Model): materials_type_id = fields.Many2one('sf.materials.model', string='材料型号') single_manufacturing = fields.Boolean(string="单个制造") upload_model_file = fields.Many2many('ir.attachment', 'upload_model_file_attachment_ref', string='上传模型文件') - model_file = fields.Binary('模型文件') + model_code = fields.Char('模型编码') + + 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') + + # model_file = fields.Binary('模型文件') # 胚料的库存路线设置 # def _get_routes(self, route_type): @@ -72,16 +82,18 @@ class ResProductTemplate(models.Model): item['model_height'] + model_type.embryo_tolerance), 'model_type_id': 1, # 'model_machining_precision': item['model_machining_precision'], - 'model_processing_panel': 'A', + 'model_processing_panel': 'R', 'model_machining_precision': '±0.10mm', + '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': base64.b64decode(item['model_file']), + 'model_file': '' if not item['model_file'] else base64.b64decode(item['model_file']), 'model_name': attachment.name, 'upload_model_file': [(6, 0, [attachment.id])], # 'single_manufacturing': True, + 'tracking': 'serial', 'list_price': item['price'], # 'categ_id': self.env.ref('sf_dlm.product_category_finished_sf').id, 'materials_id': self.env['sf.production.materials'].search( @@ -94,18 +106,17 @@ class ResProductTemplate(models.Model): # [('process_encode', '=', item['process_parameters_code'])]).id, 'model_remark': item['remark'], 'default_code': '%s-%s' % (order_number, i), - #'barcode': item['barcode'], + # 'barcode': item['barcode'], 'active': True, # 'route_ids': self._get_routes('') } copy_product_id.sudo().write(vals) - print(len(copy_product_id.model_file)) - product_id.product_tmpl_id.active = False + # product_id.product_tmpl_id.active = False return copy_product_id def attachment_create(self, name, data): attachment = self.env['ir.attachment'].create({ - 'datas': base64.b64decode(data), + 'datas': base64.b64decode(data), 'type': 'binary', 'description': '模型文件', 'name': name @@ -125,8 +136,9 @@ class ResProductTemplate(models.Model): logging.info('no_bom_copy_product_supplier-vals:%s' % supplier) vals = { 'name': '%s %s %s %s * %s * %s' % ( - order_id.name, materials_id.name, materials_type_id.name, item['model_long'], item['model_width'], - item['model_height']), + order_id.name, 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, @@ -158,32 +170,32 @@ class ResProductTemplate(models.Model): logging.info('no_bom_copy_product_id-seller_ids-vals:%s' % no_bom_copy_product_id.seller_ids) no_bom_copy_product_id.write(vals) logging.info('no_bom_copy_product_id-vals:%s' % vals) - product_id.product_tmpl_id.active = False + # product_id.product_tmpl_id.active = False return no_bom_copy_product_id - @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] - item.model_name = file_attachment_id.name - # 附件路径 - report_path = file_attachment_id._full_path(file_attachment_id.store_fname) - shapes = read_step_file(report_path) - output_file = get_resource_path('sf_dlm', 'static/file', 'out.stl') - write_stl_file(shapes, output_file, 'binary', 0.03, 0.5) - # 转化为glb - output_glb_file = get_resource_path('sf_dlm', 'static/file', 'out.glb') - util_path = get_resource_path('sf_dlm', 'static/util') - cmd = 'python %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 + # @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] + # item.model_name = file_attachment_id.name + # # 附件路径 + # report_path = file_attachment_id._full_path(file_attachment_id.store_fname) + # shapes = read_step_file(report_path) + # output_file = get_resource_path('sf_dlm', 'static/file', 'out.stl') + # write_stl_file(shapes, output_file, 'binary', 0.03, 0.5) + # # 转化为glb + # output_glb_file = get_resource_path('sf_dlm', 'static/file', 'out.glb') + # util_path = get_resource_path('sf_dlm', 'static/util') + # cmd = 'python %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 class ResMrpBom(models.Model): @@ -244,8 +256,6 @@ class ResMrpBom(models.Model): # 匹配bom def get_bom(self, product): - logging.info('get_bom-product:%s' % product) - logging.info('get_bom-product:%s' % product.materials_type_id.id) embryo_has = self.env['product.product'].search( [('categ_id.type', '=', '胚料'), ('materials_type_id', '=', product.materials_type_id.id), ('length', '>', product.length), ('width', '>', product.width), @@ -257,7 +267,7 @@ class ResMrpBom(models.Model): logging.info('get_bom-vals:%s' % embryo_has) if embryo_has: rate_of_waste = ((embryo_has.volume - product.model_volume) % embryo_has.volume) * 100 - if rate_of_waste >= 20: + if rate_of_waste <= 20: return embryo_has else: return diff --git a/sf_dlm/views/product_template_view.xml b/sf_dlm/views/product_template_view.xml index c563f728..652b05a3 100644 --- a/sf_dlm/views/product_template_view.xml +++ b/sf_dlm/views/product_template_view.xml @@ -6,13 +6,13 @@ product.template - - - - + + + + - + @@ -36,18 +36,31 @@ - - - - - - - - - - - + + + diff --git a/sf_manufacturing/__manifest__.py b/sf_manufacturing/__manifest__.py index 2f73f417..e51cc99c 100644 --- a/sf_manufacturing/__manifest__.py +++ b/sf_manufacturing/__manifest__.py @@ -10,15 +10,15 @@ """, 'category': 'sf', 'website': 'https://www.sf.jikimo.com', - 'depends': ['mrp', 'sf_base', 'maintenance'], + 'depends': ['mrp', 'sf_base', 'maintenance', 'sf_mrs_connect'], 'data': [ 'security/group_security.xml', 'security/ir.model.access.csv', 'report/tray_report.xml', 'views/mrp_maintenance_views.xml', 'views/mrp_routing_workcenter_view.xml', - 'views/mrp_workorder_view.xml', 'views/mrp_workcenter_views.xml', + 'views/mrp_workorder_view.xml', 'views/tray_view.xml', 'views/model_type_view.xml', diff --git a/sf_manufacturing/models/__init__.py b/sf_manufacturing/models/__init__.py index b439701c..419dee46 100644 --- a/sf_manufacturing/models/__init__.py +++ b/sf_manufacturing/models/__init__.py @@ -6,6 +6,9 @@ from . import mrp_routing_workcenter from . import mrp_workorder from . import model_type from . import stock +from . import res_user + + diff --git a/sf_manufacturing/models/model_type.py b/sf_manufacturing/models/model_type.py index ecc4b7af..bdc5fc78 100644 --- a/sf_manufacturing/models/model_type.py +++ b/sf_manufacturing/models/model_type.py @@ -6,7 +6,7 @@ class ModelType(models.Model): _description = '模型类型' name = fields.Char('名称') - embryo_tolerance = fields.Integer('胚料的容余量') + embryo_tolerance = fields.Boolean('胚料的容余量', default=False) routing_tmpl_ids = fields.One2many('sf.model.type.routing.sort', 'model_type_id', '工序模板') diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 036bf969..c1a252f2 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -1,5 +1,11 @@ # -*- coding: utf-8 -*- -from odoo import api, fields, models, _ +from odoo import api, fields, models,_ + + +class ResProducTemplate_Production(models.Model): + _inherit = 'product.template' + + model_file = fields.Binary('模型文件') class MrpProduction(models.Model): @@ -9,8 +15,7 @@ class MrpProduction(models.Model): tray_ids = fields.One2many('sf.tray', 'production_id', string="托盘") maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests") request_ids = fields.One2many('maintenance.request', 'production_id') - # model_file = fields.Binary('模型文件', related='product_id.model_file') - # model_information = fields.Char('模型信息', related='product_id.model_information') + model_file = fields.Binary('模型文件', related='product_id.model_file') @api.depends('request_ids') def _compute_maintenance_count(self): @@ -131,9 +136,6 @@ class MrpProduction(models.Model): 'location_src_id': production.location_src_id.id, 'location_dest_id': production.location_dest_id.id, 'bom_id': production.bom_id.id, - 'model_file': base64.b64decode(production.product_id.model_file), - 'model_information': '%s/%s' % ( - production.product_id.model_processing_panel, production.product_id.materials_id.name), 'date_deadline': production.date_deadline, 'date_planned_start': production.date_planned_start, 'date_planned_finished': production.date_planned_finished, diff --git a/sf_manufacturing/models/mrp_workcenter.py b/sf_manufacturing/models/mrp_workcenter.py index db7db216..5a9c9d91 100644 --- a/sf_manufacturing/models/mrp_workcenter.py +++ b/sf_manufacturing/models/mrp_workcenter.py @@ -7,16 +7,18 @@ class ResWorkcenter(models.Model): _inherit = "mrp.workcenter" machine_tool_id = fields.Many2one('sf.machine_tool', '机床') - @api.onchange('machine_tool_id') - def get_machine_tool_is_binding(self): - print('1111111') - for item in self: - item.machine_tool_id.is_binding = False + users_ids = fields.Many2many("res.users", 'users_workcenter') equipment_ids = fields.One2many( 'maintenance.equipment', 'workcenter_id', string="Maintenance Equipment", check_company=True) + @api.onchange('machine_tool_id') + def update_machine_tool_is_binding(self): + self.machine_tool_id.is_binding = True + + + def action_work_order(self): if not self.env.context.get('desktop_list_view', False): action = self.env["ir.actions.actions"]._for_xml_id("sf_manufacturing.mrp_workorder_action_tablet") diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index a478438f..a5e8cba6 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -4,6 +4,7 @@ import math import requests import logging import base64 +import hashlib # import subprocess from datetime import datetime from dateutil.relativedelta import relativedelta @@ -19,6 +20,7 @@ class ResMrpWorkOrder(models.Model): _order = 'sequence' workcenter_id = fields.Many2one('mrp.workcenter', required=False) + users_ids = fields.Many2many("res.users", 'users_workorder', related="workcenter_id.users_ids") processing_panel = fields.Char('加工面') sequence = fields.Integer(string='工序') routing_type = fields.Selection([ @@ -29,8 +31,26 @@ class ResMrpWorkOrder(models.Model): ('后置三元质量检测', '后置三元质量检测'), ('解除装夹', '解除装夹'), ], string="工序类型") + + @api.onchange('users_ids') + def get_user_permissions(self): + uid = self.env.uid + for workorder in self: + if workorder.users_ids: + list_user_id = [] + for item in workorder.users_ids: + list_user_id.append(item.id) + if uid in list_user_id: + workorder.user_permissions = True + else: + workorder.user_permissions = False + else: + workorder.user_permissions = False + + user_permissions = fields.Boolean('用户权限', compute='get_user_permissions') programming_no = fields.Char('编程单号') - is_programming = fields.Boolean('是否编程', default=False) + work_state = fields.Char('业务状态') + programming_state = fields.Char('编程状态') cnc_worksheet = fields.Binary( '工作指令', readonly=True) material_center_point = fields.Char(string='配料中心点') @@ -106,7 +126,11 @@ class ResMrpWorkOrder(models.Model): print("(%.2f,%.2f)" % (x, y)) self.material_center_point = ("(%.2f,%.2f,%.2f)" % (x, y, z)) self.X_deviation_angle = jdz - return self.material_center_point + # 将补偿值写入CNC加工工单 + workorder = self.env['mrp.workorder'].browse(self.ids) + work = workorder.production_id.workorder_ids + work.compensation_value_x = eval(self.material_center_point)[0] + work.compensation_value_y = eval(self.material_center_point)[1] def json_workorder_str(self, k, production, route): workorders_values_str = [0, '', { @@ -116,6 +140,7 @@ class ResMrpWorkOrder(models.Model): 'name': route.route_workcenter_id.name, 'processing_panel': k, 'routing_type': route.routing_type, + 'work_state': '' if not route.routing_type == '获取CNC加工程序' else '待发起', 'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids), 'date_planned_start': False, 'date_planned_finished': False, @@ -233,35 +258,72 @@ class ResMrpWorkOrder(models.Model): else: return True + # def fetchCNCing(self): + # return None + # cnc程序获取 def fetchCNC(self): - cnc = self.env['mrp.workorder'].search( - [('routing_type', '=', 'CNC加工'), ('production_id', '=', self.production_id.id)], limit=1) - res = {'model_code': cnc.product_id.barcode, 'production_no': self.production_id.name, - 'machine_tool_code': cnc.workcenter_id.machine_tool_id.code, - 'material_code': cnc.env['sf.production.materials'].search( - [('id', '=', cnc.product_id.materials_id.id)]).materials_no, - 'material_type_code': cnc.env['sf.materials.model'].search( - [('id', '=', cnc.product_id.materials_type_id.id)]).materials_no, - 'machining_precision': cnc.product_id.model_machining_precision, - 'embryo_long': cnc.product_id.bom_ids.bom_line_ids.product_id.length, - 'embryo_height': cnc.product_id.bom_ids.bom_line_ids.product_id.height, - 'embryo_width': cnc.product_id.bom_ids.bom_line_ids.product_id.width, - 'order_no': cnc.production_id.origin, - 'user': self.env.user.name, - 'model_file': base64.b64encode(cnc.product_id.model_file).decode('utf-8') - } - logging.info('res:%s' % res) - 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_str = json.dumps(res) - ret = requests.post(config_url, json={}, data=res, headers=config_header) - ret = ret.json() - result = json.loads(ret['result']) - if result['status'] == 1: - return self.write({'programming_no': result['programming_no'], 'is_programming': True}) + try: + cnc = self.env['mrp.workorder'].search( + [('routing_type', '=', 'CNC加工'), ('production_id', '=', self.production_id.id)], limit=1) + logging.info('fetchCNC-cnc:%s' % cnc) + # if cnc.product_id.upload_model_file: + # logging.info('fetchCNC-upload_model_file:%s' % cnc.product_id.upload_model_file) + # attachments = cnc.product_id.upload_model_file[0] + # logging.info('fetchCNC-attachment1:%s' % attachments) + # logging.info('fetchCNC-attachment1:%s' % cnc.product_id.upload_model_file[0]) + # logging.info('fetchCNC-attachment2:%s' % cnc.product_id.upload_model_file[0].datas) + # logging.info('fetchCNC-attachment:%s' % attachments.datas) + # base64_data = base64.b64encode(attachments.datas) + # logging.info('fetchCNC-attachment1:%s' % attachments) + # base64_datas = base64_data.decode('utf-8') + # model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest() + # logging.info('fetchCNC-model_code:%s' % model_code) + logging.info('fetchCNC-model_code1:%s' % cnc.product_id.model_code) + res = {'model_code': '' if not cnc.product_id.model_code else cnc.product_id.model_code, + 'production_no': self.production_id.name, + 'machine_tool_code': cnc.workcenter_id.machine_tool_id.code, + 'material_code': cnc.env['sf.production.materials'].search( + [('id', '=', cnc.product_id.materials_id.id)]).materials_no, + 'material_type_code': cnc.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': cnc.product_id.model_machining_precision, + 'embryo_long': cnc.product_id.bom_ids.bom_line_ids.product_id.length, + 'embryo_height': cnc.product_id.bom_ids.bom_line_ids.product_id.height, + 'embryo_width': cnc.product_id.bom_ids.bom_line_ids.product_id.width, + 'order_no': cnc.production_id.origin, + 'user': self.env.user.name, + 'model_file': '' if not cnc.product_id.model_file else base64.b64encode( + cnc.product_id.model_file).decode('utf-8') + } + logging.info('res:%s' % res) + 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_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': '编程中'}) + else: + logging.info('fetchCNC-error:%s' % cnc) + raise UserError('行业资源库解析失败') + except Exception as e: + logging.info('fetchCNC error:%s' % e) + raise UserError(e) + + # return { + # 'name': _("工单"), + # 'view_mode': 'form', + # 'res_model': 'mrp.workorder', + # 'res_id': self.id, + # 'type': 'ir.actions.act_window', + # 'target': 'new' + # } def json_workorder_str1(self, k, production, route): workorders_values_str = [0, '', { @@ -271,6 +333,7 @@ class ResMrpWorkOrder(models.Model): 'name': route.route_workcenter_id.name, 'processing_panel': k, 'routing_type': route.routing_type, + 'work_state': '' if not route.routing_type == '获取CNC加工程序' else '待发起', 'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids), 'date_planned_start': False, 'date_planned_finished': False, @@ -349,44 +412,73 @@ class CNCprocessing(models.Model): workorder_id = fields.Many2one('mrp.workorder', string="工单") # mrs下发编程单创建CNC加工 - def cnc_processing_create(self, obj): - workorder = self.env['mrp.workorder'].search([('production_id.name', '=', obj['production_order_no']), - ('processing_panel', '=', obj['processing_panel']), - ('routing_type', '=', 'CNC加工')]) - vals = { - 'workorder_id': workorder.id, - 'sequence_number': obj['sequence_number'], - 'program_name': obj['program_name'], - 'cutting_tool_name': obj['cutting_tool_name'], - 'cutting_tool_no': obj['cutting_tool_no'], - 'processing_type': obj['processing_type'], - 'margin_x_y': obj['margin_x_y'], - 'margin_z': obj['margin_z'], - 'depth_of_processing_z': obj['depth_of_processing_z'], - 'cutting_tool_extension_length': obj['cutting_tool_extension_length'], - 'cutting_tool_handle_type': obj['cutting_tool_handle_type'], - 'estimated_processing_time': obj['estimated_processing_time'], - 'remark': obj['remark'] - } - return self.env['sf.cnc.processing'].create(vals) + def cnc_processing_create(self, cnc_workorder, ret): + for obj in ret['programming_list']: + workorder = self.env['mrp.workorder'].search([('production_id.name', '=', ret['production_order_no']), + ('processing_panel', '=', obj['processing_panel']), + ('routing_type', '=', 'CNC加工')]) + cnc_processing = self.env['sf.cnc.processing'].create({ + 'workorder_id': workorder.id, + 'sequence_number': obj['sequence_number'], + 'program_name': obj['program_name'], + 'cutting_tool_name': obj['cutting_tool_name'], + 'cutting_tool_no': obj['cutting_tool_no'], + 'processing_type': obj['processing_type'], + 'margin_x_y': obj['margin_x_y'], + 'margin_z': obj['margin_z'], + 'depth_of_processing_z': obj['depth_of_processing_z'], + 'cutting_tool_extension_length': obj['cutting_tool_extension_length'], + 'cutting_tool_handle_type': obj['cutting_tool_handle_type'], + 'estimated_processing_time': obj['estimated_processing_time'], + 'remark': obj['remark'] + }) + self.get_cnc_processing_file(ret['folder_name'], cnc_processing) + cnc_workorder.state = 'done' + cnc_workorder.work_state = '已编程' + cnc_workorder.programming_state = '已编程' + cnc_workorder.time_ids.date_end = datetime.now() + + def get_cnc_processing_file(self, folder_name, cnc_processing): + logging.info('folder_name:%s' % folder_name) + serverdir = os.path.join('/', folder_name, 'return', cnc_processing.processing_panel) + logging.info('serverdir:%s' % serverdir) + for root, dirs, files in os.walk(server_dir): + for f in files: + logging.info('f:%s' % f) + if os.path.splitext(f)[1] == ".pdf": + full_path = os.path.join(server_dir, root, f) + logging.info('pdf:%s' % full_path) + if full_path != False: + if not cnc_processing.workorder_id.cnc_worksheet: + cnc_processing.workorder_id.cnc_worksheet = base64.b64encode( + open(full_path, 'rb').read()) + else: + if cnc_processing.program_name == f.split('.')[0]: + cnc_file_path = os.path.join(server_dir, root, f) + logging.info('cnc_file_path:%s' % cnc_file_path) + cnc_processing.with_user(request.env.ref("base.user_admin")).write_file(cnc_file_path, + cnc_processing) # 创建附件(nc文件) def attachment_create(self, name, data): attachment = self.env['ir.attachment'].create({ 'datas': base64.b64encode(data), 'type': 'binary', + 'public': True, 'description': '程序文件', 'name': name }) return attachment # 将FTP的nc文件下载到临时目录 - def download_file_tmp(self, model_code, processing_panel): - remotepath = os.path.join('/', model_code, 'return', processing_panel) - serverdir = os.path.join('/tmp', model_code, 'return', processing_panel) - ftp = FtpController() - ftp.download_file_tree(remotepath, serverdir) - return serverdir + def download_file_tmp(self, production_no, processing_panel): + remotepath = os.path.join('/', production_no, 'return', processing_panel) + serverdir = os.path.join('/tmp', production_no, 'return', processing_panel) + ftp_resconfig = self.env['res.config.settings'].get_values() + ftp = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']), ftp_resconfig['ftp_user'], + ftp_resconfig['ftp_password']) + download_state = ftp.download_file_tree(remotepath, serverdir) + return download_state # 将nc文件存到attach的datas里 def write_file(self, nc_file_path, cnc): diff --git a/sf_manufacturing/models/res_user.py b/sf_manufacturing/models/res_user.py new file mode 100644 index 00000000..d79313db --- /dev/null +++ b/sf_manufacturing/models/res_user.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +from odoo import SUPERUSER_ID, _, api, fields, models, registry + +class Users(models.Model): + _inherit = 'res.users' + + workcenter_ids = fields.Many2many("mrp.workcenter", 'users_workcenter') \ No newline at end of file diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 487f69ed..7adf4004 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -66,25 +66,24 @@ class StockRule(models.Model): list2 = [] for item in procurements: num = int(item[0].product_qty) - product = self.env['product.template'].search( - ["&", ("name", '=', item[0].product_id.display_name), ('single_manufacturing', '!=', False)]) - if product: + + product = self.env['product.product'].search( + [("id", '=', item[0].product_id.id)]) + product_tmpl = self.env['product.template'].search( + ["&", ("id", '=', product.product_tmpl_id.id), ('single_manufacturing', "!=", False)]) + if product_tmpl: if num > 1: for no in range(1, num + 1): Procurement = namedtuple('Procurement', ['product_id', 'product_qty', 'product_uom', 'location_id', 'name', 'origin', 'company_id', - 'values', 'model_file', - 'model_information']) + 'values']) s = Procurement(product_id=item[0].product_id, product_qty=1.0, product_uom=item[0].product_uom, location_id=item[0].location_id, name=item[0].name, origin=item[0].origin, company_id=item[0].company_id, values=item[0].values, - model_file=base64.b64decode(item[0].product_id.model_file), - model_information='%s/%s' % (item[0].product_id.model_processing_panel, - item[0].product_id.materials_id.name), ) item1 = list(item) item1[0] = s diff --git a/sf_manufacturing/models/tray.py b/sf_manufacturing/models/tray.py index bdea35c4..0fdb8c30 100644 --- a/sf_manufacturing/models/tray.py +++ b/sf_manufacturing/models/tray.py @@ -3,7 +3,7 @@ import base64 from io import BytesIO from odoo import api, fields, models, SUPERUSER_ID, _ -# from pystrich.code128 import Code128Encoder +#from pystrich.code128 import Code128Encoder class Tray(models.Model): diff --git a/sf_manufacturing/views/model_type_view.xml b/sf_manufacturing/views/model_type_view.xml index 58d1bf94..58fd70be 100644 --- a/sf_manufacturing/views/model_type_view.xml +++ b/sf_manufacturing/views/model_type_view.xml @@ -31,7 +31,7 @@
- + diff --git a/sf_manufacturing/views/mrp_workcenter_views.xml b/sf_manufacturing/views/mrp_workcenter_views.xml index d500e3b6..6c6e73e6 100644 --- a/sf_manufacturing/views/mrp_workcenter_views.xml +++ b/sf_manufacturing/views/mrp_workcenter_views.xml @@ -24,14 +24,16 @@ - + mrp.workcenter.view.kanban.inherit.mrp.workorder mrp.workcenter -