diff --git a/sf_bf_connect/controllers/controllers.py b/sf_bf_connect/controllers/controllers.py index 8c901610..607aa5c2 100644 --- a/sf_bf_connect/controllers/controllers.py +++ b/sf_bf_connect/controllers/controllers.py @@ -111,11 +111,12 @@ class Sf_Bf_Connect(http.Controller): res['message'] = '该订单模型的材料型号在您分配的工厂里暂未设置获取方式和供应商,请先配置再进行分配' request.cr.rollback() return json.JSONEncoder().encode(res) - # 产品配置bom - product_bom_purchase = request.env['mrp.bom'].with_user( - request.env.ref("base.user_admin")).bom_create(product, 'normal', False) - product_bom_purchase.with_user(request.env.ref("base.user_admin")).bom_create_line_has( - purchase_embryo) + else: + # 产品配置bom + product_bom_purchase = request.env['mrp.bom'].with_user( + request.env.ref("base.user_admin")).bom_create(product, 'normal', False) + 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 diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py index e42bb1c7..86d18009 100644 --- a/sf_manufacturing/controllers/controllers.py +++ b/sf_manufacturing/controllers/controllers.py @@ -511,7 +511,6 @@ class Manufacturing_Connect(http.Controller): rfid_code = ret[f'RfidCode{i}'] logging.info('RfidCode:%s' % rfid_code) domain = [ - ('feeder_station_start_id.name', '=', ret['DeviceId']), ('workorder_id.rfid_code', '=', rfid_code), ('status', '=', '待下发'), ('type', '=', '下产线') diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index a96f3383..405fd1d5 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -166,26 +166,30 @@ class MrpProduction(models.Model): if quick_order: programme_way = 'manual operation' try: - res = {'model_code': '' if not cnc.product_id.model_code else cnc.product_id.model_code, - 'production_no': cnc.name, - 'machine_tool_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': 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.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') - } - logging.info('res:%s' % res) + res = { + 'production_no': cnc.name, + 'machine_tool_code': '', + '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': 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.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') + } + # 打印出除了 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' @@ -263,14 +267,15 @@ class MrpProduction(models.Model): # 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心; def _create_workorder3(self): - programming_no = None - product_id_new = None + # production_names = [production.name for production in self if production.product_id.categ_id.type == '成品'] + # programming_no = None + # product_first = None for production in self: if not production.bom_id or not production.product_id: continue workorders_values = [] - if product_id_new is None: - product_id_new = production.product_id + # if product_first is None: + # product_first = production.product_id product_qty = production.product_uom_id._compute_quantity(production.product_qty, production.bom_id.product_uom_id) @@ -295,14 +300,15 @@ class MrpProduction(models.Model): 'state': 'pending', }] if production.product_id.categ_id.type == '成品': - if programming_no is None: - production.fetchCNC() - programming_no = production.programming_no - else: - if production.product_id == product_id_new: - if not production.programming_no: - production.write({'programming_no': programming_no, 'programming_state': '编程中'}) - + production.fetchCNC() + # 第二期同一个产品多个制造订单对应一个编程单和模型库 + # if programming_no is None: + # production.fetchCNC(production_names) + # programming_no = production.programming_no + # else: + # if production.product_id == product_first: + # if not production.programming_no: + # production.write({'programming_no': programming_no, 'programming_state': '编程中'}) # 根据加工面板的面数及对应的工序模板生成工单 i = 0 processing_panel_len = len(production.product_id.model_processing_panel.split(',')) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 704b0ec5..e10db743 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -493,9 +493,15 @@ class ResMrpWorkOrder(models.Model): return workorders_values_str def _json_workpiece_delivery_list(self, production): + up_route = self.env['sf.agv.task.route'].search([('route_type', '=', '上产线')], limit=1, order='id asc') + down_route = self.env['sf.agv.task.route'].search([('route_type', '=', '下产线')], limit=1, order='id asc') return [ - [0, '', {'production_id': production.id, 'type': '上产线'}], - [0, '', {'production_id': production.id, 'type': '下产线'}]] + [0, '', {'production_id': production.id, 'type': '上产线', 'route_id': up_route.id, + 'feeder_station_start_id': up_route.start_site_id.id, + 'feeder_station_destination_id': up_route.end_site_id.id}], + [0, '', {'production_id': production.id, 'type': '下产线', 'route_id': down_route.id, + 'feeder_station_start_id': down_route.start_site_id.id, + 'feeder_station_destination_id': down_route.end_site_id.id}]] # 拼接工单对象属性值(表面工艺) def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id): @@ -827,16 +833,13 @@ class ResMrpWorkOrder(models.Model): raise UserError("请对前置三元检测定位参数进行计算定位") if not record.rfid_code: raise UserError("请扫RFID码进行绑定") - record.workpiece_delivery_ids[0].write({'status': '待下发'}) record.process_state = '待加工' # record.write({'process_state': '待加工'}) record.production_id.process_state = '待加工' - if record.routing_type == 'CNC加工': record.process_state = '待解除装夹' # record.write({'process_state': '待加工'}) record.production_id.process_state = '待解除装夹' - if record.routing_type == '解除装夹': ''' 记录结束时间 @@ -904,13 +907,17 @@ class ResMrpWorkOrder(models.Model): # 根据中控系统提供的检测文件地址去ftp里对应的制造订单里获取 def get_detection_file(self, workorder, reportPath): - if reportPath.startswith('/'): - reportPath = reportPath[4:] - serverdir = os.path.join('/tmp', reportPath) + # if reportPath.startswith('/'): + # reportPath = reportPath[4:] + # serverdir = os.path.join('/tmp', reportPath) + serverdir = '/tmp' + reportPath logging.info('get_detection_file-serverdir:%s' % serverdir) serverdir_prefix = os.path.dirname(serverdir) + logging.info('serverdir_prefix-serverdir:%s' % serverdir_prefix) for root, dirs, files in os.walk(serverdir_prefix): for filename in files: + logging.info('filename:%s' % filename) + logging.info('reportPath:%s' % os.path.basename(reportPath)) if filename == os.path.basename(reportPath): report_file_path = os.path.join(root, filename) logging.info('get_detection_file-report_file_path:%s' % report_file_path) @@ -945,6 +952,8 @@ class CNCprocessing(models.Model): # mrs下发编程单创建CNC加工 def cnc_processing_create(self, cnc_workorder, ret, program_path, program_path_tmp): + # 注释代码为第二期同一产品多个编程单需求 + # cnc_processing = None for obj in ret['programming_list']: workorder = self.env['mrp.workorder'].search([('production_id.name', '=', ret['production_order_no']), ('processing_panel', '=', obj['processing_panel']), @@ -979,10 +988,28 @@ class CNCprocessing(models.Model): item.is_cnc_program_down = True if item.workorder_id.state == 'waiting': item.workorder_id.state = 'ready' + # return cnc_processing # cnc_workorder.time_ids.date_end = datetime.now() # cnc_workorder.button_finish() + def _json_cnc_processing(self, obj): + cnc_processing_str = [0, 0, { + '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 cnc_processing_str + # 根据程序名和加工面匹配到ftp里对应的Nc程序名,可优化为根据cnc_processing.program_path进行匹配 def get_cnc_processing_file(self, serverdir, cnc_processing, program_path): logging.info('serverdir:%s' % serverdir) @@ -1014,7 +1041,6 @@ class CNCprocessing(models.Model): # 将FTP的nc文件下载到临时目录 def download_file_tmp(self, production_no, processing_panel): remotepath = os.path.join('/NC', 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']) @@ -1236,8 +1262,8 @@ class WorkPieceDelivery(models.Model): same_route_id = item.route_id.id if item.route_id.id != same_route_id: is_not_route += 1 - else: - raise UserError('请选择【任务路线】再进行配送') + # else: + # raise UserError('请选择【任务路线】再进行配送') if production_type != item.type: raise UserError('请选择类型为%s的制造订单进行配送' % production_type) if down_status != item.status: @@ -1280,7 +1306,7 @@ class WorkPieceDelivery(models.Model): 'default_type': production_type, }} else: - if self.type == '运送空料架': + if production_type == '运送空料架': raise UserError("您所选择的【任务路线】的【终点接驳站】已占用,请在该接驳站空闲时进行配送") else: raise UserError( @@ -1317,30 +1343,33 @@ class WorkPieceDelivery(models.Model): feeder_station_destination = None route_id = None for item in self: - delivery_Arr.append(item.name) + if route_id is None: + route_id = item.route_id.id + if feeder_station_start is None: + feeder_station_start = item.feeder_station_start_id + if feeder_station_destination is None: + feeder_station_destination = item.feeder_station_destination_id if item.type in ['上产线', '下产线']: - if route_id is None: - route_id = item.route_id.id - if feeder_station_start is None: - feeder_station_start = item.feeder_station_start_id.name - if feeder_station_destination is None: - feeder_station_destination = item.feeder_station_destination_id.name item.route_id = route_id + item.feeder_station_start_id = feeder_station_start.id + item.feeder_station_destination_id = feeder_station_destination.id + delivery_Arr.append(item.name) else: self = self.create( {'name': self.env['ir.sequence'].next_by_code('sf.workpiece.delivery'), 'route_id': self.route_id.id, 'feeder_station_start_id': self.feeder_station_start_id.id, 'feeder_station_destination_id': self.feeder_station_destination_id.id}) + delivery_Arr.append(self.name) delivery_str = ','.join(map(str, delivery_Arr)) if feeder_station_start is not None: positionCode_Arr.append({ - 'positionCode': feeder_station_start, + 'positionCode': feeder_station_start.name, 'code': '00' }) if feeder_station_destination is not None: positionCode_Arr.append({ - 'positionCode': feeder_station_destination, + 'positionCode': feeder_station_destination.name, 'code': '00' }) res = {'reqCode': delivery_str, 'reqTime': '', 'clientCode': '', 'tokenCode': '', diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 4d07ae1c..3e91e6a3 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -7,6 +7,8 @@ import os from odoo import models, fields, api, _ from odoo.exceptions import ValidationError from odoo.modules import get_resource_path + + from OCC.Extend.DataExchange import read_step_file from OCC.Extend.DataExchange import write_stl_file @@ -179,6 +181,12 @@ class ResProductMo(models.Model): # ('standard_library_id', '=', self.cutting_tool_model_id.id)], # } + # def name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None): + # # if self._context.get('is_sale_order_line'): + # # domain = [('sale_ok', '=', True), ('categ_type', '=', '成品')] + # # return self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid) + # return super(product.template, self)._name_search(name, args, operator, limit, name_get_uid) + @api.onchange('specification_id') def _onchange_specification(self): if self.specification_id: diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv index 1798ba27..22cff848 100644 --- a/sf_manufacturing/security/ir.model.access.csv +++ b/sf_manufacturing/security/ir.model.access.csv @@ -30,7 +30,7 @@ access_mrp_workcenter_group_sf_mrp_user,mrp_workcenter,model_mrp_workcenter,sf_b access_mrp_workcenter_manager,mrp_workcenter,model_mrp_workcenter,sf_base.group_sf_mrp_manager,1,1,1,0 access_mrp_workcenter_productivity_group_sf_mrp_user,mrp_workcenter_productivity,model_mrp_workcenter_productivity,sf_base.group_sf_mrp_user,1,0,0,0 access_mrp_workcenter_productivity_manager,mrp_workcenter_productivity,model_mrp_workcenter_productivity,sf_base.group_sf_mrp_manager,1,1,1,0 -access_sf_workpiece_delivery_group_sf_order_user,sf_workpiece_delivery_group_sf_order_user,model_sf_workpiece_delivery,sf_base.group_sf_order_user,1,1,0,0 +access_sf_workpiece_delivery_group_sf_order_user,sf_workpiece_delivery_group_sf_order_user,model_sf_workpiece_delivery,sf_base.group_sf_order_user,1,1,1,0 access_sf_workpiece_delivery_group_sf_equipment_user,sf_workpiece_delivery_group_sf_equipment_user,model_sf_workpiece_delivery,sf_base.group_sf_equipment_user,1,1,0,0 access_sf_workpiece_delivery_manager,sf_workpiece_delivery,model_sf_workpiece_delivery,sf_base.group_sf_mrp_manager,1,1,0,0 diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 7fdf390d..dce2a68a 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -145,7 +145,6 @@