From c3a7a6c4d6b2e5c80665ce673fb11703fa0a7b2d Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Tue, 25 Oct 2022 17:30:13 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E5=B7=A5=E5=BA=8F=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=94=AF=E4=B8=80=E7=BC=96=E7=A0=81,=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=EF=BC=8C=E6=8E=92=E5=BA=8F=EF=BC=9B=E7=94=A8?= =?UTF-8?q?xml=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90CNC=E5=8A=A0=E5=B7=A5?= =?UTF-8?q?=E7=9A=84=E6=A0=87=E5=87=86=E5=B7=A5=E5=BA=8F=EF=BC=9B=20?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E5=A2=9E=E5=8A=A0=E6=A8=A1=E5=9E=8B=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=AF=B9=E8=B1=A1=E5=92=8C=E5=8A=A0=E5=B7=A5=E7=9A=84?= =?UTF-8?q?=E9=9D=A2=EF=BC=8C=E5=8C=85=E6=8B=AC=E8=83=9A=E6=96=99=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=9A=84=E5=B0=BA=E5=AF=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/views/mrs_common_view.xml | 1 - sf_bpm_api/__manifest__.py | 5 +- sf_bpm_api/data/process_data.xml | 79 ++++++++++++++++++++ sf_bpm_api/models/__init__.py | 1 + sf_bpm_api/models/process.py | 11 +++ sf_bpm_api/models/product_template.py | 15 ++++ sf_bpm_api/security/ir.model.access.csv | 5 +- sf_bpm_api/views/product_template_view.xml | 86 +++++++++++++--------- 8 files changed, 162 insertions(+), 41 deletions(-) create mode 100644 sf_bpm_api/data/process_data.xml create mode 100644 sf_bpm_api/models/process.py diff --git a/sf_base/views/mrs_common_view.xml b/sf_base/views/mrs_common_view.xml index 1877de05..8c3e92d2 100644 --- a/sf_base/views/mrs_common_view.xml +++ b/sf_base/views/mrs_common_view.xml @@ -284,7 +284,6 @@ - diff --git a/sf_bpm_api/__manifest__.py b/sf_bpm_api/__manifest__.py index b659bd14..51ff2a57 100644 --- a/sf_bpm_api/__manifest__.py +++ b/sf_bpm_api/__manifest__.py @@ -10,9 +10,12 @@ """, 'category': 'sf', 'website': 'https://www.sf.cs.jikimo.com', - 'depends': ['sale', 'sf_base'], + 'depends': ['sale', 'sf_base', 'mrp'], 'data': [ + 'security/group_security.xml', + 'security/ir.model.access.csv', 'data/product_data.xml', + 'data/process_data.xml', 'views/product_template_view.xml', 'views/sale_order_view.xml' ], diff --git a/sf_bpm_api/data/process_data.xml b/sf_bpm_api/data/process_data.xml new file mode 100644 index 00000000..1447fc13 --- /dev/null +++ b/sf_bpm_api/data/process_data.xml @@ -0,0 +1,79 @@ + + + + + + Assembly Line 1 + false + + + + + + 1 + false + + + + 获取自动编码程序 + automatic coding + manual + + + 60 + false + + + + 装夹 + clamping + manual + + + 60 + false + + + + 前置三元定位检测 + pre-ternary positioning detection + manual + + + 60 + false + + + + CNC加工 + CNC machining + manual + + + 60 + false + + + + 后置三元质量检测 + post ternary quality inspection + manual + + + 60 + false + + + + 解除装夹 + remove the clamping + manual + + + 60 + false + + + + + \ No newline at end of file diff --git a/sf_bpm_api/models/__init__.py b/sf_bpm_api/models/__init__.py index 4c183668..0dc63d28 100644 --- a/sf_bpm_api/models/__init__.py +++ b/sf_bpm_api/models/__init__.py @@ -2,5 +2,6 @@ from . import sale_order from . import product_template from . import http from . import models +from . import process diff --git a/sf_bpm_api/models/process.py b/sf_bpm_api/models/process.py new file mode 100644 index 00000000..056b824d --- /dev/null +++ b/sf_bpm_api/models/process.py @@ -0,0 +1,11 @@ +from odoo import fields, models, api + + +class ResMrpRoutingWorkcenter(models.Model): + _inherit = 'mrp.routing.workcenter' + + code = fields.Char('唯一编码') + is_repeat = fields.Boolean('重复',default=False) + sort = fields.Integer('排序') + + diff --git a/sf_bpm_api/models/product_template.py b/sf_bpm_api/models/product_template.py index 08f2237c..0c1d4b12 100644 --- a/sf_bpm_api/models/product_template.py +++ b/sf_bpm_api/models/product_template.py @@ -13,6 +13,8 @@ class ResProductTemplate(models.Model): model_precision = fields.Float('精度要求', digits=(16, 3)) model_materials_id = fields.Many2one('mrs.production.materials', string='材料') model_materials_type_id = fields.Many2one('mrs.materials.model', string='型号') + model_type_id = fields.Many2one('sf.model.type', string='类型') + processing_panel = fields.Char('加工面板') # 胚料的长,宽,高 embryo_long = fields.Float('长[mm]', digits=(16, 3)) embryo_width = fields.Float('宽[mm]', digits=(16, 3)) @@ -20,6 +22,7 @@ class ResProductTemplate(models.Model): embryo_materials_id = fields.Many2one('mrs.production.materials', string='材料') embryo_materials_type_id = fields.Many2one('mrs.materials.model', string='型号') + # 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品 def product_create(self, product_id, item, order_id, order_number, i): copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy() @@ -84,3 +87,15 @@ class ResMrpBom(models.Model): 'product_uom_id': 1 } return self.env['mrp.bom.line'].create(vals) + + +class ModelType(models.Model): + _name = 'sf.model.type' + _description = '模型类型' + + name = fields.Char('名称') + code = fields.Char('编码') + + + + diff --git a/sf_bpm_api/security/ir.model.access.csv b/sf_bpm_api/security/ir.model.access.csv index 963679d4..c36d0d05 100644 --- a/sf_bpm_api/security/ir.model.access.csv +++ b/sf_bpm_api/security/ir.model.access.csv @@ -1,5 +1,2 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink - - - - +access_sf_model_type,sf_model_type,model_sf_model_type,base.group_user,1,1,1,1 diff --git a/sf_bpm_api/views/product_template_view.xml b/sf_bpm_api/views/product_template_view.xml index 406330e3..fea34c5c 100644 --- a/sf_bpm_api/views/product_template_view.xml +++ b/sf_bpm_api/views/product_template_view.xml @@ -7,51 +7,67 @@ - - - + + + - - + + - + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 71a925334ec4c397a48f45c7fffaa5a84d59a2bc Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Wed, 26 Oct 2022 17:27:32 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E7=94=9F=E6=88=90=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E7=9A=84BOM=E4=B8=8A=E7=9A=84=E5=8A=A0=E5=B7=A5=E5=B7=A5?= =?UTF-8?q?=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/__manifest__.py | 7 +- {sf_bpm_api => sf_base}/data/process_data.xml | 45 ++-------- {sf_bpm_api => sf_base}/data/product_data.xml | 0 sf_base/models/__init__.py | 3 + sf_base/models/process.py | 20 +++++ .../models/product_template.py | 33 +++---- {sf_bpm_api => sf_base}/models/sale_order.py | 0 sf_base/security/ir.model.access.csv | 2 +- sf_base/views/menu_view.xml | 14 +-- sf_base/views/mrp_routing_workcenter_view.xml | 15 ++++ sf_base/views/mrs_base_view.xml | 70 ++++++++++++++- sf_base/views/product_template_view.xml | 50 +++++++++++ .../views/sale_order_view.xml | 0 .../views/sale_process_order_view.xml | 30 +++---- sf_bpm_api/__manifest__.py | 4 - sf_bpm_api/models/__init__.py | 4 +- sf_bpm_api/models/process.py | 11 --- sf_bpm_api/security/ir.model.access.csv | 2 +- sf_bpm_api/views/product_template_view.xml | 85 ------------------- 19 files changed, 208 insertions(+), 187 deletions(-) rename {sf_bpm_api => sf_base}/data/process_data.xml (52%) rename {sf_bpm_api => sf_base}/data/product_data.xml (100%) create mode 100644 sf_base/models/process.py rename {sf_bpm_api => sf_base}/models/product_template.py (80%) rename {sf_bpm_api => sf_base}/models/sale_order.py (100%) create mode 100644 sf_base/views/mrp_routing_workcenter_view.xml create mode 100644 sf_base/views/product_template_view.xml rename {sf_bpm_api => sf_base}/views/sale_order_view.xml (100%) delete mode 100644 sf_bpm_api/models/process.py delete mode 100644 sf_bpm_api/views/product_template_view.xml diff --git a/sf_base/__manifest__.py b/sf_base/__manifest__.py index 77165cde..800d07c0 100644 --- a/sf_base/__manifest__.py +++ b/sf_base/__manifest__.py @@ -14,9 +14,14 @@ 'data': [ 'security/group_security.xml', 'security/ir.model.access.csv', + 'data/product_data.xml', + 'data/process_data.xml', + 'views/product_template_view.xml', + 'views/sale_order_view.xml', 'views/mrs_base_view.xml', 'views/mrs_common_view.xml', - "views/menu_view.xml" + 'views/menu_view.xml', + 'views/mrp_routing_workcenter_view.xml', ], 'demo': [ diff --git a/sf_bpm_api/data/process_data.xml b/sf_base/data/process_data.xml similarity index 52% rename from sf_bpm_api/data/process_data.xml rename to sf_base/data/process_data.xml index 1447fc13..4bc9cf25 100644 --- a/sf_bpm_api/data/process_data.xml +++ b/sf_base/data/process_data.xml @@ -1,79 +1,52 @@ - - - - Assembly Line 1 - false - - - - - - 1 - false - - + 获取自动编码程序 automatic coding manual - - 60 - false + True 装夹 clamping manual - - 60 - false + True 前置三元定位检测 - pre-ternary positioning detection + pre-ternary manual - - 60 - false + True CNC加工 CNC machining manual - - 60 - false + True 后置三元质量检测 - post ternary quality inspection + post ternary manual - - 60 - false + True 解除装夹 remove the clamping manual - - 60 - false + True - - \ No newline at end of file diff --git a/sf_bpm_api/data/product_data.xml b/sf_base/data/product_data.xml similarity index 100% rename from sf_bpm_api/data/product_data.xml rename to sf_base/data/product_data.xml diff --git a/sf_base/models/__init__.py b/sf_base/models/__init__.py index 27b447be..1b906dd5 100644 --- a/sf_base/models/__init__.py +++ b/sf_base/models/__init__.py @@ -1,2 +1,5 @@ from. import sf_base from. import sf_common +from . import sale_order +from . import product_template +from . import process diff --git a/sf_base/models/process.py b/sf_base/models/process.py new file mode 100644 index 00000000..05b7791c --- /dev/null +++ b/sf_base/models/process.py @@ -0,0 +1,20 @@ +from odoo import fields, models, api + + +class ModelType(models.Model): + _name = 'sf.model.type' + _description = '模型类型' + + name = fields.Char('名称') + routing_tmpl_id = fields.One2many('mrp.routing.workcenter', 'model_type_id', '工序模板') + + +class ResMrpRoutingWorkcenter(models.Model): + _inherit = 'mrp.routing.workcenter' + + code = fields.Char('唯一编码') + is_repeat = fields.Boolean('重复', default=False) + workcenter_id = fields.Many2many('mrp.workcenter', required=False) + bom_id = fields.Many2one('mrp.bom', required=False) + sort = fields.Integer('排序') + model_type_id = fields.Many2one('sf.model.type') diff --git a/sf_bpm_api/models/product_template.py b/sf_base/models/product_template.py similarity index 80% rename from sf_bpm_api/models/product_template.py rename to sf_base/models/product_template.py index 0c1d4b12..7535ae92 100644 --- a/sf_bpm_api/models/product_template.py +++ b/sf_base/models/product_template.py @@ -6,21 +6,21 @@ class ResProductTemplate(models.Model): _inherit = 'product.template' # 模型的长,宽,高,体积,精度,材料 - model_long = fields.Float('长[mm]', digits=(16, 3)) - model_width = fields.Float('宽[mm]', digits=(16, 3)) - model_height = fields.Float('高[mm]', digits=(16, 3)) - model_volume = fields.Float('体积[mm³]', digits=(16, 3)) + model_long = fields.Float('模型长[mm]', digits=(16, 3)) + model_width = fields.Float('模型宽[mm]', digits=(16, 3)) + model_height = fields.Float('模型高[mm]', digits=(16, 3)) + model_volume = fields.Float('模型体积[mm³]', digits=(16, 3)) model_precision = fields.Float('精度要求', digits=(16, 3)) - model_materials_id = fields.Many2one('mrs.production.materials', string='材料') - model_materials_type_id = fields.Many2one('mrs.materials.model', string='型号') - model_type_id = fields.Many2one('sf.model.type', string='类型') - processing_panel = fields.Char('加工面板') + model_materials_id = fields.Many2one('mrs.production.materials', string='模型材料') + model_materials_type_id = fields.Many2one('mrs.materials.model', string='模型材料型号') + model_type_id = fields.Many2one('sf.model.type', string='模型类型') + processing_panel = fields.Char('模型加工面板') # 胚料的长,宽,高 - embryo_long = fields.Float('长[mm]', digits=(16, 3)) - embryo_width = fields.Float('宽[mm]', digits=(16, 3)) - embryo_height = fields.Float('高[mm]', digits=(16, 3)) - embryo_materials_id = fields.Many2one('mrs.production.materials', string='材料') - embryo_materials_type_id = fields.Many2one('mrs.materials.model', string='型号') + embryo_long = fields.Float('胚料长[mm]', digits=(16, 3)) + embryo_width = fields.Float('胚料宽[mm]', digits=(16, 3)) + embryo_height = fields.Float('胚料高[mm]', digits=(16, 3)) + embryo_materials_id = fields.Many2one('mrs.production.materials', string='胚料材料') + embryo_materials_type_id = fields.Many2one('mrs.materials.model', string='胚料材料型号') # 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品 @@ -89,12 +89,7 @@ class ResMrpBom(models.Model): return self.env['mrp.bom.line'].create(vals) -class ModelType(models.Model): - _name = 'sf.model.type' - _description = '模型类型' - - name = fields.Char('名称') - code = fields.Char('编码') + diff --git a/sf_bpm_api/models/sale_order.py b/sf_base/models/sale_order.py similarity index 100% rename from sf_bpm_api/models/sale_order.py rename to sf_base/models/sale_order.py diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv index 5b4aa249..e94d9ea6 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -13,7 +13,7 @@ access_mrs_production_materials,mrs_production_materials,model_mrs_production_ma access_mrs_materials_model,mrs_materials_model,model_mrs_materials_model,base.group_user,1,1,1,1 access_mrs_processing_technology,mrs_processing_technology,model_mrs_processing_technology,base.group_user,1,1,1,1 access_sf_tray,sf_tray,model_sf_tray,base.group_user,1,1,1,1 - +access_sf_model_type,sf_model_type,model_sf_model_type,base.group_user,1,1,1,1 diff --git a/sf_base/views/menu_view.xml b/sf_base/views/menu_view.xml index 42c9602c..4babedb1 100644 --- a/sf_base/views/menu_view.xml +++ b/sf_base/views/menu_view.xml @@ -142,13 +142,13 @@ action="action_mrs_machine_control_system"/> - - - - - - - + diff --git a/sf_base/views/mrp_routing_workcenter_view.xml b/sf_base/views/mrp_routing_workcenter_view.xml new file mode 100644 index 00000000..3712561e --- /dev/null +++ b/sf_base/views/mrp_routing_workcenter_view.xml @@ -0,0 +1,15 @@ + + + + + mrp.routing.workcenter.form.inherit.sf + mrp.routing.workcenter + + + + + + + + + \ No newline at end of file diff --git a/sf_base/views/mrs_base_view.xml b/sf_base/views/mrs_base_view.xml index 1d6aeaf3..10c6a6b6 100644 --- a/sf_base/views/mrs_base_view.xml +++ b/sf_base/views/mrs_base_view.xml @@ -355,11 +355,11 @@
-
- + - + @@ -406,7 +407,7 @@ - + @@ -489,4 +490,65 @@

+ + #------------------模型类型------------------ + + + search.sf.model.type + sf.model.type + + + + + + + + + tree.sf.model.type + sf.model.type + + + + + + + + + form.sf.model.type + sf.model.type + + + + + + + + + + + + + + + + + + + + + + + 模型类型 + ir.actions.act_window + sf.model.type + tree,form + +

+ [模型类型] 还没有哦!点左上角的[创建]按钮,沙发归你了! +

+

+

+
+
\ No newline at end of file diff --git a/sf_base/views/product_template_view.xml b/sf_base/views/product_template_view.xml new file mode 100644 index 00000000..3a8c0955 --- /dev/null +++ b/sf_base/views/product_template_view.xml @@ -0,0 +1,50 @@ + + + + + product.template.form.inherit.sf + product.template + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + product.category.form.inherit.sf + product.category + + + + + + + + + \ No newline at end of file diff --git a/sf_bpm_api/views/sale_order_view.xml b/sf_base/views/sale_order_view.xml similarity index 100% rename from sf_bpm_api/views/sale_order_view.xml rename to sf_base/views/sale_order_view.xml diff --git a/sf_bf_connect/views/sale_process_order_view.xml b/sf_bf_connect/views/sale_process_order_view.xml index 898ade1b..188a2767 100644 --- a/sf_bf_connect/views/sale_process_order_view.xml +++ b/sf_bf_connect/views/sale_process_order_view.xml @@ -1,18 +1,18 @@ - - - sale.order - - - - - - - - - - - - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sf_bpm_api/__manifest__.py b/sf_bpm_api/__manifest__.py index 51ff2a57..0447a76b 100644 --- a/sf_bpm_api/__manifest__.py +++ b/sf_bpm_api/__manifest__.py @@ -14,10 +14,6 @@ 'data': [ 'security/group_security.xml', 'security/ir.model.access.csv', - 'data/product_data.xml', - 'data/process_data.xml', - 'views/product_template_view.xml', - 'views/sale_order_view.xml' ], 'demo': [ ], diff --git a/sf_bpm_api/models/__init__.py b/sf_bpm_api/models/__init__.py index 0dc63d28..0d9a2937 100644 --- a/sf_bpm_api/models/__init__.py +++ b/sf_bpm_api/models/__init__.py @@ -1,7 +1,5 @@ -from . import sale_order -from . import product_template from . import http from . import models -from . import process + diff --git a/sf_bpm_api/models/process.py b/sf_bpm_api/models/process.py deleted file mode 100644 index 056b824d..00000000 --- a/sf_bpm_api/models/process.py +++ /dev/null @@ -1,11 +0,0 @@ -from odoo import fields, models, api - - -class ResMrpRoutingWorkcenter(models.Model): - _inherit = 'mrp.routing.workcenter' - - code = fields.Char('唯一编码') - is_repeat = fields.Boolean('重复',default=False) - sort = fields.Integer('排序') - - diff --git a/sf_bpm_api/security/ir.model.access.csv b/sf_bpm_api/security/ir.model.access.csv index c36d0d05..08145a00 100644 --- a/sf_bpm_api/security/ir.model.access.csv +++ b/sf_bpm_api/security/ir.model.access.csv @@ -1,2 +1,2 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_sf_model_type,sf_model_type,model_sf_model_type,base.group_user,1,1,1,1 + diff --git a/sf_bpm_api/views/product_template_view.xml b/sf_bpm_api/views/product_template_view.xml deleted file mode 100644 index fea34c5c..00000000 --- a/sf_bpm_api/views/product_template_view.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - product.template.form.inherit.sf - product.template - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - product.category.form.inherit.sf - product.category - - - - - - - - - \ No newline at end of file From 002653957e85df6474cb5078567f659d4cbf0ac1 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 27 Oct 2022 17:27:40 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E6=94=B9=E9=80=A0=E5=88=B6=E9=80=A0?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E9=87=8C=E7=9A=84=E7=94=9F=E6=88=90=E5=B7=A5?= =?UTF-8?q?=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/__manifest__.py | 6 +- sf_base/models/__init__.py | 6 +- sf_base/views/mrs_common_view.xml | 30 +++-- sf_manufacturing_orders/models/__init__.py | 3 +- .../models/mrp_workorder.py | 124 ++++++++++++++++++ .../models/sf_production.py | 49 ++++++- 6 files changed, 194 insertions(+), 24 deletions(-) create mode 100644 sf_manufacturing_orders/models/mrp_workorder.py diff --git a/sf_base/__manifest__.py b/sf_base/__manifest__.py index 800d07c0..5c5c2725 100644 --- a/sf_base/__manifest__.py +++ b/sf_base/__manifest__.py @@ -10,18 +10,18 @@ """, 'category': 'YZ', 'website': 'https://www.sf.jikimo.com', - 'depends': ['account', 'base', 'mrp'], + 'depends': ['account', 'base', 'mrp', 'sale'], 'data': [ 'security/group_security.xml', 'security/ir.model.access.csv', 'data/product_data.xml', 'data/process_data.xml', - 'views/product_template_view.xml', - 'views/sale_order_view.xml', 'views/mrs_base_view.xml', 'views/mrs_common_view.xml', 'views/menu_view.xml', 'views/mrp_routing_workcenter_view.xml', + 'views/sale_order_view.xml', + 'views/product_template_view.xml', ], 'demo': [ diff --git a/sf_base/models/__init__.py b/sf_base/models/__init__.py index 1b906dd5..0f189de6 100644 --- a/sf_base/models/__init__.py +++ b/sf_base/models/__init__.py @@ -1,5 +1,5 @@ -from. import sf_base -from. import sf_common -from . import sale_order +from . import sf_base +from . import sf_common from . import product_template +from . import sale_order from . import process diff --git a/sf_base/views/mrs_common_view.xml b/sf_base/views/mrs_common_view.xml index 8c3e92d2..56178e82 100644 --- a/sf_base/views/mrs_common_view.xml +++ b/sf_base/views/mrs_common_view.xml @@ -277,6 +277,18 @@ #------------------托盘------------------ + + 托盘 + ir.actions.act_window + sf.tray + tree,form + +

+ 创建托盘吧 +

+
+
+ sf.tray.search sf.tray @@ -285,9 +297,9 @@ - - - + + + @@ -321,17 +333,7 @@
- - 托盘 - ir.actions.act_window - sf.tray - tree,form - -

- 创建托盘吧 -

-
-
+ \ No newline at end of file diff --git a/sf_manufacturing_orders/models/__init__.py b/sf_manufacturing_orders/models/__init__.py index 3fb32983..e1f5282a 100644 --- a/sf_manufacturing_orders/models/__init__.py +++ b/sf_manufacturing_orders/models/__init__.py @@ -1 +1,2 @@ -from. import sf_production +from . import sf_production +from . import mrp_workorder diff --git a/sf_manufacturing_orders/models/mrp_workorder.py b/sf_manufacturing_orders/models/mrp_workorder.py new file mode 100644 index 00000000..6469e23e --- /dev/null +++ b/sf_manufacturing_orders/models/mrp_workorder.py @@ -0,0 +1,124 @@ +from collections import defaultdict +from dateutil.relativedelta import relativedelta + +from odoo import api, fields, models, SUPERUSER_ID, _ +from odoo.osv import expression +from odoo.addons.stock.models.stock_rule import ProcurementException +from odoo.tools import float_compare, OrderedSet + + +class StockRule(models.Model): + _inherit = 'stock.rule' + + +def _run_manufacture(self, procurements): + productions_values_by_company = defaultdict(list) + errors = [] + for procurement, rule in procurements: + if float_compare(procurement.product_qty, 0, precision_rounding=procurement.product_uom.rounding) <= 0: + # If procurement contains negative quantity, don't create a MO that would be for a negative value. + continue + bom = rule._get_matching_bom(procurement.product_id, procurement.company_id, procurement.values) + + productions_values_by_company[procurement.company_id.id].append(rule._prepare_mo_vals(*procurement, bom)) + + if errors: + raise ProcurementException(errors) + + for company_id, productions_values in productions_values_by_company.items(): + # create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example) + productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create( + productions_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 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) + return True + + +class ResMrpWorkOrder(models.Model): + _inherit = 'mrp.workorder' + + workcenter_id = fields.Many2one('mrp.workcenter', required=False) + processing_panel = fields.Char('加工面') + + @api.model_create_multi + def create(self, values): + res = super().create(values) + if self.env.context.get('skip_confirm'): + return res + to_confirm = res.filtered(lambda wo: wo.production_id.state in ("confirmed", "progress", "to_close")) + to_confirm = to_confirm.production_id.workorder_ids + to_confirm._action_confirm() + return res + + def _action_confirm(self): + workorders_by_production = defaultdict(lambda: self.env['mrp.workorder']) + for workorder in self: + workorders_by_production[workorder.production_id] |= workorder + + for production, workorders in workorders_by_production.items(): + workorders_by_bom = defaultdict(lambda: self.env['mrp.workorder']) + bom = self.env['mrp.bom'] + moves = production.move_raw_ids | production.move_finished_ids + + for workorder in workorders: + bom = workorder.operation_id.bom_id or workorder.production_id.bom_id + previous_workorder = workorders_by_bom[bom][-1:] + previous_workorder.next_work_order_id = workorder.id + workorders_by_bom[bom] |= workorder + + moves.filtered(lambda m: m.operation_id == workorder.operation_id).write({ + 'workorder_id': workorder.id + }) + + exploded_boms, dummy = production.bom_id.explode(production.product_id, 1, + picking_type=production.bom_id.picking_type_id) + exploded_boms = {b[0]: b[1] for b in exploded_boms} + for move in moves: + if move.workorder_id: + continue + bom = move.bom_line_id.bom_id + while bom and bom not in workorders_by_bom: + bom_data = exploded_boms.get(bom, {}) + bom = bom_data.get('parent_line') and bom_data['parent_line'].bom_id or False + if bom in workorders_by_bom: + move.write({ + 'workorder_id': workorders_by_bom[bom][-1:].id + }) + else: + move.write({ + 'workorder_id': workorders_by_bom[production.bom_id][-1:].id + }) + + for workorders in workorders_by_bom.values(): + if not workorders: + continue + if workorders[0].state == 'pending': + workorders[0].state = 'ready' if workorders[0].production_availability == 'assigned' else 'waiting' + for workorder in workorders: + workorder._start_nextworkorder() diff --git a/sf_manufacturing_orders/models/sf_production.py b/sf_manufacturing_orders/models/sf_production.py index 6995005a..b02c895d 100644 --- a/sf_manufacturing_orders/models/sf_production.py +++ b/sf_manufacturing_orders/models/sf_production.py @@ -29,10 +29,54 @@ class MrpProduction(models.Model): _inherit = 'mrp.production' _description = "制造订单" + # 重载根据工序生成工单的程序:如果产品BOM中没有工序时, + # 根据产品对应的模板类型中工序,去生成工单; + # 工单对应的工作中心,根据工序中的工作中心去匹配, + # 如果只配置了一个工作中心,则默认采用该工作中心; + # 如果有多个工作中心, + # 则根据该工作中心的工单个数进行分配(优先分配给工单个数最少的); + # CNC加工工序的选取规则: + # 如果自动报价有带过来预分配的机床, + # 则根据设备找到工作中心;否则采用前面描述的工作中心分配机制; + # 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心; + + def _create_workorder(self): + for production in self: + print(production.product_id.model_type_id) + if not production.bom_id or not production.product_id: + continue + workorders_values = [] + + product_qty = production.product_uom_id._compute_quantity(production.product_qty, + production.bom_id.product_uom_id) + exploded_boms, dummy = production.bom_id.explode(production.product_id, + product_qty / production.bom_id.product_qty, + picking_type=production.bom_id.picking_type_id) + + for bom, bom_data in exploded_boms: + # If the operations of the parent BoM and phantom BoM are the same, don't recreate work orders. + if not (bom.operation_ids and (not bom_data['parent_line'] or bom_data[ + 'parent_line'].bom_id.operation_ids != bom.operation_ids)): + continue + for operation in bom.operation_ids: + if operation._skip_operation_line(bom_data['product']): + continue + workorders_values += [{ + 'name': operation.name, + 'production_id': production.id, + 'workcenter_id': operation.workcenter_id.id, + 'product_uom_id': production.product_uom_id.id, + 'operation_id': operation.id, + 'state': 'pending', + }] + production.workorder_ids = [(5, 0)] + [(0, 0, value) for value in workorders_values] + for workorder in production.workorder_ids: + workorder.duration_expected = workorder._get_duration_expected() + + class StockRule(models.Model): _inherit = 'stock.rule' - @api.model def _run_pull(self, procurements): moves_values_by_company = defaultdict(list) @@ -142,6 +186,7 @@ class StockRule(models.Model): moves = self.env['stock.move'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(moves_values) # Since action_confirm launch following procurement_group we should activate it. moves._action_confirm() + return True # @api.model @@ -256,5 +301,3 @@ class StockRule(models.Model): # mo_lists.append(vals) # # return mo_lists - - From 7067b29735a4725a68a44da18ce0161bee8b17e8 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Mon, 31 Oct 2022 17:34:44 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E7=B1=BB=E5=9E=8B=E8=AE=A1=E7=AE=97=E5=87=BA?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E7=9A=84=E8=83=9A=E6=96=99=E5=B0=BA=E5=AF=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/process.py | 15 +++- sf_base/models/product_template.py | 22 +++++- sf_base/security/ir.model.access.csv | 1 + sf_base/views/mrs_base_view.xml | 17 ++--- .../models/mrp_workorder.py | 70 ++++++++----------- .../models/sf_production.py | 1 - 6 files changed, 73 insertions(+), 53 deletions(-) diff --git a/sf_base/models/process.py b/sf_base/models/process.py index 05b7791c..ea97dac0 100644 --- a/sf_base/models/process.py +++ b/sf_base/models/process.py @@ -6,7 +6,7 @@ class ModelType(models.Model): _description = '模型类型' name = fields.Char('名称') - routing_tmpl_id = fields.One2many('mrp.routing.workcenter', 'model_type_id', '工序模板') + routing_tmpl_id = fields.One2many('sf.model.type.routing.sort', 'model_type_id', '工序模板') class ResMrpRoutingWorkcenter(models.Model): @@ -16,5 +16,16 @@ class ResMrpRoutingWorkcenter(models.Model): is_repeat = fields.Boolean('重复', default=False) workcenter_id = fields.Many2many('mrp.workcenter', required=False) bom_id = fields.Many2one('mrp.bom', required=False) - sort = fields.Integer('排序') + route_workcenter_sort_id = fields.Many2many('sf.model.type.routing.sort') + + +class ModelTypeRoutingSort(models.Model): + _name = 'sf.model.type.routing.sort' + _description = '工序排序' + + sequence = fields.Integer('Sequence') + + route_workcenter_id = fields.Many2many('mrp.routing.workcenter') model_type_id = fields.Many2one('sf.model.type') + + diff --git a/sf_base/models/product_template.py b/sf_base/models/product_template.py index 7535ae92..48c42996 100644 --- a/sf_base/models/product_template.py +++ b/sf_base/models/product_template.py @@ -1,4 +1,4 @@ -from odoo import models, fields +from odoo import models, fields,api from odoo.exceptions import ValidationError @@ -45,6 +45,22 @@ class ResProductTemplate(models.Model): copy_product_id.sudo().write(vals) return copy_product_id + # 在产品上增加模型类型和加工的面(例如:A、B) , + # 并根据模型类型计算出产品的胚料尺寸; + @api.onchange('model_type_id') + def count_embryo_size(self): + bom = self.env['mrp.bom.line'].search( + [('product_tmpl_id', '=', self.id)]) + for item in self: + print(bom.product_tmpl_id) + print(bom.model_long) + item.model_long = bom.model_long + 1 + print(item.model_long) + item.embryo_width = bom.embryo_width + 1 + item.embryo_height = bom.embryo_height + 1 + + + class ResProductCategory(models.Model): _inherit = "product.category" @@ -94,3 +110,7 @@ class ResMrpBom(models.Model): + + + + diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv index e94d9ea6..565b5faf 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -14,6 +14,7 @@ access_mrs_materials_model,mrs_materials_model,model_mrs_materials_model,base.gr access_mrs_processing_technology,mrs_processing_technology,model_mrs_processing_technology,base.group_user,1,1,1,1 access_sf_tray,sf_tray,model_sf_tray,base.group_user,1,1,1,1 access_sf_model_type,sf_model_type,model_sf_model_type,base.group_user,1,1,1,1 +access_sf_model_type_routing_sort,sf_model_type_routing_sort,model_sf_model_type_routing_sort,base.group_user,1,1,1,1 diff --git a/sf_base/views/mrs_base_view.xml b/sf_base/views/mrs_base_view.xml index 10c6a6b6..713173d4 100644 --- a/sf_base/views/mrs_base_view.xml +++ b/sf_base/views/mrs_base_view.xml @@ -523,16 +523,13 @@
- - - - - - - - - - + + + + + + + diff --git a/sf_manufacturing_orders/models/mrp_workorder.py b/sf_manufacturing_orders/models/mrp_workorder.py index 6469e23e..200ec6b2 100644 --- a/sf_manufacturing_orders/models/mrp_workorder.py +++ b/sf_manufacturing_orders/models/mrp_workorder.py @@ -7,40 +7,42 @@ from odoo.addons.stock.models.stock_rule import ProcurementException from odoo.tools import float_compare, OrderedSet -class StockRule(models.Model): +class ReStockRule(models.Model): _inherit = 'stock.rule' + def _run_manufacture(self, procurements): + productions_values_by_company = defaultdict(list) + errors = [] + for procurement, rule in procurements: + if float_compare(procurement.product_qty, 0, precision_rounding=procurement.product_uom.rounding) <= 0: + # If procurement contains negative quantity, don't create a MO that would be for a negative value. + continue + bom = rule._get_matching_bom(procurement.product_id, procurement.company_id, procurement.values) -def _run_manufacture(self, procurements): - productions_values_by_company = defaultdict(list) - errors = [] - for procurement, rule in procurements: - if float_compare(procurement.product_qty, 0, precision_rounding=procurement.product_uom.rounding) <= 0: - # If procurement contains negative quantity, don't create a MO that would be for a negative value. - continue - bom = rule._get_matching_bom(procurement.product_id, procurement.company_id, procurement.values) + productions_values_by_company[procurement.company_id.id].append(rule._prepare_mo_vals(*procurement, bom)) - productions_values_by_company[procurement.company_id.id].append(rule._prepare_mo_vals(*procurement, bom)) + if errors: + raise ProcurementException(errors) - if errors: - raise ProcurementException(errors) + for company_id, productions_values in productions_values_by_company.items(): + # create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example) + productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create( + productions_values) + self.env['stock.move'].sudo().create(productions._get_moves_raw_values()) + self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) + print(productions.product_id.processing_panel) + # 查出产品的加工面板并对根据面板的数量循环生成工序 + for k in (productions.product_id.processing_panel.split(',')): + print(productions.product_id.model_type_id.routing_tmpl_id) + for j in productions.product_id.model_type_id.routing_tmpl_id: + 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 company_id, productions_values in productions_values_by_company.items(): - # create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example) - productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create( - productions_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 in productions: - origin_production = production.move_dest_ids and production.move_dest_ids[ - 0].raw_material_production_id or False + 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( @@ -57,7 +59,7 @@ def _run_manufacture(self, procurements): 'mail.message_origin_link', values={'self': production, 'origin': origin_production}, subtype_id=self.env.ref('mail.mt_note').id) - return True + return True class ResMrpWorkOrder(models.Model): @@ -66,16 +68,6 @@ class ResMrpWorkOrder(models.Model): workcenter_id = fields.Many2one('mrp.workcenter', required=False) processing_panel = fields.Char('加工面') - @api.model_create_multi - def create(self, values): - res = super().create(values) - if self.env.context.get('skip_confirm'): - return res - to_confirm = res.filtered(lambda wo: wo.production_id.state in ("confirmed", "progress", "to_close")) - to_confirm = to_confirm.production_id.workorder_ids - to_confirm._action_confirm() - return res - def _action_confirm(self): workorders_by_production = defaultdict(lambda: self.env['mrp.workorder']) for workorder in self: diff --git a/sf_manufacturing_orders/models/sf_production.py b/sf_manufacturing_orders/models/sf_production.py index b02c895d..a41c65f6 100644 --- a/sf_manufacturing_orders/models/sf_production.py +++ b/sf_manufacturing_orders/models/sf_production.py @@ -42,7 +42,6 @@ class MrpProduction(models.Model): def _create_workorder(self): for production in self: - print(production.product_id.model_type_id) if not production.bom_id or not production.product_id: continue workorders_values = [] From ae85009a183113571bb004feb302fa4e4eb82f43 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Tue, 1 Nov 2022 17:30:25 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=B7=A5=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/__manifest__.py | 2 +- sf_base/data/process_data.xml | 94 +++++++++---------- sf_base/models/process.py | 22 +++-- sf_base/models/product_template.py | 13 +-- sf_base/security/ir.model.access.csv | 1 + sf_base/views/mrp_routing_workcenter_view.xml | 2 +- sf_base/views/mrs_base_view.xml | 13 ++- .../models/mrp_workorder.py | 4 +- .../models/sf_production.py | 2 + 9 files changed, 83 insertions(+), 70 deletions(-) diff --git a/sf_base/__manifest__.py b/sf_base/__manifest__.py index 5c5c2725..94c9da55 100644 --- a/sf_base/__manifest__.py +++ b/sf_base/__manifest__.py @@ -15,7 +15,7 @@ 'security/group_security.xml', 'security/ir.model.access.csv', 'data/product_data.xml', - 'data/process_data.xml', + # 'data/process_data.xml', 'views/mrs_base_view.xml', 'views/mrs_common_view.xml', 'views/menu_view.xml', diff --git a/sf_base/data/process_data.xml b/sf_base/data/process_data.xml index 4bc9cf25..066f4e45 100644 --- a/sf_base/data/process_data.xml +++ b/sf_base/data/process_data.xml @@ -1,52 +1,52 @@ - - - - - 获取自动编码程序 - automatic coding - manual - 60 - True - + + + + + + + + + + - - 装夹 - clamping - manual - 60 - True - + + + + + + + - - 前置三元定位检测 - pre-ternary - manual - 60 - True - + + + + + + + - - CNC加工 - CNC machining - manual - 60 - True - + + + + + + + - - 后置三元质量检测 - post ternary - manual - 60 - True - + + + + + + + - - 解除装夹 - remove the clamping - manual - 60 - True - - - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/sf_base/models/process.py b/sf_base/models/process.py index ea97dac0..4fec8c90 100644 --- a/sf_base/models/process.py +++ b/sf_base/models/process.py @@ -6,7 +6,7 @@ class ModelType(models.Model): _description = '模型类型' name = fields.Char('名称') - routing_tmpl_id = fields.One2many('sf.model.type.routing.sort', 'model_type_id', '工序模板') + routing_tmpl_ids = fields.One2many('sf.model.type.routing.sort', 'model_type_id', '工序模板') class ResMrpRoutingWorkcenter(models.Model): @@ -14,9 +14,16 @@ class ResMrpRoutingWorkcenter(models.Model): code = fields.Char('唯一编码') is_repeat = fields.Boolean('重复', default=False) - workcenter_id = fields.Many2many('mrp.workcenter', required=False) + workcenter_id = fields.Many2one('mrp.workcenter', required=False) + workcenter_ids = fields.Many2many('mrp.workcenter', 'rel_workcenter_route', required=True) bom_id = fields.Many2one('mrp.bom', required=False) - route_workcenter_sort_id = fields.Many2many('sf.model.type.routing.sort') + + # 获得当前登陆者公司 + def get_company_id(self): + company = self.env.ref('base.main_company') + return company.id + + company_id = fields.Many2one('res.company', default=lambda self: self.env.company) class ModelTypeRoutingSort(models.Model): @@ -24,8 +31,11 @@ class ModelTypeRoutingSort(models.Model): _description = '工序排序' sequence = fields.Integer('Sequence') - - route_workcenter_id = fields.Many2many('mrp.routing.workcenter') + route_workcenter_id = fields.Many2one('mrp.routing.workcenter') + is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat') + workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids') model_type_id = fields.Many2one('sf.model.type') - + _sql_constraints = [ + ('route_model_type_uniq', 'unique (route_workcenter_id,model_type_id)', '工序不能重复!') + ] diff --git a/sf_base/models/product_template.py b/sf_base/models/product_template.py index 48c42996..f3ecda1c 100644 --- a/sf_base/models/product_template.py +++ b/sf_base/models/product_template.py @@ -49,15 +49,16 @@ class ResProductTemplate(models.Model): # 并根据模型类型计算出产品的胚料尺寸; @api.onchange('model_type_id') def count_embryo_size(self): - bom = self.env['mrp.bom.line'].search( - [('product_tmpl_id', '=', self.id)]) + bom = self.env['product.product'].search( + [('categ_id.is_embryo', '=', True), ('product_tmpl_id', '=', self.id)], + limit=1, + order='volume desc' + ) for item in self: - print(bom.product_tmpl_id) - print(bom.model_long) - item.model_long = bom.model_long + 1 - print(item.model_long) + item.model_long = bom.embryo_long + 1 item.embryo_width = bom.embryo_width + 1 item.embryo_height = bom.embryo_height + 1 + item.volume = item.model_long * item.embryo_width * item.embryo_height diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv index 565b5faf..b9b1ca39 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -19,3 +19,4 @@ access_sf_model_type_routing_sort,sf_model_type_routing_sort,model_sf_model_type + diff --git a/sf_base/views/mrp_routing_workcenter_view.xml b/sf_base/views/mrp_routing_workcenter_view.xml index 3712561e..87fe49a7 100644 --- a/sf_base/views/mrp_routing_workcenter_view.xml +++ b/sf_base/views/mrp_routing_workcenter_view.xml @@ -7,7 +7,7 @@ - + diff --git a/sf_base/views/mrs_base_view.xml b/sf_base/views/mrs_base_view.xml index 713173d4..b7f61d4f 100644 --- a/sf_base/views/mrs_base_view.xml +++ b/sf_base/views/mrs_base_view.xml @@ -523,13 +523,12 @@ - - - - - - - + + + + + + diff --git a/sf_manufacturing_orders/models/mrp_workorder.py b/sf_manufacturing_orders/models/mrp_workorder.py index 200ec6b2..59f2626d 100644 --- a/sf_manufacturing_orders/models/mrp_workorder.py +++ b/sf_manufacturing_orders/models/mrp_workorder.py @@ -33,8 +33,8 @@ class ReStockRule(models.Model): print(productions.product_id.processing_panel) # 查出产品的加工面板并对根据面板的数量循环生成工序 for k in (productions.product_id.processing_panel.split(',')): - print(productions.product_id.model_type_id.routing_tmpl_id) - for j in productions.product_id.model_type_id.routing_tmpl_id: + print(productions.product_id.model_type_id.routing_tmpl_ids) + for j in productions.product_id.model_type_id.routing_tmpl_ids: productions._create_workorder() productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ ( diff --git a/sf_manufacturing_orders/models/sf_production.py b/sf_manufacturing_orders/models/sf_production.py index a41c65f6..e76ee80c 100644 --- a/sf_manufacturing_orders/models/sf_production.py +++ b/sf_manufacturing_orders/models/sf_production.py @@ -68,7 +68,9 @@ class MrpProduction(models.Model): 'operation_id': operation.id, 'state': 'pending', }] + print('1111111') production.workorder_ids = [(5, 0)] + [(0, 0, value) for value in workorders_values] + print('22222') for workorder in production.workorder_ids: workorder.duration_expected = workorder._get_duration_expected() From f2988ddffb72d3a984b3fbc5df996eedb4e29014 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 3 Nov 2022 15:01:15 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E5=B7=A5=E5=BA=8F?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=94=9F=E6=88=90=E5=B7=A5=E5=8D=95=EF=BC=8C?= =?UTF-8?q?=E5=8F=8A=E7=9B=B8=E5=85=B3=E9=A1=B5=E9=9D=A2=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=B7=A5=E9=9D=A2=E6=9D=BF=E5=8F=8A=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/process.py | 6 +- sf_base/models/product_template.py | 17 ++- sf_base/views/mrp_routing_workcenter_view.xml | 28 +++++ .../models/mrp_workorder.py | 109 +----------------- .../models/sf_production.py | 21 +++- 5 files changed, 63 insertions(+), 118 deletions(-) diff --git a/sf_base/models/process.py b/sf_base/models/process.py index 4fec8c90..c5d22873 100644 --- a/sf_base/models/process.py +++ b/sf_base/models/process.py @@ -12,7 +12,6 @@ class ModelType(models.Model): class ResMrpRoutingWorkcenter(models.Model): _inherit = 'mrp.routing.workcenter' - code = fields.Char('唯一编码') is_repeat = fields.Boolean('重复', default=False) workcenter_id = fields.Many2one('mrp.workcenter', required=False) workcenter_ids = fields.Many2many('mrp.workcenter', 'rel_workcenter_route', required=True) @@ -20,10 +19,9 @@ class ResMrpRoutingWorkcenter(models.Model): # 获得当前登陆者公司 def get_company_id(self): - company = self.env.ref('base.main_company') - return company.id + self.company_id = self.env.user.company_id.id - company_id = fields.Many2one('res.company', default=lambda self: self.env.company) + company_id = fields.Many2one('res.company', compute="get_company_id", related=False) class ModelTypeRoutingSort(models.Model): diff --git a/sf_base/models/product_template.py b/sf_base/models/product_template.py index f3ecda1c..45c46144 100644 --- a/sf_base/models/product_template.py +++ b/sf_base/models/product_template.py @@ -16,12 +16,17 @@ class ResProductTemplate(models.Model): model_type_id = fields.Many2one('sf.model.type', string='模型类型') processing_panel = fields.Char('模型加工面板') # 胚料的长,宽,高 - embryo_long = fields.Float('胚料长[mm]', digits=(16, 3)) - embryo_width = fields.Float('胚料宽[mm]', digits=(16, 3)) - embryo_height = fields.Float('胚料高[mm]', digits=(16, 3)) + embryo_long = fields.Float('胚料长[mm]', digits=(16, 3), onchange='count_embryo_size') + embryo_width = fields.Float('胚料宽[mm]', digits=(16, 3), onchange='count_embryo_size') + embryo_height = fields.Float('胚料高[mm]', digits=(16, 3), onchange='count_embryo_size') embryo_materials_id = fields.Many2one('mrs.production.materials', string='胚料材料') embryo_materials_type_id = fields.Many2one('mrs.materials.model', string='胚料材料型号') + volume = fields.Float(compute='_compute_volume', store=True) + + @api.depends('embryo_long', 'embryo_width', 'embryo_height') + def _compute_volume(self): + self.volume = self.embryo_long * self.embryo_width * self.embryo_height # 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品 def product_create(self, product_id, item, order_id, order_number, i): @@ -49,16 +54,18 @@ class ResProductTemplate(models.Model): # 并根据模型类型计算出产品的胚料尺寸; @api.onchange('model_type_id') def count_embryo_size(self): + if not self.model_type_id: + return bom = self.env['product.product'].search( [('categ_id.is_embryo', '=', True), ('product_tmpl_id', '=', self.id)], limit=1, order='volume desc' ) for item in self: - item.model_long = bom.embryo_long + 1 + item.embryo_long = bom.embryo_long + 1 item.embryo_width = bom.embryo_width + 1 item.embryo_height = bom.embryo_height + 1 - item.volume = item.model_long * item.embryo_width * item.embryo_height + diff --git a/sf_base/views/mrp_routing_workcenter_view.xml b/sf_base/views/mrp_routing_workcenter_view.xml index 87fe49a7..be0d32c8 100644 --- a/sf_base/views/mrp_routing_workcenter_view.xml +++ b/sf_base/views/mrp_routing_workcenter_view.xml @@ -1,6 +1,7 @@ + #-----------------作业------------------- mrp.routing.workcenter.form.inherit.sf mrp.routing.workcenter @@ -9,7 +10,34 @@ + + + + + #-----------------工单------------------- + + mrp.workorder.form.inherit.sf + mrp.workorder + + + + + + + + + #-----------------制造订单------------------- + + + + + + + + + + \ No newline at end of file diff --git a/sf_manufacturing_orders/models/mrp_workorder.py b/sf_manufacturing_orders/models/mrp_workorder.py index 59f2626d..164b1347 100644 --- a/sf_manufacturing_orders/models/mrp_workorder.py +++ b/sf_manufacturing_orders/models/mrp_workorder.py @@ -1,65 +1,9 @@ -from collections import defaultdict -from dateutil.relativedelta import relativedelta - from odoo import api, fields, models, SUPERUSER_ID, _ -from odoo.osv import expression -from odoo.addons.stock.models.stock_rule import ProcurementException -from odoo.tools import float_compare, OrderedSet -class ReStockRule(models.Model): - _inherit = 'stock.rule' - - def _run_manufacture(self, procurements): - productions_values_by_company = defaultdict(list) - errors = [] - for procurement, rule in procurements: - if float_compare(procurement.product_qty, 0, precision_rounding=procurement.product_uom.rounding) <= 0: - # If procurement contains negative quantity, don't create a MO that would be for a negative value. - continue - bom = rule._get_matching_bom(procurement.product_id, procurement.company_id, procurement.values) - - productions_values_by_company[procurement.company_id.id].append(rule._prepare_mo_vals(*procurement, bom)) - - if errors: - raise ProcurementException(errors) - - for company_id, productions_values in productions_values_by_company.items(): - # create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example) - productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create( - productions_values) - self.env['stock.move'].sudo().create(productions._get_moves_raw_values()) - self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) - print(productions.product_id.processing_panel) - # 查出产品的加工面板并对根据面板的数量循环生成工序 - for k in (productions.product_id.processing_panel.split(',')): - print(productions.product_id.model_type_id.routing_tmpl_ids) - for j in productions.product_id.model_type_id.routing_tmpl_ids: - 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 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) - return True +class ResWorkcenterProductivity(models.Model): + _inherit = 'mrp.workcenter.productivity' + workcenter_id = fields.Many2one('mrp.workcenter', required=False) class ResMrpWorkOrder(models.Model): @@ -67,50 +11,3 @@ class ResMrpWorkOrder(models.Model): workcenter_id = fields.Many2one('mrp.workcenter', required=False) processing_panel = fields.Char('加工面') - - def _action_confirm(self): - workorders_by_production = defaultdict(lambda: self.env['mrp.workorder']) - for workorder in self: - workorders_by_production[workorder.production_id] |= workorder - - for production, workorders in workorders_by_production.items(): - workorders_by_bom = defaultdict(lambda: self.env['mrp.workorder']) - bom = self.env['mrp.bom'] - moves = production.move_raw_ids | production.move_finished_ids - - for workorder in workorders: - bom = workorder.operation_id.bom_id or workorder.production_id.bom_id - previous_workorder = workorders_by_bom[bom][-1:] - previous_workorder.next_work_order_id = workorder.id - workorders_by_bom[bom] |= workorder - - moves.filtered(lambda m: m.operation_id == workorder.operation_id).write({ - 'workorder_id': workorder.id - }) - - exploded_boms, dummy = production.bom_id.explode(production.product_id, 1, - picking_type=production.bom_id.picking_type_id) - exploded_boms = {b[0]: b[1] for b in exploded_boms} - for move in moves: - if move.workorder_id: - continue - bom = move.bom_line_id.bom_id - while bom and bom not in workorders_by_bom: - bom_data = exploded_boms.get(bom, {}) - bom = bom_data.get('parent_line') and bom_data['parent_line'].bom_id or False - if bom in workorders_by_bom: - move.write({ - 'workorder_id': workorders_by_bom[bom][-1:].id - }) - else: - move.write({ - 'workorder_id': workorders_by_bom[production.bom_id][-1:].id - }) - - for workorders in workorders_by_bom.values(): - if not workorders: - continue - if workorders[0].state == 'pending': - workorders[0].state = 'ready' if workorders[0].production_availability == 'assigned' else 'waiting' - for workorder in workorders: - workorder._start_nextworkorder() diff --git a/sf_manufacturing_orders/models/sf_production.py b/sf_manufacturing_orders/models/sf_production.py index e76ee80c..0d82dcdd 100644 --- a/sf_manufacturing_orders/models/sf_production.py +++ b/sf_manufacturing_orders/models/sf_production.py @@ -68,9 +68,24 @@ class MrpProduction(models.Model): 'operation_id': operation.id, 'state': 'pending', }] - print('1111111') - production.workorder_ids = [(5, 0)] + [(0, 0, value) for value in workorders_values] - print('22222') + # 根据加工面板的面数及对应的工序模板生成工序 + for k in (production.product_id.processing_panel.split(',')): + for route in production.product_id.model_type_id.routing_tmpl_ids: + if route.route_workcenter_id: + workorders_values_str = [0, '', { + 'product_uom_id': production.product_uom_id.id, + 'qty_producing': 0, + 'operation_id': False, + 'name': route.route_workcenter_id.name, + 'processing_panel': k, + 'workcenter_id': False, + 'date_planned_start': False, + 'date_planned_finished': False, + 'duration_expected': 60, + 'duration': 0 + }] + workorders_values.append(workorders_values_str) + production.workorder_ids = workorders_values for workorder in production.workorder_ids: workorder.duration_expected = workorder._get_duration_expected()