From 8726f8cac3da3e9d413493aa23d906fae2458f73 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Wed, 17 Jul 2024 15:20:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8A=A5=E5=BA=9F=E5=90=91?= =?UTF-8?q?=E5=AF=BC=EF=BC=9B=E6=B7=BB=E5=8A=A0=E9=87=8D=E6=96=B0=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=88=B6=E9=80=A0=E8=AE=A2=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/__manifest__.py | 1 + sf_manufacturing/models/mrp_production.py | 160 +++++++++++++++--- sf_manufacturing/models/mrp_workorder.py | 124 +------------- sf_manufacturing/models/product_template.py | 4 +- sf_manufacturing/security/ir.model.access.csv | 2 + .../views/mrp_production_addional_change.xml | 6 +- sf_manufacturing/wizard/__init__.py | 1 + sf_manufacturing/wizard/production_wizard.py | 21 +++ .../wizard/production_wizard_views.xml | 34 ++++ sf_sale/models/quick_easy_order.py | 4 +- sf_sale/models/quick_easy_order_old.py | 4 +- 11 files changed, 209 insertions(+), 152 deletions(-) create mode 100644 sf_manufacturing/wizard/production_wizard.py create mode 100644 sf_manufacturing/wizard/production_wizard_views.xml diff --git a/sf_manufacturing/__manifest__.py b/sf_manufacturing/__manifest__.py index 985b87a4..39da4482 100644 --- a/sf_manufacturing/__manifest__.py +++ b/sf_manufacturing/__manifest__.py @@ -19,6 +19,7 @@ 'security/ir.model.access.csv', 'wizard/workpiece_delivery_views.xml', 'wizard/rework_wizard_views.xml', + 'wizard/production_wizard_views.xml', 'views/mrp_views_menus.xml', 'views/stock_lot_views.xml', 'views/mrp_production_addional_change.xml', diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index b965a63e..f0ba816c 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -82,7 +82,7 @@ class MrpProduction(models.Model): part_drawing = fields.Binary('零件图纸') manual_quotation = fields.Boolean('人工编程', default=False, readonly=True) - rework_production = fields.Many2one('mrp.production', string='返工的制造订单') + is_scrap = fields.Boolean('是否报废', default=False) @api.depends( 'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state', @@ -211,7 +211,8 @@ class MrpProduction(models.Model): # 编程单更新 def update_programming_state(self): try: - res = {'programming_no': self.programming_no, 'manufacturing_type': 'rework'} + res = {'programming_no': self.programming_no, + 'manufacturing_type': 'rework' if self.is_scrap is False else 'scrap'} 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']) @@ -486,28 +487,6 @@ class MrpProduction(models.Model): for workorder in production.workorder_ids: workorder.duration_expected = workorder._get_duration_expected() - # 在之前的销售单上重新生成制造订单 - def create_production1_values(self, production): - production_values_str = {'origin': production.origin, - 'product_id': production.product_id.id, - 'product_description_variants': production.product_description_variants, - 'product_qty': production.product_qty, - 'product_uom_id': production.product_uom_id.id, - 'location_src_id': production.location_src_id.id, - 'location_dest_id': production.location_dest_id.id, - 'bom_id': production.bom_id.id, - 'date_deadline': production.date_deadline, - 'date_planned_start': production.date_planned_start, - 'date_planned_finished': production.date_planned_finished, - 'procurement_group_id': False, - 'propagate_cancel': production.propagate_cancel, - 'orderpoint_id': production.orderpoint_id.id, - 'picking_type_id': production.picking_type_id.id, - 'company_id': production.company_id.id, - 'move_dest_ids': production.move_dest_ids.ids, - 'user_id': production.user_id.id} - return production_values_str - # 工单排序 def _reset_work_order_sequence1(self, k): for rec in self: @@ -786,10 +765,6 @@ class MrpProduction(models.Model): } } - # 报废 - def button_scrap_new(self): - return True - # 更新程序 def do_update_program(self): program_production = self @@ -879,6 +854,135 @@ class MrpProduction(models.Model): logging.info('get_new_program error:%s' % e) raise UserError("从云平台获取最新程序失败,请联系管理员") + def recreateManufacturing(self): + """ + 重新生成制造订单 + """ + if self.is_scrap is True: + sale_order = self.env['sale.order'].sudo().search([('name', '=', productions.origin)]) + values = self.env['mrp.production'].create_production1_values(self.production_id) + productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company( + self.production_id.company_id).create( + values) + # self.env['stock.move'].sudo().create(productions._get_moves_raw_values()) + self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) + productions._create_workorder() + productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ + ( + p.move_dest_ids.procure_method != 'make_to_order' and + not p.move_raw_ids and not p.workorder_ids)).action_confirm() + for production_item in productions: + process_parameter_workorder = self.env['mrp.workorder'].search( + [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production_item.id), + ('is_subcontract', '=', True)]) + if process_parameter_workorder: + is_pick = False + consecutive_workorders = [] + m = 0 + sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id) + for i in range(len(sorted_workorders) - 1): + if m == 0: + is_pick = False + if sorted_workorders[i].supplier_id.id == sorted_workorders[i + 1].supplier_id.id and \ + sorted_workorders[i].is_subcontract == sorted_workorders[i + 1].is_subcontract and \ + sorted_workorders[i].id == sorted_workorders[i + 1].id - 1: + if sorted_workorders[i] not in consecutive_workorders: + consecutive_workorders.append(sorted_workorders[i]) + consecutive_workorders.append(sorted_workorders[i + 1]) + m += 1 + continue + else: + if m == len(consecutive_workorders) - 1 and m != 0: + self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, + production_item) + if sorted_workorders[i] in consecutive_workorders: + is_pick = True + consecutive_workorders = [] + m = 0 + # 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单 + if is_pick is False: + self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], + production_item) + if m == len(consecutive_workorders) - 1 and m != 0: + self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, + production_item) + if sorted_workorders[i] in consecutive_workorders: + is_pick = True + consecutive_workorders = [] + m = 0 + if m == len(consecutive_workorders) - 1 and m != 0: + self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production_item) + if is_pick is False and m == 0: + if len(sorted_workorders) == 1: + self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production_item) + else: + self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production_item) + + for production in productions: + origin_production = production.move_dest_ids and production.move_dest_ids[ + 0].raw_material_production_id or False + orderpoint = production.orderpoint_id + if orderpoint and orderpoint.create_uid.id == SUPERUSER_ID and orderpoint.trigger == 'manual': + production.message_post( + body=_('This production order has been created from Replenishment Report.'), + message_type='comment', + subtype_xmlid='mail.mt_note') + elif orderpoint: + production.message_post_with_view( + 'mail.message_origin_link', + values={'self': production, 'origin': orderpoint}, + subtype_id=self.env.ref('mail.mt_note').id) + elif origin_production: + production.message_post_with_view( + 'mail.message_origin_link', + values={'self': production, 'origin': origin_production}, + subtype_id=self.env.ref('mail.mt_note').id) + + ''' + 创建生产计划 + ''' + # 工单耗时 + workorder_duration = 0 + for workorder in productions.workorder_ids: + workorder_duration += workorder.duration_expected + + if sale_order: + sale_order.mrp_production_ids |= productions + # sale_order.write({'schedule_status': 'to schedule'}) + self.env['sf.production.plan'].sudo().with_company(self.production_id.company_id).create({ + 'name': productions.name, + 'order_deadline': sale_order.deadline_of_delivery, + 'production_id': productions.id, + 'date_planned_start': productions.date_planned_start, + 'origin': productions.origin, + 'product_qty': productions.product_qty, + 'product_id': productions.product_id.id, + 'state': 'draft', + }) + + # 在之前的销售单上重新生成制造订单 + def create_production1_values(self, production, sale_order): + production_values_str = {'origin': production.origin, + 'product_id': production.product_id.id, + 'product_description_variants': production.product_description_variants, + 'product_qty': production.product_qty, + 'product_uom_id': production.product_uom_id.id, + 'location_src_id': production.location_src_id.id, + 'location_dest_id': production.location_dest_id.id, + 'bom_id': production.bom_id.id, + 'date_deadline': production.date_deadline, + 'date_planned_start': production.date_planned_start, + 'date_planned_finished': production.date_planned_finished, + 'procurement_group_id': sale_order.id, + 'propagate_cancel': production.propagate_cancel, + 'orderpoint_id': production.orderpoint_id.id, + 'picking_type_id': production.picking_type_id.id, + 'company_id': production.company_id.id, + 'move_dest_ids': production.move_dest_ids.ids, + 'user_id': production.user_id.id} + return production_values_str + + class sf_detection_result(models.Model): _name = 'sf.detection.result' diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 6da74cbc..a6f80fa2 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -684,118 +684,7 @@ class ResMrpWorkOrder(models.Model): # 'target':'new' # } - def recreateManufacturingOrWorkerOrder(self): - """ - 重新生成制造订单或者重新生成工单 - """ - if self.test_results in ['返工', '报废']: - values = self.env['mrp.production'].create_production1_values(self.production_id) - productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company( - self.production_id.company_id).create( - values) - # self.env['stock.move'].sudo().create(productions._get_moves_raw_values()) - self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) - productions._create_workorder() - productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ - ( - p.move_dest_ids.procure_method != 'make_to_order' and - not p.move_raw_ids and not p.workorder_ids)).action_confirm() - for production_item in productions: - process_parameter_workorder = self.env['mrp.workorder'].search( - [('surface_technics_parameters_id', '!=', False), ('production_id', '=', production_item.id), - ('is_subcontract', '=', True)]) - if process_parameter_workorder: - is_pick = False - consecutive_workorders = [] - m = 0 - sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id) - for i in range(len(sorted_workorders) - 1): - if m == 0: - is_pick = False - if sorted_workorders[i].supplier_id.id == sorted_workorders[i + 1].supplier_id.id and \ - sorted_workorders[i].is_subcontract == sorted_workorders[i + 1].is_subcontract and \ - sorted_workorders[i].id == sorted_workorders[i + 1].id - 1: - if sorted_workorders[i] not in consecutive_workorders: - consecutive_workorders.append(sorted_workorders[i]) - consecutive_workorders.append(sorted_workorders[i + 1]) - m += 1 - continue - else: - if m == len(consecutive_workorders) - 1 and m != 0: - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, - production_item) - if sorted_workorders[i] in consecutive_workorders: - is_pick = True - consecutive_workorders = [] - m = 0 - # 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单 - if is_pick is False: - self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], - production_item) - if m == len(consecutive_workorders) - 1 and m != 0: - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, - production_item) - if sorted_workorders[i] in consecutive_workorders: - is_pick = True - consecutive_workorders = [] - m = 0 - if m == len(consecutive_workorders) - 1 and m != 0: - self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production_item) - if is_pick is False and m == 0: - if len(sorted_workorders) == 1: - self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production_item) - else: - self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production_item) - for production in productions: - origin_production = production.move_dest_ids and production.move_dest_ids[ - 0].raw_material_production_id or False - orderpoint = production.orderpoint_id - if orderpoint and orderpoint.create_uid.id == SUPERUSER_ID and orderpoint.trigger == 'manual': - production.message_post( - body=_('This production order has been created from Replenishment Report.'), - message_type='comment', - subtype_xmlid='mail.mt_note') - elif orderpoint: - production.message_post_with_view( - 'mail.message_origin_link', - values={'self': production, 'origin': orderpoint}, - subtype_id=self.env.ref('mail.mt_note').id) - elif origin_production: - production.message_post_with_view( - 'mail.message_origin_link', - values={'self': production, 'origin': origin_production}, - subtype_id=self.env.ref('mail.mt_note').id) - - ''' - 创建生产计划 - ''' - # 工单耗时 - workorder_duration = 0 - for workorder in productions.workorder_ids: - workorder_duration += workorder.duration_expected - - sale_order = self.env['sale.order'].sudo().search([('name', '=', productions.origin)]) - if sale_order: - sale_order.mrp_production_ids |= productions - # sale_order.write({'schedule_status': 'to schedule'}) - self.env['sf.production.plan'].sudo().with_company(self.production_id.company_id).create({ - 'name': productions.name, - 'order_deadline': sale_order.deadline_of_delivery, - 'production_id': productions.id, - 'date_planned_start': productions.date_planned_start, - 'origin': productions.origin, - 'product_qty': productions.product_qty, - 'product_id': productions.product_id.id, - 'state': 'draft', - }) - # if self.test_results == '返工': - # productions = self.production_id - # # self.env['stock.move'].sudo().create(productions._get_moves_raw_values()) - # # self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) - # productions._create_workorder2(self.processing_panel) - # else: - # self.results = '合格' def json_workorder_str1(self, k, production, route): workorders_values_str = [0, '', { @@ -997,7 +886,7 @@ class ResMrpWorkOrder(models.Model): record.process_state = '待解除装夹' # record.write({'process_state': '待加工'}) record.production_id.process_state = '待解除装夹' - if record.test_results in ['返工']: + if record.test_results in ['返工', '报废']: record.production_id.write({'detection_result_ids': [(0, 0, { 'rework_reason': record.reason, 'detailed_reason': record.detailed_reason, @@ -1005,7 +894,8 @@ class ResMrpWorkOrder(models.Model): 'routing_type': record.routing_type, 'handle_result': '待处理' if record.test_results == '返工' or record.is_rework is True else '', 'test_results': record.test_results, - 'test_report': record.detection_report})]}) + 'test_report': record.detection_report})], + 'is_scrap': True if record.test_results == '报废' else False}) if record.routing_type == '解除装夹': ''' 记录结束时间 @@ -1064,14 +954,16 @@ class ResMrpWorkOrder(models.Model): for workorder in record.production_id.workorder_ids: if workorder.state != 'done': is_production_id = False - if record.routing_type == '解除装夹': + if record.routing_type in ['解除装夹'] or ( + record.is_rework is True and record.routing_type in ['装夹预调']) or ( + record.test_results in ['返工', '报废'] and record.routing_type in ['CNC加工']): for workorder in record.production_id.workorder_ids: if workorder.processing_panel == record.processing_panel: rfid_code = workorder.rfid_code workorder.write({'rfid_code_old': rfid_code, 'rfid_code': False}) - workorder.rfid_code_old = rfid_code - workorder.rfid_code = False + # workorder.rfid_code_old = rfid_code + # workorder.rfid_code = False if is_production_id is True and record.routing_type in ['解除装夹', '表面工艺']: logging.info('product_qty:%s' % record.production_id.product_qty) for move_raw_id in record.production_id.move_raw_ids: diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 4d05de81..f292d694 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -7,8 +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 +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file class ResProductMo(models.Model): diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv index 5cdb72b7..b3a7173a 100644 --- a/sf_manufacturing/security/ir.model.access.csv +++ b/sf_manufacturing/security/ir.model.access.csv @@ -144,5 +144,7 @@ access_mrp_bom_byproduct_group_sf_stock_manager,mrp_bom_byproduct_group_sf_mrp_m access_sf_rework_wizard_group_sf_order_user,sf_rework_wizard_group_sf_order_user,model_sf_rework_wizard,sf_base.group_sf_order_user,1,1,1,0 access_sf_detection_result_group_sf_order_user,sf_detection_result_group_sf_order_user,model_sf_detection_result,sf_base.group_sf_order_user,1,1,1,0 access_sf_processing_panel_group_sf_order_user,sf_processing_panel_group_sf_order_user,model_sf_processing_panel,sf_base.group_sf_order_user,1,1,1,0 +access_sf_production_wizard_group_sf_order_user,sf_production_wizard_group_sf_order_user,model_sf_production_wizard,sf_base.group_sf_order_user,1,1,1,0 + diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 9ee96732..9d177542 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -88,6 +88,7 @@ decoration-danger="programming_state =='已编程未下发'"/> + @@ -123,8 +124,9 @@ attrs="{'invisible': ['|',('state', '!=', 'rework'),('programming_state', '!=', '已编程未下发')]}"/>