From a1bf997d516b88e12e30d350310aca9e4669e932 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Thu, 2 Jan 2025 12:49:05 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=B2=97=E4=B8=8E?= =?UTF-8?q?=E9=87=87=E8=B4=AD=E6=80=BB=E7=9B=91=E5=B2=97=E4=BD=8D=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=B7=A5=E5=8D=95=E6=93=8D=E4=BD=9C=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/security/ir.model.access.csv | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv index f096b449..b8862b8d 100644 --- a/sf_manufacturing/security/ir.model.access.csv +++ b/sf_manufacturing/security/ir.model.access.csv @@ -183,4 +183,7 @@ access_sf_manual_product_model_type_routing_sort_manager,sf_manual_product_model access_sf_manual_product_model_type_routing_sort_group_plan_dispatch,sf_manual_product_model_type_routing_sort_group_plan_dispatch,model_sf_manual_product_model_type_routing_sort,sf_base.group_plan_dispatch,1,0,0,0 access_sf_detection_result_manager,sf_detection_result_manager,model_sf_detection_result,,1,1,1,1 -access_mrp_workorder_batch_replan_wizard_group_plan_dispatch,mrp_workorder_batch_replan_wizard_group_plan_dispatch,model_mrp_workorder_batch_replan_wizard,sf_base.group_plan_dispatch,1,1,1,0 \ No newline at end of file +access_mrp_workorder_batch_replan_wizard_group_plan_dispatch,mrp_workorder_batch_replan_wizard_group_plan_dispatch,model_mrp_workorder_batch_replan_wizard,sf_base.group_plan_dispatch,1,1,1,0 + +access_mrp_workorder_group_purchase_director,mrp_workorder,model_mrp_workorder,sf_base.group_purchase_director,1,1,0,0 +access_mrp_workorder_group_purchase,mrp_workorder,model_mrp_workorder,sf_base.group_purchase,1,1,0,0 \ No newline at end of file From 0ce51a4a66a320191c1ed81e3e7082dc52231d5a Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Thu, 2 Jan 2025 12:49:46 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=BA=E5=B7=A5?= =?UTF-8?q?=E7=BA=BF=E4=B8=8B=E5=8A=A0=E5=B7=A5=E5=B7=A5=E5=8D=95=E6=8E=92?= =?UTF-8?q?=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 2 + .../production_technology_re_adjust_wizard.py | 49 ------------------- .../wizard/production_technology_wizard.py | 30 ------------ 3 files changed, 2 insertions(+), 79 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 057530d0..af0f0aa9 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -941,6 +941,8 @@ class MrpProduction(models.Model): and item.process_parameters_id == work.surface_technics_parameters_id) or (item.route_id.name == work.name and item.panel and item.panel == work.processing_panel)) + if work.name == '人工线下加工': + td_ids = technology_design_ids.filtered(lambda item: (item.route_id.name in work.name)) if td_ids: work.sequence = td_ids[0].sequence cancel_work_ids = workorder_ids.filtered(lambda item: item.state in ('已取消', 'cancel')) diff --git a/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py b/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py index 5bd32b8c..fe90f66a 100644 --- a/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py +++ b/sf_manufacturing/wizard/production_technology_re_adjust_wizard.py @@ -25,38 +25,6 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel): # 该制造订单的其他同一销售订单的制造订单的工艺设计处理 if production_item != self.production_id: self.env['sf.technology.design'].sudo().unified_procedure_multiple_work_orders(technology_designs, production_item) - # for td_other in production_item.technology_design_ids: - # # if td_other.is_auto is False: - # # td_del = technology_designs.filtered(lambda tdo: tdo.route_id.id == td_other.route_id.id) - # # if not td_del or td_del.active is False: - # # td_other.write({'active': False}) - # for td_main in technology_designs: - # route_other = production_item.technology_design_ids.filtered( - # lambda td: td.route_id.id == td_main.route_id.id) - # if not route_other and td_main.active is True: - # production_item.write({'technology_design_ids': [(0, 0, { - # 'route_id': td_main.route_id.id, - # 'process_parameters_id': False if td_main.process_parameters_id is False else - # self.env[ - # 'sf.production.process.parameter'].search( - # [('id', '=', td_main.process_parameters_id.id)]).id, - # 'sequence': td_main.sequence, - # 'is_auto': td_main.is_auto})]}) - # else: - # for ro in route_other: - # domain = [('production_id', '=', self.production_id.id), - # ('active', 'in', [True, False]), - # ('route_id', '=', ro.route_id.id)] - # if ro.route_id.routing_type == '表面工艺': - # domain += [('process_parameters_id', '=', ro.process_parameters_id.id)] - # elif ro.route_id.routing_tag == 'special' and ro.is_auto is False: - # # display_name = ro.route_id.display_name - # domain += [('id', '=', ro.id)] - # elif ro.panel is not False: - # domain += [('panel', '=', ro.panel)] - # td_upd = self.env['sf.technology.design'].sudo().search(domain) - # if td_upd: - # ro.write({'sequence': td_upd.sequence, 'active': td_upd.active}) special_design = self.env['sf.technology.design'].sudo().search( [('routing_tag', '=', 'special'), ('production_id', '=', production_item.id), ('is_auto', '=', False), ('active', 'in', [True, False])]) @@ -71,23 +39,6 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel): else: domain += [('technology_design_id', '=', special.id), ('state', '!=', 'cancel')] workorder = self.env['mrp.workorder'].search(domain) - # previous_workorder = self.env['mrp.workorder'].search( - # [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'), - # ('production_id', '=', workorder.production_id.id)]) - # if previous_workorder: - # if previous_workorder.supplier_id != workorder.supplier_id: - # is_cancel = True - # else: - # is_cancel = True - # if workorder.state != 'cancel' and is_cancel is True: - # workorder.write({'state': 'cancel'}) - # workorder.picking_ids.write({'state': 'cancel'}) - # workorder.picking_ids.move_ids.write({'state': 'cancel'}) - # purchase_order = self.env['purchase.order'].search( - # [('origin', '=', workorder.production_id.name)]) - # for line in purchase_order.order_line: - # if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id: - # purchase_order.write({'state': 'cancel'}) else: workorder = self.env['mrp.workorder'].search( [('technology_design_id', '=', special.id), ('production_id', '=', special.production_id.id), ('state', '!=', 'cancel')]) diff --git a/sf_manufacturing/wizard/production_technology_wizard.py b/sf_manufacturing/wizard/production_technology_wizard.py index 1feee749..0415d1fd 100644 --- a/sf_manufacturing/wizard/production_technology_wizard.py +++ b/sf_manufacturing/wizard/production_technology_wizard.py @@ -27,36 +27,6 @@ class ProductionTechnologyWizard(models.TransientModel): if production != self.production_id: self.env['sf.technology.design'].sudo().unified_procedure_multiple_work_orders(technology_designs, production) - # for td_other in production.technology_design_ids: - # if td_other.is_auto is False: - # td_del = technology_designs.filtered(lambda tdo: tdo.route_id.id == td_other.route_id.id) - # if not td_del or td_del.active is False: - # td_other.write({'active': False}) - # for td_main in technology_designs: - # route_other = production.technology_design_ids.filtered( - # lambda td: td.route_id.id == td_main.route_id.id) - # if not route_other and td_main.active is True: - # production.write({'technology_design_ids': [(0, 0, { - # 'route_id': td_main.route_id.id, - # 'process_parameters_id': False if td_main.process_parameters_id is False else self.env[ - # 'sf.production.process.parameter'].search( - # [('id', '=', td_main.process_parameters_id.id)]).id, - # 'sequence': td_main.sequence})]}) - # else: - # for ro in route_other: - # domain = [('production_id', '=', self.production_id.id), - # ('active', 'in', [True, False]), - # ('route_id', '=', ro.route_id.id)] - # if ro.route_id.routing_type == '表面工艺': - # domain += [('process_parameters_id', '=', ro.process_parameters_id.id)] - # elif ro.route_id.routing_tag == 'special' and ro.is_auto is False: - # # display_name = ro.route_id.display_name - # domain += [('id', '=', ro.id)] - # elif ro.panel is not False: - # domain += [('panel', '=', ro.panel)] - # td_upd = self.env['sf.technology.design'].sudo().search(domain) - # if td_upd: - # ro.write({'sequence': td_upd.sequence, 'active': td_upd.active}) # 特殊表面工艺 special_design = self.env['sf.technology.design'].sudo().search( [('routing_tag', '=', 'special'), ('production_id', '=', production.id), From 2f3e12e3af4bd9b123bc73b537b65e2e8bec30fb Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Thu, 2 Jan 2025 12:50:39 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E8=A1=A8=E9=9D=A2=E5=B7=A5=E8=89=BA?= =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=8D=95=E7=A1=AE=E8=AE=A4=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E9=99=90=E5=88=B6=EF=BC=8C=E8=87=AA=E5=8A=A8=E5=8C=96=E4=BA=A7?= =?UTF-8?q?=E7=BA=BF=E5=8A=A0=E5=B7=A5=E8=B7=AF=E7=BA=BF=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E7=9F=AB=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_sale/models/sale_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index 95999611..b03d761a 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -401,7 +401,7 @@ class RePurchaseOrder(models.Model): artificial_offline = ( workorder.production_id.production_type == '人工线下加工' and workorder.production_id.schedule_state != '已排') auto_production = ( - workorder.production_id.production_type == '自动化产线加工' and workorder.production_id.schedule_state != '已编程') + workorder.production_id.production_type == '自动化产线加工' and workorder.production_id.programming_state != '已编程') if workorder.sequence == min_sequence_wk.sequence: if artificial_offline or auto_production: raise UserError('等待组件') From f884963abc8c4748c61cd1d29bd98d42bddfa443 Mon Sep 17 00:00:00 2001 From: liaodanlong Date: Thu, 2 Jan 2025 13:34:09 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E5=B7=A5=E8=89=BA=E7=A1=AE=E8=AE=A4?= =?UTF-8?q?=E9=87=8D=E7=BD=AE=E8=A1=A8=E9=9D=A2=E5=B7=A5=E8=89=BA=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=E7=9A=84=E5=85=B3=E8=81=94=E9=87=87=E8=B4=AD=E5=8D=95?= =?UTF-8?q?=E4=B8=BA=E8=8D=89=E7=A8=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_sale/models/sale_order.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py index b03d761a..1b282c8e 100644 --- a/sf_sale/models/sale_order.py +++ b/sf_sale/models/sale_order.py @@ -346,6 +346,7 @@ class RePurchaseOrder(models.Model): server_product_process = [] purchase_order = pp._get_surface_technics_purchase_ids() if purchase_order: + purchase_order.write({'state': 'draft'}) pp.purchase_id = [(6, 0, [purchase_order.id])] else: server_template = self.env['product.template'].search( From f92bd8263ca03b1eb1e2bc529c2fd369fae33fa7 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Thu, 2 Jan 2025 14:20:31 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E5=BE=85=E8=B4=A8=E6=A3=80=E6=8F=90?= =?UTF-8?q?=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quality_control/views/quality_views.xml | 1 + sf_message/__manifest__.py | 2 +- sf_message/data/bussiness_node.xml | 5 +++ sf_message/data/template_data.xml | 12 +++++++ sf_message/models/__init__.py | 1 + sf_message/models/sf_message_product.py | 14 +++++++- sf_message/models/sf_message_quality_check.py | 34 +++++++++++++++++++ 7 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 sf_message/models/sf_message_quality_check.py diff --git a/quality_control/views/quality_views.xml b/quality_control/views/quality_views.xml index 790f8cef..c40d42b2 100644 --- a/quality_control/views/quality_views.xml +++ b/quality_control/views/quality_views.xml @@ -519,6 +519,7 @@ Quality Checks quality.check tree,kanban,form,pivot,graph + {'is_web_request': True}

No quality check found diff --git a/sf_message/__manifest__.py b/sf_message/__manifest__.py index 6796a50b..8c769d60 100644 --- a/sf_message/__manifest__.py +++ b/sf_message/__manifest__.py @@ -12,7 +12,7 @@ 'category': 'sf', 'website': 'https://www.sf.jikimo.com', 'depends': ['sale', 'purchase', 'sf_plan', 'jikimo_message_notify', 'stock', 'sf_quality', 'mrp', - 'sf_manufacturing','product'], + 'sf_manufacturing','product','quality'], 'data': [ 'data/bussiness_node.xml', 'data/cron_data.xml', diff --git a/sf_message/data/bussiness_node.xml b/sf_message/data/bussiness_node.xml index e7c3b0ba..b429d766 100644 --- a/sf_message/data/bussiness_node.xml +++ b/sf_message/data/bussiness_node.xml @@ -150,5 +150,10 @@ 采购单已逾期提醒 purchase.order + + + 待质检提醒 + product.product + \ No newline at end of file diff --git a/sf_message/data/template_data.xml b/sf_message/data/template_data.xml index 52b226e3..11f05a3c 100644 --- a/sf_message/data/template_data.xml +++ b/sf_message/data/template_data.xml @@ -389,5 +389,17 @@ 事项:[共有{{num}}个采购订单已逾期]({{url}}) + + + 待质检提醒 + + product.product + + markdown + normal + ### 待质检提醒: +单号:产品[{{name}}]({{url}}) +事项:有{{num}}个质检单需要处理。 + \ No newline at end of file diff --git a/sf_message/models/__init__.py b/sf_message/models/__init__.py index 8c215042..f8f6fcf1 100644 --- a/sf_message/models/__init__.py +++ b/sf_message/models/__init__.py @@ -13,3 +13,4 @@ from . import sf_message_maintenance_logs from . import sf_message_mrp_production_wizard from . import sf_message_mrp_production_adjust_wizard from . import sf_message_product +from . import sf_message_quality_check \ No newline at end of file diff --git a/sf_message/models/sf_message_product.py b/sf_message/models/sf_message_product.py index 85ac4ce2..0f2cfd7e 100644 --- a/sf_message/models/sf_message_product.py +++ b/sf_message/models/sf_message_product.py @@ -3,7 +3,7 @@ from odoo import models, fields, api, _ from urllib.parse import urlencode -class SFMessagePlan(models.Model): +class SFMessageProduct(models.Model): _name = 'product.product' _inherit = ['product.product', 'jikimo.message.dispatch'] @@ -28,6 +28,18 @@ class SFMessagePlan(models.Model): '{{number}}', str(production_num)).replace( '{{request_url}}', url) contents.append(content) + if message_queue_id.message_template_id.name == '待质检提醒': + content = message_queue_id.message_template_id.content + product_product = self.env['product.product'].sudo().search([('id', '=', int(message_queue_id.res_id))]) + quality_check_num = self.env['quality.check'].sudo().search_count( + [('product_id', '=', product_product.id), ('quality_state', '=', 'none')]) + if quality_check_num >= 1: + url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + action_id = self.env.ref('quality_control.quality_check_action_report').id + url_with_id = f"{url}/web#view_type=list&action={action_id}" + content = content.replace('{{name}}', product_product.name).replace('{{url}}', url_with_id).replace( + '{{num}}', str(quality_check_num)) + contents.append(content) return contents, message_queue_ids def get_request_url(self): diff --git a/sf_message/models/sf_message_quality_check.py b/sf_message/models/sf_message_quality_check.py new file mode 100644 index 00000000..c53adda9 --- /dev/null +++ b/sf_message/models/sf_message_quality_check.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +import logging +from odoo import models, fields, api, _ + + +class SFMessageQualityCheck(models.Model): + _name = 'quality.check' + _inherit = ['quality.check', 'jikimo.message.dispatch'] + + @api.model_create_multi + def create(self, vals_list): + result = super().create(vals_list) + try: + # 判断是否为web页面创建请求 + is_web_request = self.env.context.get('is_web_request', False) + if not is_web_request: + for obj in result: + jikimo_message_queue = self.get_message_queue(obj.product_id.id) + if not jikimo_message_queue: + obj.product_id.add_queue('待质检提醒') + except Exception as e: + logging.info('add_queue待质检提醒 error:%s' % e) + return result + + def get_message_queue(self, res_id): + business_node_id = self.env.ref('sf_message.bussiness_quality_check').id + message_template = self.env["jikimo.message.template"].sudo().search([ + ("model", "=", self._name), + ("bussiness_node_id", "=", business_node_id) + ], limit=1) + jikimo_message_queue = self.env['jikimo.message.queue'].sudo().search( + [('res_id', '=', res_id), ("message_status", "in", ("pending", "sent")), + ('message_template_id', '=', message_template.id)]) + return jikimo_message_queue From eaaa13fb9aa2db1be8ec4fc126815b35d7d5e5a7 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Thu, 2 Jan 2025 14:21:18 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E5=BE=85=E8=B4=A8=E6=A3=80=E6=8F=90?= =?UTF-8?q?=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_message/models/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_message/models/__init__.py b/sf_message/models/__init__.py index f8f6fcf1..18c6b873 100644 --- a/sf_message/models/__init__.py +++ b/sf_message/models/__init__.py @@ -13,4 +13,4 @@ from . import sf_message_maintenance_logs from . import sf_message_mrp_production_wizard from . import sf_message_mrp_production_adjust_wizard from . import sf_message_product -from . import sf_message_quality_check \ No newline at end of file +from . import sf_message_quality_check From c6aeff2006cccfa21c82d53c139fe617ce77d131 Mon Sep 17 00:00:00 2001 From: guanhuan Date: Fri, 3 Jan 2025 10:17:33 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E5=BE=85=E8=B4=A8=E6=A3=80=E6=8F=90?= =?UTF-8?q?=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_message/models/sf_message_quality_check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_message/models/sf_message_quality_check.py b/sf_message/models/sf_message_quality_check.py index c53adda9..15713791 100644 --- a/sf_message/models/sf_message_quality_check.py +++ b/sf_message/models/sf_message_quality_check.py @@ -25,7 +25,7 @@ class SFMessageQualityCheck(models.Model): def get_message_queue(self, res_id): business_node_id = self.env.ref('sf_message.bussiness_quality_check').id message_template = self.env["jikimo.message.template"].sudo().search([ - ("model", "=", self._name), + ("name", "=", '待质检提醒'), ("bussiness_node_id", "=", business_node_id) ], limit=1) jikimo_message_queue = self.env['jikimo.message.queue'].sudo().search(