From 0fb751ebbeff511915eb9cd94005f3e00fd334ff Mon Sep 17 00:00:00 2001 From: gqh Date: Tue, 25 Oct 2022 17:19:42 +0800 Subject: [PATCH 01/22] =?UTF-8?q?=E6=89=98=E7=9B=98=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E5=B7=A5=E5=8D=95=EF=BC=8C=E6=89=98=E7=9B=98=E7=94=9F=E6=88=90?= =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/sf_common.py | 4 +- sf_base/views/mrs_common_view.xml | 24 ++++---- sf_route_workcenter/__init__.py | 2 + sf_route_workcenter/__manifest__.py | 25 ++++++++ sf_route_workcenter/models/__init__.py | 2 + sf_route_workcenter/models/workcenter.py | 70 ++++++++++++++++++++++ sf_route_workcenter/views/sf_tray_view.xml | 28 +++++++++ sf_route_workcenter/views/sf_workorder.xml | 21 +++++++ 8 files changed, 164 insertions(+), 12 deletions(-) create mode 100644 sf_route_workcenter/__init__.py create mode 100644 sf_route_workcenter/__manifest__.py create mode 100644 sf_route_workcenter/models/__init__.py create mode 100644 sf_route_workcenter/models/workcenter.py create mode 100644 sf_route_workcenter/views/sf_tray_view.xml create mode 100644 sf_route_workcenter/views/sf_workorder.xml diff --git a/sf_base/models/sf_common.py b/sf_base/models/sf_common.py index 0d86e593..b1abf43b 100644 --- a/sf_base/models/sf_common.py +++ b/sf_base/models/sf_common.py @@ -72,9 +72,9 @@ class Tray(models.Model): _name = 'sf.tray' _description = '托盘' - code = fields.Char('编码') + code = fields.Char('编码',copy=False) name = fields.Char('名称') state = fields.Selection( [("空闲", "空闲"), ("占用", "占用"), ("报损", "报损")], - default=" ", string="状态") + default="空闲", string="状态") active = fields.Boolean('有效', default=True) diff --git a/sf_base/views/mrs_common_view.xml b/sf_base/views/mrs_common_view.xml index 1877de05..4f9374e1 100644 --- a/sf_base/views/mrs_common_view.xml +++ b/sf_base/views/mrs_common_view.xml @@ -281,14 +281,18 @@ sf.tray.search sf.tray - - - - - - - - + + + + + + + + + + + + @@ -308,11 +312,11 @@ sf.tray.form sf.tray +
- + - diff --git a/sf_route_workcenter/__init__.py b/sf_route_workcenter/__init__.py new file mode 100644 index 00000000..c081ee06 --- /dev/null +++ b/sf_route_workcenter/__init__.py @@ -0,0 +1,2 @@ +# -*-coding:utf-8-*- +from . import models diff --git a/sf_route_workcenter/__manifest__.py b/sf_route_workcenter/__manifest__.py new file mode 100644 index 00000000..8a4dffd0 --- /dev/null +++ b/sf_route_workcenter/__manifest__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +{ + 'name': '机企猫藏智能工厂 工序', + 'version': '1.0', + 'summary': '智能工厂工作中心工序', + 'sequence': 1, + 'description': """ +在本模块,同步资源库 + """, + 'category': 'YZ', + 'website': 'https://www.sf.cs.jikimo.com', + 'depends': ['mrp', 'sf_base'], + 'data': [ + 'views/sf_tray_view.xml', + 'views/sf_workorder.xml', + ], + 'demo': [ + ], + 'qweb': [ + ], + 'installable': True, + 'application': False, + 'auto_install': False, +} diff --git a/sf_route_workcenter/models/__init__.py b/sf_route_workcenter/models/__init__.py new file mode 100644 index 00000000..94d72e99 --- /dev/null +++ b/sf_route_workcenter/models/__init__.py @@ -0,0 +1,2 @@ +# -*-coding:utf-8-*- +from . import workcenter \ No newline at end of file diff --git a/sf_route_workcenter/models/workcenter.py b/sf_route_workcenter/models/workcenter.py new file mode 100644 index 00000000..eae2f56c --- /dev/null +++ b/sf_route_workcenter/models/workcenter.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Part of SmartGo. See LICENSE file for full copyright and licensing details. +import base64 +import logging + +import qrcode + +from io import BytesIO +from odoo import api, fields, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +class Tray(models.Model): + _inherit = 'sf.tray' + _description = '托盘' + + production_id = fields.Many2one('mrp.production', string='制造订单', + related='workorder_id.production_id') + workorder_id = fields.Many2one('mrp.workorder', string="工单") + qr_image = fields.Binary(string="托盘二维码", compute='compute_qr_image') + + @api.depends('code') + def compute_qr_image(self): + for item in self: + if not item.code: + item.qr_image = False + continue + qr = qrcode.QRCode( + version=1, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=10, + border=4, + ) + qr.add_data(item.code) + qr.make(fit=True) + img = qr.make_image() + temp = BytesIO() + img.save(temp, format='PNG') + qr_image = base64.b64encode(temp.getvalue()) + item.qr_image = qr_image + + +''' +工单绑定托盘信息 +''' + + +class MrpWorkOrder(models.Model): + _inherit = 'mrp.workorder' + _description = '工单' + + tray_id = fields.Many2one('sf.tray', string="托盘") + tray_code = fields.Char( + string='托盘编码', + related='tray_id.code') + tray_state = fields.Selection( + string='托盘状态', + related='tray_id.state') + + +''' +制造订单绑定托盘信息 +''' + + +class MrpProduction(models.Model): + _inherit = 'mrp.production' + _description = "制造订单" diff --git a/sf_route_workcenter/views/sf_tray_view.xml b/sf_route_workcenter/views/sf_tray_view.xml new file mode 100644 index 00000000..05cb382a --- /dev/null +++ b/sf_route_workcenter/views/sf_tray_view.xml @@ -0,0 +1,28 @@ + + + + 托盘二维码生成 + sf.tray + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sf_route_workcenter/views/sf_workorder.xml b/sf_route_workcenter/views/sf_workorder.xml new file mode 100644 index 00000000..c5b24711 --- /dev/null +++ b/sf_route_workcenter/views/sf_workorder.xml @@ -0,0 +1,21 @@ + + + + + 装夹工序工单 + mrp.workorder + + + + + + + + + + + + + + + \ No newline at end of file From c3a7a6c4d6b2e5c80665ce673fb11703fa0a7b2d Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Tue, 25 Oct 2022 17:30:13 +0800 Subject: [PATCH 02/22] =?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 03/22] =?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 ccb26bc4ec2aa4e329a60f8186a3fb51e286b818 Mon Sep 17 00:00:00 2001 From: gqh Date: Thu, 27 Oct 2022 17:24:08 +0800 Subject: [PATCH 04/22] =?UTF-8?q?=E6=89=98=E7=9B=98=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E5=87=BA=E6=9D=A1=E5=BD=A2=E7=A0=81=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_route_workcenter/__init__.py | 1 + sf_route_workcenter/__manifest__.py | 3 +- sf_route_workcenter/models/workcenter.py | 55 ++++++++++++++----- sf_route_workcenter/report/sf_tray_report.xml | 43 +++++++++++++++ sf_route_workcenter/views/sf_tray_view.xml | 27 +++------ 5 files changed, 97 insertions(+), 32 deletions(-) create mode 100644 sf_route_workcenter/report/sf_tray_report.xml diff --git a/sf_route_workcenter/__init__.py b/sf_route_workcenter/__init__.py index c081ee06..87c2fd17 100644 --- a/sf_route_workcenter/__init__.py +++ b/sf_route_workcenter/__init__.py @@ -1,2 +1,3 @@ # -*-coding:utf-8-*- from . import models +from . import report diff --git a/sf_route_workcenter/__manifest__.py b/sf_route_workcenter/__manifest__.py index 8a4dffd0..6cf239f2 100644 --- a/sf_route_workcenter/__manifest__.py +++ b/sf_route_workcenter/__manifest__.py @@ -10,10 +10,11 @@ """, 'category': 'YZ', 'website': 'https://www.sf.cs.jikimo.com', - 'depends': ['mrp', 'sf_base'], + 'depends': ['mrp', 'sf_base','hr_holidays'], 'data': [ 'views/sf_tray_view.xml', 'views/sf_workorder.xml', + 'report/sf_tray_report.xml' ], 'demo': [ ], diff --git a/sf_route_workcenter/models/workcenter.py b/sf_route_workcenter/models/workcenter.py index eae2f56c..3551680e 100644 --- a/sf_route_workcenter/models/workcenter.py +++ b/sf_route_workcenter/models/workcenter.py @@ -7,6 +7,9 @@ import qrcode from io import BytesIO from odoo import api, fields, models +import barcode +from barcode.writer import ImageWriter +from pystrich.code128 import Code128Encoder from odoo.exceptions import UserError _logger = logging.getLogger(__name__) @@ -17,8 +20,8 @@ class Tray(models.Model): _description = '托盘' production_id = fields.Many2one('mrp.production', string='制造订单', - related='workorder_id.production_id') - workorder_id = fields.Many2one('mrp.workorder', string="工单") + ) + qr_image = fields.Binary(string="托盘二维码", compute='compute_qr_image') @api.depends('code') @@ -27,22 +30,31 @@ class Tray(models.Model): if not item.code: item.qr_image = False continue - qr = qrcode.QRCode( - version=1, - error_correction=qrcode.constants.ERROR_CORRECT_L, - box_size=10, - border=4, - ) - qr.add_data(item.code) - qr.make(fit=True) - img = qr.make_image() + # 根据code动态生成二维码图片 + # qr = qrcode.QRCode( + # version=1, + # error_correction=qrcode.constants.ERROR_CORRECT_L, + # box_size=10, + # border=4, + # ) + # qr.add_data(item.code) + # qr.make(fit=True) + # img = qr.make_image() + # 生成条形码文件 + # bar = barcode.get("ean13", "123456789102", writer=ImageWriter()) + # a = bar.get_fullcode() + # b = bar.save('occ') + # 生成条形码图片 + partner_encoder = Code128Encoder(item.code) + # 转换bytes流 temp = BytesIO() - img.save(temp, format='PNG') + partner_encoder.save(temp) + # img.save(temp, format='PNG') qr_image = base64.b64encode(temp.getvalue()) item.qr_image = qr_image -''' +''' 工单绑定托盘信息 ''' @@ -58,6 +70,23 @@ class MrpWorkOrder(models.Model): tray_state = fields.Selection( string='托盘状态', related='tray_id.state') + # def get_tray_info(self): + + + @api.depends('tray_id') + def updateTrayState(self): + + for item in self: + if item.tray_code == False: + continue + trayInfo = self.env['sf.tray'].sudo.search([('code', '=', item.tray_code)]) + if trayInfo: + trayInfo.update( + { + 'production_id': item.production_id, + 'state': "占用", + } + ) ''' diff --git a/sf_route_workcenter/report/sf_tray_report.xml b/sf_route_workcenter/report/sf_tray_report.xml new file mode 100644 index 00000000..dcab9ee4 --- /dev/null +++ b/sf_route_workcenter/report/sf_tray_report.xml @@ -0,0 +1,43 @@ + + + + 打印条形码 + sf.tray + qweb-pdf + sf_route_workcenter.sf_tray_template + sf_route_workcenter.sf_tray_template + + report + + + + + + + European A4 for DIN5008 Type A + + A5 + Portrait + 27 + 40 + 20 + 10 + 70 + + 27 + + + diff --git a/sf_route_workcenter/views/sf_tray_view.xml b/sf_route_workcenter/views/sf_tray_view.xml index 05cb382a..f2d9f355 100644 --- a/sf_route_workcenter/views/sf_tray_view.xml +++ b/sf_route_workcenter/views/sf_tray_view.xml @@ -1,27 +1,18 @@ - 托盘二维码生成 + 托盘条形码生成 sf.tray - - - - - - - - - - - - - - - - - + + + + + + + + From 002653957e85df6474cb5078567f659d4cbf0ac1 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 27 Oct 2022 17:27:40 +0800 Subject: [PATCH 05/22] =?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 d3757871606554f87107ac51724d2a756a50f126 Mon Sep 17 00:00:00 2001 From: gqh Date: Mon, 31 Oct 2022 17:32:44 +0800 Subject: [PATCH 06/22] =?UTF-8?q?=E6=89=98=E7=9B=98=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E5=B7=A5=E5=8D=95=E7=BB=91=E5=AE=9A=E5=88=B6=E9=80=A0=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=EF=BC=8C=E4=BF=AE=E6=94=B9=E6=89=98=E7=9B=98=E7=8A=B6?= =?UTF-8?q?=E6=80=81=20=E6=B7=BB=E5=8A=A0=E8=A7=A3=E9=99=A4=E8=A3=85?= =?UTF-8?q?=E5=A4=B9=E5=8A=9F=E8=83=BD=20=E4=B8=89=E5=85=83=E5=AE=9A?= =?UTF-8?q?=E4=BD=8D=E5=A2=9E=E5=8A=A0xy=208=E4=B8=AA=E7=82=B9=E7=9A=84?= =?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_route_workcenter/models/workcenter.py | 70 +++++++++++++++---- sf_route_workcenter/report/sf_tray_report.xml | 39 ++++++----- sf_route_workcenter/views/sf_tray_view.xml | 12 +++- sf_route_workcenter/views/sf_workorder.xml | 70 ++++++++++++++++++- 4 files changed, 159 insertions(+), 32 deletions(-) diff --git a/sf_route_workcenter/models/workcenter.py b/sf_route_workcenter/models/workcenter.py index 3551680e..feccccb4 100644 --- a/sf_route_workcenter/models/workcenter.py +++ b/sf_route_workcenter/models/workcenter.py @@ -18,11 +18,26 @@ _logger = logging.getLogger(__name__) class Tray(models.Model): _inherit = 'sf.tray' _description = '托盘' + qr_image = fields.Binary(string="托盘二维码", compute='compute_qr_image') production_id = fields.Many2one('mrp.production', string='制造订单', + related='workorder_id.production_id' ) + workorder_id = fields.Many2one('mrp.workorder', string="工单" + ) - qr_image = fields.Binary(string="托盘二维码", compute='compute_qr_image') + @api.onchange('production_id') + def updateTrayState(self): + + if self.workorder_id != False: + self.state = '占用' + else: + self.state = '空闲' + + def unclamp(self): + self.workorder_id = False + self.production_id = False + self.state = '空闲' @api.depends('code') def compute_qr_image(self): @@ -70,23 +85,48 @@ class MrpWorkOrder(models.Model): tray_state = fields.Selection( string='托盘状态', related='tray_id.state') + # def get_tray_info(self): + @api.onchange('X_axis', 'Y_axis', 'Z_axis') + def get_center_point(self): + return 'X:%s,Y:%s,Z:%s' % (self.X_axis, self.Y_axis, self.Z_axis) + surface = fields.Selection([("上面", "上面"), ("下面", "下面"), ("左面", "左面"), ("右面", "右面"), + ("顶面", "顶面")], required=True, default="顶面") + material_center_point = fields.Char(string='配料中心点', default=get_center_point) + X1_axis = fields.Integer(string='x1', default=0) + Y1_axis = fields.Integer(string='y1', default=0) + X2_axis = fields.Integer(string='x2', default=0) + Y2_axis = fields.Integer(string='y2', default=0) + X3_axis = fields.Integer(string='x3', default=0) + Y3_axis = fields.Integer(string='y3', default=0) + X4_axis = fields.Integer(string='x4', default=0) + Y4_axis = fields.Integer(string='y4', default=0) + X5_axis = fields.Integer(string='x5', default=0) + Y5_axis = fields.Integer(string='y5', default=0) + X6_axis = fields.Integer(string='x6', default=0) + Y6_axis = fields.Integer(string='y6', default=0) + X7_axis = fields.Integer(string='x7', default=0) + Y7_axis = fields.Integer(string='y7', default=0) + X8_axis = fields.Integer(string='x8', default=0) + Y8_axis = fields.Integer(string='y8', default=0) - @api.depends('tray_id') - def updateTrayState(self): + X_deviation_angle = fields.Integer(string="X轴偏差度", default=0) - for item in self: - if item.tray_code == False: - continue - trayInfo = self.env['sf.tray'].sudo.search([('code', '=', item.tray_code)]) - if trayInfo: - trayInfo.update( - { - 'production_id': item.production_id, - 'state': "占用", - } - ) + # @api.depends('tray_id') + # def updateTrayState(self): + # + # for item in self: + # if item.tray_code == False: + # continue + # trayInfo = self.env['sf.tray'].sudo.search([('code', '=', item.tray_code)]) + # if trayInfo: + # trayInfo.update( + # { + # 'production_id': item.production_id, + # 'state': "占用", + # } + # ) ''' @@ -97,3 +137,5 @@ class MrpWorkOrder(models.Model): class MrpProduction(models.Model): _inherit = 'mrp.production' _description = "制造订单" + + tray_ids = fields.One2many('sf.tray', 'production_id', string="托盘") diff --git a/sf_route_workcenter/report/sf_tray_report.xml b/sf_route_workcenter/report/sf_tray_report.xml index dcab9ee4..d1af6676 100644 --- a/sf_route_workcenter/report/sf_tray_report.xml +++ b/sf_route_workcenter/report/sf_tray_report.xml @@ -1,5 +1,21 @@ + + + Dymo Label Sheet + + custom + 100 + 60 + Landscape + 0 + 0 + 0 + 0 + + 96 + + 打印条形码 sf.tray @@ -8,7 +24,7 @@ sf_route_workcenter.sf_tray_template report - + @@ -17,27 +33,18 @@
-

编码:

-
+
+
+ - - European A4 for DIN5008 Type A - - A5 - Portrait - 27 - 40 - 20 - 10 - 70 - - 27 - + + diff --git a/sf_route_workcenter/views/sf_tray_view.xml b/sf_route_workcenter/views/sf_tray_view.xml index f2d9f355..c9520f63 100644 --- a/sf_route_workcenter/views/sf_tray_view.xml +++ b/sf_route_workcenter/views/sf_tray_view.xml @@ -9,8 +9,18 @@ - + + + + +
+
+
+
diff --git a/sf_route_workcenter/views/sf_workorder.xml b/sf_route_workcenter/views/sf_workorder.xml index c5b24711..a12db9f0 100644 --- a/sf_route_workcenter/views/sf_workorder.xml +++ b/sf_route_workcenter/views/sf_workorder.xml @@ -6,7 +6,7 @@ mrp.workorder - + @@ -14,7 +14,75 @@ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
From 7067b29735a4725a68a44da18ce0161bee8b17e8 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Mon, 31 Oct 2022 17:34:44 +0800 Subject: [PATCH 07/22] =?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 08/22] =?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 09/22] =?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() From 3dfbd7a1e459e59797b6c829c46fe162dc4c9c91 Mon Sep 17 00:00:00 2001 From: gqh Date: Thu, 3 Nov 2022 15:09:36 +0800 Subject: [PATCH 10/22] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=B7=A5=E5=8D=95?= =?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/sf_base.py | 17 ++ sf_base/security/ir.model.access.csv | 1 + sf_route_workcenter/models/workcenter.py | 110 +++++++++--- sf_route_workcenter/views/sf_workorder.xml | 199 ++++++++++++++------- 4 files changed, 240 insertions(+), 87 deletions(-) diff --git a/sf_base/models/sf_base.py b/sf_base/models/sf_base.py index 453f6eb0..d10f190e 100644 --- a/sf_base/models/sf_base.py +++ b/sf_base/models/sf_base.py @@ -247,3 +247,20 @@ class CuttingToolType(models.Model): brand_id = fields.Many2one('mrs.machine.brand', string='品牌') remark = fields.Text('备注') active = fields.Boolean('有效', default=True) + +class CNCprocessing(models.Model): + _name = 'cnc.processing' + _description = "CNC加工" + + FNo = fields.Char(string="序号") + FPGName = fields.Char(string="程序名") + FKnifeName = fields.Char(string="刀具名称") + FDNo = fields.Char(string="刀号") + FWorkType = fields.Char(string="加工类型") + FXY = fields.Char(string="余量_X/Y") + FZ = fields.Char(string="余量_Z") + FJGSD = fields.Char(string="加工深度(Z)") + FSCCD = fields.Char(string="刀具伸出长度") + FDJSpec = fields.Char(string="刀柄型号") + FJGDate = fields.Char(string="预计加工时间") + FComment = fields.Char(string="备注") diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv index 5b4aa249..930fcd07 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -13,6 +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_cnc_processing,cnc_processing,model_cnc_processing,base.group_user,1,1,1,1 diff --git a/sf_route_workcenter/models/workcenter.py b/sf_route_workcenter/models/workcenter.py index feccccb4..4340b465 100644 --- a/sf_route_workcenter/models/workcenter.py +++ b/sf_route_workcenter/models/workcenter.py @@ -2,6 +2,7 @@ # Part of SmartGo. See LICENSE file for full copyright and licensing details. import base64 import logging +import math import qrcode @@ -15,6 +16,13 @@ from odoo.exceptions import UserError _logger = logging.getLogger(__name__) +class CNCprocessing(models.Model): + _inherit = 'cnc.processing' + _description = "CNC加工" + + workorder_id = fields.Many2one('mrp.workorder' ,string="工单") + + class Tray(models.Model): _inherit = 'sf.tray' _description = '托盘' @@ -87,32 +95,90 @@ class MrpWorkOrder(models.Model): related='tray_id.state') # def get_tray_info(self): - @api.onchange('X_axis', 'Y_axis', 'Z_axis') - def get_center_point(self): - return 'X:%s,Y:%s,Z:%s' % (self.X_axis, self.Y_axis, self.Z_axis) + # @api.onchange('X_axis', 'Y_axis', 'Z_axis') + # def get_center_point(self): + # return 'X:%s,Y:%s,Z:%s' % (self.X_axis, self.Y_axis, self.Z_axis) + # 加工面 + surface = fields.Selection([("前面", "前面"), ("后面", "后面"), ("左面", "左面"), ("右面", "右面"), + ("上面", "上面")], required=True, default="顶面", string="加工面") + material_center_point = fields.Char(string='配料中心点') + X1_axis = fields.Float(string='Lx1', default=0) + Y1_axis = fields.Float(string='Ly1', default=0) + Z1_axis = fields.Float(string='Lz1', default=0) + X2_axis = fields.Float(string='Lx2', default=0) + Y2_axis = fields.Float(string='Ly2', default=0) + Z2_axis = fields.Float(string='Lz2', default=0) + X3_axis = fields.Float(string='Fx3', default=0) + Y3_axis = fields.Float(string='Fy3', default=0) + Z3_axis = fields.Float(string='Fz3', default=0) + X4_axis = fields.Float(string='Fx4', default=0) + Y4_axis = fields.Float(string='Fy4', default=0) + Z4_axis = fields.Float(string='Fz4', default=0) + X5_axis = fields.Float(string='Rx5', default=0) + Y5_axis = fields.Float(string='Ry5', default=0) + Z5_axis = fields.Float(string='Rz5', default=0) + X6_axis = fields.Float(string='Rx6', default=0) + Y6_axis = fields.Float(string='Ry6', default=0) + Z6_axis = fields.Float(string='Rz6', default=0) + X7_axis = fields.Float(string='Bx7', default=0) + Y7_axis = fields.Float(string='By7', default=0) + Z7_axis = fields.Float(string='Bz7', default=0) + X8_axis = fields.Float(string='Bx8', default=0) + Y8_axis = fields.Float(string='By8', default=0) + Z8_axis = fields.Float(string='Bz8', default=0) + X9_axis = fields.Float(string='Uz9', default=0) + Y9_axis = fields.Float(string='Uz9', default=0) + Z9_axis = fields.Float(string='Uz9', default=0) + X10_axis = fields.Float(string='Uz10', default=0) + Y10_axis = fields.Float(string='Uz10', default=0) + Z10_axis = fields.Float(string='Uz10', default=0) - surface = fields.Selection([("上面", "上面"), ("下面", "下面"), ("左面", "左面"), ("右面", "右面"), - ("顶面", "顶面")], required=True, default="顶面") - material_center_point = fields.Char(string='配料中心点', default=get_center_point) - X1_axis = fields.Integer(string='x1', default=0) - Y1_axis = fields.Integer(string='y1', default=0) - X2_axis = fields.Integer(string='x2', default=0) - Y2_axis = fields.Integer(string='y2', default=0) - X3_axis = fields.Integer(string='x3', default=0) - Y3_axis = fields.Integer(string='y3', default=0) - X4_axis = fields.Integer(string='x4', default=0) - Y4_axis = fields.Integer(string='y4', default=0) - X5_axis = fields.Integer(string='x5', default=0) - Y5_axis = fields.Integer(string='y5', default=0) - X6_axis = fields.Integer(string='x6', default=0) - Y6_axis = fields.Integer(string='y6', default=0) - X7_axis = fields.Integer(string='x7', default=0) - Y7_axis = fields.Integer(string='y7', default=0) - X8_axis = fields.Integer(string='x8', default=0) - Y8_axis = fields.Integer(string='y8', default=0) + # 扫码绑定托盘方法 + def gettray(self): + return "" + + # 计算配料中心点和与x轴倾斜度方法 + def getcenter(self): + x1 = self.X1_axis + x2 = self.X2_axis + x3 = self.X3_axis + x4 = self.X4_axis + x5 = self.X5_axis + x6 = self.X6_axis + x7 = self.X7_axis + x8 = self.X8_axis + y1 = self.Y1_axis + y2 = self.Y2_axis + y3 = self.Y3_axis + y4 = self.Y4_axis + y5 = self.Y5_axis + y6 = self.Y6_axis + y7 = self.Y7_axis + y8 = self.Y8_axis + z1 = self.Z9_axis + x0 = ((x3 - x4) * (x2 * y1 - x1 * y2) - (x1 - x2) * (x4 * y3 - x3 * y4)) / ( + (x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4)) + y0 = ((y3 - y4) * (y2 * x1 - y1 * x2) - (y1 - y2) * (y4 * x3 - y3 * x4)) / ( + (y3 - y4) * (x1 - x2) - (y1 - y2) * (x3 - x4)) + x1 = ((x7 - x8) * (x6 * y5 - x5 * y7) - (x5 - x6) * (x8 * y7 - x7 * y8)) / ( + (x7 - x8) * (y5 - y6) - (x5 - x6) * (y7 - y8)); + y1 = ((y7 - y8) * (y6 * x5 - y5 * x7) - (y5 - y6) * (y8 * x7 - y7 * x8)) / ( + (y7 - y8) * (x5 - x6) - (y5 - y6) * (x7 - x8)) + x = (x0 + x1) / 2 + y = (y0 + y1) / 2 + z = z1 / 2 + + jd = math.atan2((x7 - x8), (y7 - y8)) + jdz = jd * 180 / math.pi + print("(%s,%s)" % (x, y)) + self.material_center_point = ("(%s,%s,%s)" % (x, y, z)) + self.X_deviation_angle = jdz X_deviation_angle = fields.Integer(string="X轴偏差度", default=0) + test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], string="检测结果") + + cnc_ids = fields.One2many("cnc.processing",'workorder_id', string="CNC加工") # @api.depends('tray_id') # def updateTrayState(self): # diff --git a/sf_route_workcenter/views/sf_workorder.xml b/sf_route_workcenter/views/sf_workorder.xml index a12db9f0..daa77756 100644 --- a/sf_route_workcenter/views/sf_workorder.xml +++ b/sf_route_workcenter/views/sf_workorder.xml @@ -6,82 +6,151 @@ mrp.workorder - - + + - - - + +
+
-
- + + - + - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ +
+ + + +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ + +
+
+ + +
+ + + + +
-
+
+ + + + + + + + + + + + + + + + + + + +
From 14d0d32ab685472968ef1766f6ce77d4141fe940 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 3 Nov 2022 17:58:33 +0800 Subject: [PATCH 11/22] =?UTF-8?q?=E5=8C=B9=E9=85=8D=E5=8A=A0=E5=B7=A5?= =?UTF-8?q?=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/process.py | 16 ++++++++++++ sf_base/security/ir.model.access.csv | 4 +-- sf_base/views/mrp_routing_workcenter_view.xml | 26 +++++++++---------- sf_base/views/mrs_common_view.xml | 24 +++-------------- .../models/mrp_workorder.py | 2 ++ .../models/sf_production.py | 9 +++---- sf_route_workcenter/models/workcenter.py | 4 +-- 7 files changed, 41 insertions(+), 44 deletions(-) diff --git a/sf_base/models/process.py b/sf_base/models/process.py index c5d22873..1a115333 100644 --- a/sf_base/models/process.py +++ b/sf_base/models/process.py @@ -23,6 +23,22 @@ class ResMrpRoutingWorkcenter(models.Model): company_id = fields.Many2one('res.company', compute="get_company_id", related=False) + # 工单对应的工作中心,根据工序中的工作中心去匹配, + # 如果只配置了一个工作中心,则默认采用该工作中心; + # 如果有多个工作中心, + # 则根据该工作中心的工单个数进行分配(优先分配给工单个数最少的); + # def get_workcenter(self, workcenter_ids): + # print(workcenter_ids[0].id) + # if workcenter_ids: + # if len(workcenter_ids) == 1: + # return workcenter_ids[0].id + # elif len(workcenter_ids) >= 2: + # workcenter_id = self.env['mrp.workorder'].search( + # [('workcenter_ids.id', 'in', True)], + # limit=1, + # group_by = + # ) + class ModelTypeRoutingSort(models.Model): _name = 'sf.model.type.routing.sort' diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv index ec0a074a..ad1cc554 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -13,12 +13,10 @@ 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 -<<<<<<< HEAD access_cnc_processing,cnc_processing,model_cnc_processing,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 ->>>>>>> 8e337dda97a98a9a8d0a892a2c39bc076640f6ac + diff --git a/sf_base/views/mrp_routing_workcenter_view.xml b/sf_base/views/mrp_routing_workcenter_view.xml index be0d32c8..dc5b328e 100644 --- a/sf_base/views/mrp_routing_workcenter_view.xml +++ b/sf_base/views/mrp_routing_workcenter_view.xml @@ -17,8 +17,8 @@ #-----------------工单------------------- - - mrp.workorder.form.inherit.sf + + mrp.production.workorder.tree.inherit.sf mrp.workorder @@ -28,16 +28,16 @@ - #-----------------制造订单------------------- - - - - - - - - - - + #-----------------制造订单的工单------------------- + + mrp.production.workorder.tree.editable.inherit.sf + mrp.workorder + + + + + + + \ No newline at end of file diff --git a/sf_base/views/mrs_common_view.xml b/sf_base/views/mrs_common_view.xml index f57d48a2..c5ab6744 100644 --- a/sf_base/views/mrs_common_view.xml +++ b/sf_base/views/mrs_common_view.xml @@ -277,7 +277,7 @@ #------------------托盘------------------ - + 托盘 ir.actions.act_window sf.tray @@ -293,27 +293,10 @@ sf.tray.search sf.tray -<<<<<<< HEAD - - - - - - - - - - - -======= - - ->>>>>>> 8e337dda97a98a9a8d0a892a2c39bc076640f6ac - @@ -333,7 +316,9 @@ sf.tray.form sf.tray -
+
+ +
@@ -348,6 +333,5 @@ - \ 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 164b1347..7997d82d 100644 --- a/sf_manufacturing_orders/models/mrp_workorder.py +++ b/sf_manufacturing_orders/models/mrp_workorder.py @@ -11,3 +11,5 @@ class ResMrpWorkOrder(models.Model): workcenter_id = fields.Many2one('mrp.workcenter', required=False) processing_panel = fields.Char('加工面') + + diff --git a/sf_manufacturing_orders/models/sf_production.py b/sf_manufacturing_orders/models/sf_production.py index 0d82dcdd..2dd8e42f 100644 --- a/sf_manufacturing_orders/models/sf_production.py +++ b/sf_manufacturing_orders/models/sf_production.py @@ -31,10 +31,6 @@ class MrpProduction(models.Model): # 重载根据工序生成工单的程序:如果产品BOM中没有工序时, # 根据产品对应的模板类型中工序,去生成工单; - # 工单对应的工作中心,根据工序中的工作中心去匹配, - # 如果只配置了一个工作中心,则默认采用该工作中心; - # 如果有多个工作中心, - # 则根据该工作中心的工单个数进行分配(优先分配给工单个数最少的); # CNC加工工序的选取规则: # 如果自动报价有带过来预分配的机床, # 则根据设备找到工作中心;否则采用前面描述的工作中心分配机制; @@ -68,10 +64,10 @@ class MrpProduction(models.Model): 'operation_id': operation.id, 'state': 'pending', }] - # 根据加工面板的面数及对应的工序模板生成工序 + # 根据加工面板的面数及对应的工序模板生成工单 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: + if route: workorders_values_str = [0, '', { 'product_uom_id': production.product_uom_id.id, 'qty_producing': 0, @@ -79,6 +75,7 @@ class MrpProduction(models.Model): 'name': route.route_workcenter_id.name, 'processing_panel': k, 'workcenter_id': False, + # 'workcenter_ids': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids), 'date_planned_start': False, 'date_planned_finished': False, 'duration_expected': 60, diff --git a/sf_route_workcenter/models/workcenter.py b/sf_route_workcenter/models/workcenter.py index 4340b465..a9ab568d 100644 --- a/sf_route_workcenter/models/workcenter.py +++ b/sf_route_workcenter/models/workcenter.py @@ -9,8 +9,8 @@ import qrcode from io import BytesIO from odoo import api, fields, models import barcode -from barcode.writer import ImageWriter -from pystrich.code128 import Code128Encoder +# from barcode.writer import ImageWriter +# from pystrich.code128 import Code128Encoder from odoo.exceptions import UserError _logger = logging.getLogger(__name__) From 65a7d74430786d05f6aabd067f37b34202777345 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Fri, 4 Nov 2022 16:08:43 +0800 Subject: [PATCH 12/22] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=E5=8A=A0=E5=B7=A5=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/process.py | 22 ++++++------ sf_base/views/mrp_routing_workcenter_view.xml | 34 +++++++++++++++---- .../models/sf_production.py | 3 +- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/sf_base/models/process.py b/sf_base/models/process.py index 1a115333..38fc6bc0 100644 --- a/sf_base/models/process.py +++ b/sf_base/models/process.py @@ -27,17 +27,17 @@ class ResMrpRoutingWorkcenter(models.Model): # 如果只配置了一个工作中心,则默认采用该工作中心; # 如果有多个工作中心, # 则根据该工作中心的工单个数进行分配(优先分配给工单个数最少的); - # def get_workcenter(self, workcenter_ids): - # print(workcenter_ids[0].id) - # if workcenter_ids: - # if len(workcenter_ids) == 1: - # return workcenter_ids[0].id - # elif len(workcenter_ids) >= 2: - # workcenter_id = self.env['mrp.workorder'].search( - # [('workcenter_ids.id', 'in', True)], - # limit=1, - # group_by = - # ) + def get_workcenter(self, workcenter_ids): + if workcenter_ids: + if len(workcenter_ids) == 1: + return workcenter_ids[0] + elif len(workcenter_ids) >= 2: + # workcenter_ids_str = ','.join([str(s) for s in workcenter_ids]) + self.env.cr.execute(""" + SELECT workcenter_id FROM mrp_workorder where workcenter_id + in %s group by workcenter_id + order by count(*),workcenter_id asc limit 1 """, [tuple(workcenter_ids)]) + return self.env.cr.dictfetchall()[0].get('workcenter_id') class ModelTypeRoutingSort(models.Model): diff --git a/sf_base/views/mrp_routing_workcenter_view.xml b/sf_base/views/mrp_routing_workcenter_view.xml index dc5b328e..a8d2fcc5 100644 --- a/sf_base/views/mrp_routing_workcenter_view.xml +++ b/sf_base/views/mrp_routing_workcenter_view.xml @@ -17,18 +17,40 @@ #-----------------工单------------------- - - mrp.production.workorder.tree.inherit.sf + + mrp.production.workorder.form.inherit.sf mrp.workorder - + - - + + - #-----------------制造订单的工单------------------- + + + + + + + + + + + + + + + + + + + + + + + #-----------------制造订单里的工单------------------- mrp.production.workorder.tree.editable.inherit.sf mrp.workorder diff --git a/sf_manufacturing_orders/models/sf_production.py b/sf_manufacturing_orders/models/sf_production.py index 2dd8e42f..c55cac6e 100644 --- a/sf_manufacturing_orders/models/sf_production.py +++ b/sf_manufacturing_orders/models/sf_production.py @@ -74,8 +74,7 @@ class MrpProduction(models.Model): 'operation_id': False, 'name': route.route_workcenter_id.name, 'processing_panel': k, - 'workcenter_id': False, - # 'workcenter_ids': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids), + 'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids), 'date_planned_start': False, 'date_planned_finished': False, 'duration_expected': 60, From a49a24e9e691d6884fa0c830cc50bd18438800bd Mon Sep 17 00:00:00 2001 From: gqh Date: Mon, 7 Nov 2022 10:59:22 +0800 Subject: [PATCH 13/22] =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/__manifest__.py | 9 +- sf_base/models/__init__.py | 7 +- sf_base/security/ir.model.access.csv | 5 -- sf_base/views/menu_view.xml | 14 +-- sf_base/views/mrs_base_view.xml | 66 +------------- sf_base/views/mrs_common_view.xml | 33 +++---- .../views/sale_process_order_view.xml | 30 +++---- sf_bpm_api/__manifest__.py | 7 +- sf_bpm_api/data/product_data.xml | 16 ++++ sf_bpm_api/models/__init__.py | 3 +- sf_bpm_api/models/product_template.py | 86 +++++++++++++++++++ sf_bpm_api/models/sale_order.py | 34 ++++++++ sf_bpm_api/security/ir.model.access.csv | 3 + sf_bpm_api/views/product_template_view.xml | 69 +++++++++++++++ sf_bpm_api/views/sale_order_view.xml | 15 ++++ sf_route_workcenter/models/workcenter.py | 25 +++--- sf_route_workcenter/views/sf_tray_view.xml | 3 +- sf_route_workcenter/views/sf_workorder.xml | 80 +++++++++++------ 18 files changed, 336 insertions(+), 169 deletions(-) create mode 100644 sf_bpm_api/data/product_data.xml create mode 100644 sf_bpm_api/models/product_template.py create mode 100644 sf_bpm_api/models/sale_order.py create mode 100644 sf_bpm_api/views/product_template_view.xml create mode 100644 sf_bpm_api/views/sale_order_view.xml diff --git a/sf_base/__manifest__.py b/sf_base/__manifest__.py index 94c9da55..77165cde 100644 --- a/sf_base/__manifest__.py +++ b/sf_base/__manifest__.py @@ -10,18 +10,13 @@ """, 'category': 'YZ', 'website': 'https://www.sf.jikimo.com', - 'depends': ['account', 'base', 'mrp', 'sale'], + 'depends': ['account', 'base', 'mrp'], 'data': [ 'security/group_security.xml', 'security/ir.model.access.csv', - 'data/product_data.xml', - # 'data/process_data.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', + "views/menu_view.xml" ], 'demo': [ diff --git a/sf_base/models/__init__.py b/sf_base/models/__init__.py index 0f189de6..27b447be 100644 --- a/sf_base/models/__init__.py +++ b/sf_base/models/__init__.py @@ -1,5 +1,2 @@ -from . import sf_base -from . import sf_common -from . import product_template -from . import sale_order -from . import process +from. import sf_base +from. import sf_common diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv index ec0a074a..930fcd07 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -13,12 +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 -<<<<<<< HEAD access_cnc_processing,cnc_processing,model_cnc_processing,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 ->>>>>>> 8e337dda97a98a9a8d0a892a2c39bc076640f6ac diff --git a/sf_base/views/menu_view.xml b/sf_base/views/menu_view.xml index 4babedb1..42c9602c 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/mrs_base_view.xml b/sf_base/views/mrs_base_view.xml index b7f61d4f..1d6aeaf3 100644 --- a/sf_base/views/mrs_base_view.xml +++ b/sf_base/views/mrs_base_view.xml @@ -355,11 +355,11 @@
-
- + - + @@ -407,7 +406,7 @@ - + @@ -490,61 +489,4 @@

- - #------------------模型类型------------------ - - - 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/mrs_common_view.xml b/sf_base/views/mrs_common_view.xml index f57d48a2..4f9374e1 100644 --- a/sf_base/views/mrs_common_view.xml +++ b/sf_base/views/mrs_common_view.xml @@ -277,23 +277,10 @@
#------------------托盘------------------ - - 托盘 - ir.actions.act_window - sf.tray - tree,form - -

- 创建托盘吧 -

-
-
- sf.tray.search sf.tray -<<<<<<< HEAD @@ -305,14 +292,6 @@ -======= - - - - - - ->>>>>>> 8e337dda97a98a9a8d0a892a2c39bc076640f6ac @@ -347,7 +326,17 @@
- + + 托盘 + ir.actions.act_window + sf.tray + tree,form + +

+ 创建托盘吧 +

+
+
\ No newline at end of file diff --git a/sf_bf_connect/views/sale_process_order_view.xml b/sf_bf_connect/views/sale_process_order_view.xml index 188a2767..898ade1b 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 0447a76b..b659bd14 100644 --- a/sf_bpm_api/__manifest__.py +++ b/sf_bpm_api/__manifest__.py @@ -10,10 +10,11 @@ """, 'category': 'sf', 'website': 'https://www.sf.cs.jikimo.com', - 'depends': ['sale', 'sf_base', 'mrp'], + 'depends': ['sale', 'sf_base'], 'data': [ - 'security/group_security.xml', - 'security/ir.model.access.csv', + 'data/product_data.xml', + 'views/product_template_view.xml', + 'views/sale_order_view.xml' ], 'demo': [ ], diff --git a/sf_bpm_api/data/product_data.xml b/sf_bpm_api/data/product_data.xml new file mode 100644 index 00000000..53fb6216 --- /dev/null +++ b/sf_bpm_api/data/product_data.xml @@ -0,0 +1,16 @@ + + + + + CNC加工产品模板 + + delivery + product + false + + + + false + + + \ No newline at end of file diff --git a/sf_bpm_api/models/__init__.py b/sf_bpm_api/models/__init__.py index 0d9a2937..4c183668 100644 --- a/sf_bpm_api/models/__init__.py +++ b/sf_bpm_api/models/__init__.py @@ -1,5 +1,6 @@ +from . import sale_order +from . import product_template from . import http from . import models - diff --git a/sf_bpm_api/models/product_template.py b/sf_bpm_api/models/product_template.py new file mode 100644 index 00000000..08f2237c --- /dev/null +++ b/sf_bpm_api/models/product_template.py @@ -0,0 +1,86 @@ +from odoo import models, fields +from odoo.exceptions import ValidationError + + +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_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='型号') + # 胚料的长,宽,高 + 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='型号') + + # 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品 + 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() + copy_product_id.product_tmpl_id.active = True + vals = { + 'name': '%s-%s' % (order_id.name, i), + 'model_long': item['model_long'], + 'model_width': item['model_width'], + 'model_height': item['model_height'], + 'model_volume': item['model_volume'], + 'list_price': item['price'], + 'model_materials_id': self.env['mrs.production.materials'].search( + [('materials_no', '=', item['texture_code'])]).id, + 'model_materials_type_id': self.env['mrs.materials.model'].search( + [('materials_no', '=', item['texture_type_code'])]).id, + 'default_code': '%s-%s' % (order_number, i), + 'barcode': item['barcode'], + 'active': True + } + copy_product_id.sudo().write(vals) + return copy_product_id + + +class ResProductCategory(models.Model): + _inherit = "product.category" + + is_embryo = fields.Boolean('胚料') + + +class ResMrpBom(models.Model): + _inherit = 'mrp.bom' + + # 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品后再次进行创建bom + def bom_create(self, product): + bom_id = self.env['mrp.bom'].create({ + 'product_tmpl_id': product.product_tmpl_id.id, + 'type': 'normal', + 'product_qty': 1, + 'product_uom_id': 1 + }) + return bom_id + + # 生成产品BOM匹配胚料,胚料的匹配规则: + # 一、匹配的胚料类别需要带有胚料的标签; + # 二、胚料的材料型号与生成产品的材料型号一致; + # 三、胚料的长宽高均要大于模型的长宽高; + # 四、如果匹配成功多个胚料,则选取体积最小的胚料; + def bom_create_Line(self, product): + embryo = self.env['product.product'].search( + [('categ_id.is_embryo', '=', True), ('embryo_materials_type_id', '=', product.model_materials_type_id.id), + ('embryo_long', '>', product.model_long), ('embryo_width', '>', product.model_width), + ('embryo_height', '>', product.model_height) + ], + limit=1, + order='volume desc' + ) + vals = { + 'bom_id': self.id, + 'product_id': embryo.id, + 'product_tmpl_id': embryo.product_tmpl_id.id, + 'product_qty': 1, + 'product_uom_id': 1 + } + return self.env['mrp.bom.line'].create(vals) diff --git a/sf_bpm_api/models/sale_order.py b/sf_bpm_api/models/sale_order.py new file mode 100644 index 00000000..1618a4e3 --- /dev/null +++ b/sf_bpm_api/models/sale_order.py @@ -0,0 +1,34 @@ +from odoo import models, fields +from odoo.exceptions import ValidationError +import datetime + + +class ReSaleOrder(models.Model): + _inherit = 'sale.order' + + deadline_of_delivery = fields.Date('交货截止日期') + + # 业务平台分配工厂后在智能工厂先创建销售订单 + def sale_order_create(self, deadline_of_delivery, company_id): + now_time = datetime.datetime.now() + order_id = self.env['sale.order'].sudo().create({ + 'company_id': company_id.id, + 'date_order': now_time, + 'name': self.env['ir.sequence'].next_by_code('sale.order', sequence_date=now_time), + 'partner_id': 8, + 'state': 'sale', + 'user_id': 6, + 'deadline_of_delivery': deadline_of_delivery + }) + return order_id + + # 业务平台分配工厂时在创建完产品后再创建销售明细信息 + def sale_order_create_line(self, product, item): + vals = { + 'order_id': self.id, + 'product_id': product.id, + 'name': '%s/%s/%s/%s/%s' % (item['model_long'], item['model_width'], item['model_height'], item['model_volume'], product.model_materials_id.name), + 'price_unit': item['price'], + 'product_uom_qty': item['number'] + } + return self.env['sale.order.line'].create(vals) diff --git a/sf_bpm_api/security/ir.model.access.csv b/sf_bpm_api/security/ir.model.access.csv index 08145a00..963679d4 100644 --- a/sf_bpm_api/security/ir.model.access.csv +++ b/sf_bpm_api/security/ir.model.access.csv @@ -1,2 +1,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink + + + diff --git a/sf_bpm_api/views/product_template_view.xml b/sf_bpm_api/views/product_template_view.xml new file mode 100644 index 00000000..406330e3 --- /dev/null +++ b/sf_bpm_api/views/product_template_view.xml @@ -0,0 +1,69 @@ + + + + + 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_bpm_api/views/sale_order_view.xml new file mode 100644 index 00000000..58abd5be --- /dev/null +++ b/sf_bpm_api/views/sale_order_view.xml @@ -0,0 +1,15 @@ + + + + + sale.order.form.inherit.sf + sale.order + + + + + + + + + \ No newline at end of file diff --git a/sf_route_workcenter/models/workcenter.py b/sf_route_workcenter/models/workcenter.py index 4340b465..6472598f 100644 --- a/sf_route_workcenter/models/workcenter.py +++ b/sf_route_workcenter/models/workcenter.py @@ -8,8 +8,7 @@ import qrcode from io import BytesIO from odoo import api, fields, models -import barcode -from barcode.writer import ImageWriter + from pystrich.code128 import Code128Encoder from odoo.exceptions import UserError @@ -20,7 +19,7 @@ class CNCprocessing(models.Model): _inherit = 'cnc.processing' _description = "CNC加工" - workorder_id = fields.Many2one('mrp.workorder' ,string="工单") + workorder_id = fields.Many2one('mrp.workorder', string="工单") class Tray(models.Model): @@ -86,21 +85,15 @@ class MrpWorkOrder(models.Model): _inherit = 'mrp.workorder' _description = '工单' - tray_id = fields.Many2one('sf.tray', string="托盘") - tray_code = fields.Char( - string='托盘编码', - related='tray_id.code') - tray_state = fields.Selection( - string='托盘状态', - related='tray_id.state') - + tray_ids = fields.One2many('sf.tray', 'workorder_id', string='托盘') # def get_tray_info(self): # @api.onchange('X_axis', 'Y_axis', 'Z_axis') # def get_center_point(self): # return 'X:%s,Y:%s,Z:%s' % (self.X_axis, self.Y_axis, self.Z_axis) # 加工面 surface = fields.Selection([("前面", "前面"), ("后面", "后面"), ("左面", "左面"), ("右面", "右面"), - ("上面", "上面")], required=True, default="顶面", string="加工面") + ("上面", "上面")], string="加工面1") + material_center_point = fields.Char(string='配料中心点') X1_axis = fields.Float(string='Lx1', default=0) Y1_axis = fields.Float(string='Ly1', default=0) @@ -178,7 +171,8 @@ class MrpWorkOrder(models.Model): test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], string="检测结果") - cnc_ids = fields.One2many("cnc.processing",'workorder_id', string="CNC加工") + cnc_ids = fields.One2many("cnc.processing", 'workorder_id', string="CNC加工") + # @api.depends('tray_id') # def updateTrayState(self): # @@ -193,6 +187,11 @@ class MrpWorkOrder(models.Model): # 'state': "占用", # } # ) + def recreateManufacturing(self): + return "" + + def recreateWorkerOrder(self): + return "" ''' diff --git a/sf_route_workcenter/views/sf_tray_view.xml b/sf_route_workcenter/views/sf_tray_view.xml index c9520f63..753b962c 100644 --- a/sf_route_workcenter/views/sf_tray_view.xml +++ b/sf_route_workcenter/views/sf_tray_view.xml @@ -14,7 +14,8 @@ attrs='{"invisible": [("production_id","=",False)]}'/> -
+
diff --git a/sf_route_workcenter/views/sf_workorder.xml b/sf_route_workcenter/views/sf_workorder.xml index daa77756..6d79a348 100644 --- a/sf_route_workcenter/views/sf_workorder.xml +++ b/sf_route_workcenter/views/sf_workorder.xml @@ -12,8 +12,10 @@
+ @@ -29,6 +31,8 @@ +
左面:
+
- +
前面:
+
-
-
- +
右面:
+
-
-
- +
下面:
+
-
-
- +
上面:
+
-
-
@@ -146,11 +154,27 @@ +
+
+
+
+ + + + + +
From 8776fc7d6c19526d551916ef6c503c1d27abc3cb Mon Sep 17 00:00:00 2001 From: gqh Date: Mon, 7 Nov 2022 11:21:31 +0800 Subject: [PATCH 14/22] =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/__init__.py | 3 +++ sf_base/security/ir.model.access.csv | 4 ---- sf_base/views/mrs_common_view.xml | 15 +++++---------- sf_route_workcenter/models/workcenter.py | 9 +-------- 4 files changed, 9 insertions(+), 22 deletions(-) diff --git a/sf_base/models/__init__.py b/sf_base/models/__init__.py index 27b447be..1314cbdf 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 process +from. import product_template +from. import sale_order diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv index 4cca247d..2422ae03 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -14,13 +14,9 @@ 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_cnc_processing,cnc_processing,model_cnc_processing,base.group_user,1,1,1,1 -<<<<<<< HEAD -======= 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 ->>>>>>> a33b16cf78ac96c7254fa26cd71610cc3aef97fa - diff --git a/sf_base/views/mrs_common_view.xml b/sf_base/views/mrs_common_view.xml index 0144b3b5..966bccec 100644 --- a/sf_base/views/mrs_common_view.xml +++ b/sf_base/views/mrs_common_view.xml @@ -277,8 +277,6 @@ #------------------托盘------------------ -<<<<<<< HEAD -======= 托盘 ir.actions.act_window @@ -291,13 +289,11 @@ ->>>>>>> a33b16cf78ac96c7254fa26cd71610cc3aef97fa sf.tray.search sf.tray -<<<<<<< HEAD - + @@ -309,12 +305,12 @@ -======= + ->>>>>>> a33b16cf78ac96c7254fa26cd71610cc3aef97fa + @@ -350,7 +346,7 @@ -<<<<<<< HEAD + 托盘 ir.actions.act_window @@ -362,8 +358,7 @@

-======= ->>>>>>> a33b16cf78ac96c7254fa26cd71610cc3aef97fa + \ No newline at end of file diff --git a/sf_route_workcenter/models/workcenter.py b/sf_route_workcenter/models/workcenter.py index a4d0d32b..8b0f9451 100644 --- a/sf_route_workcenter/models/workcenter.py +++ b/sf_route_workcenter/models/workcenter.py @@ -8,15 +8,8 @@ import qrcode from io import BytesIO from odoo import api, fields, models -<<<<<<< HEAD - from pystrich.code128 import Code128Encoder -======= -import barcode -# from barcode.writer import ImageWriter -# from pystrich.code128 import Code128Encoder ->>>>>>> a33b16cf78ac96c7254fa26cd71610cc3aef97fa -from odoo.exceptions import UserError + _logger = logging.getLogger(__name__) From cbf1cd8b0b95269ec2b861e15118c0948c0a8363 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Mon, 7 Nov 2022 15:39:26 +0800 Subject: [PATCH 15/22] =?UTF-8?q?=E5=B7=A5=E5=BA=8F=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=B7=A5=E5=BA=8F=E7=B1=BB=E5=9E=8B=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 | 7 +++++++ sf_base/views/mrp_routing_workcenter_view.xml | 1 + 2 files changed, 8 insertions(+) diff --git a/sf_base/models/process.py b/sf_base/models/process.py index 38fc6bc0..ede17d15 100644 --- a/sf_base/models/process.py +++ b/sf_base/models/process.py @@ -12,6 +12,13 @@ class ModelType(models.Model): class ResMrpRoutingWorkcenter(models.Model): _inherit = 'mrp.routing.workcenter' + routing_type = fields.Selection([ + ('装夹', '装夹'), + ('前置三元定位检测', '前置三元定位检测'), + ('CNC加工', 'CNC加工'), + ('置三元质量检测', '置三元质量检测'), + ('解除装夹', '解除装夹'), + ], string="工序类型") 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) diff --git a/sf_base/views/mrp_routing_workcenter_view.xml b/sf_base/views/mrp_routing_workcenter_view.xml index a8d2fcc5..e4912930 100644 --- a/sf_base/views/mrp_routing_workcenter_view.xml +++ b/sf_base/views/mrp_routing_workcenter_view.xml @@ -11,6 +11,7 @@ + From 7118596e1cd986021e5f425f52886b054ff64636 Mon Sep 17 00:00:00 2001 From: gqh Date: Mon, 7 Nov 2022 16:42:49 +0800 Subject: [PATCH 16/22] =?UTF-8?q?=E5=B7=A5=E5=8D=95=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=90=88=E5=B9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/__manifest__.py | 10 ++- sf_base/views/menu_view.xml | 14 ++-- sf_base/views/mrs_base_view.xml | 66 +++++++++++++++++-- sf_base/views/mrs_common_view.xml | 27 -------- sf_bpm_api/__manifest__.py | 3 +- .../models/sf_production.py | 24 ------- sf_route_workcenter/models/workcenter.py | 12 +++- sf_route_workcenter/views/sf_workorder.xml | 14 +++- 8 files changed, 100 insertions(+), 70 deletions(-) diff --git a/sf_base/__manifest__.py b/sf_base/__manifest__.py index 77165cde..967e1ba1 100644 --- a/sf_base/__manifest__.py +++ b/sf_base/__manifest__.py @@ -10,13 +10,19 @@ """, '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', 'views/mrs_base_view.xml', 'views/mrs_common_view.xml', - "views/menu_view.xml" + 'views/menu_view.xml', + 'views/sale_order_view.xml', + 'views/product_template_view.xml', + 'views/mrp_routing_workcenter_view.xml', + + ], 'demo': [ 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/mrs_base_view.xml b/sf_base/views/mrs_base_view.xml index 1d6aeaf3..b7f61d4f 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,61 @@

+ + #------------------模型类型------------------ + + + 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/mrs_common_view.xml b/sf_base/views/mrs_common_view.xml index 966bccec..c5ab6744 100644 --- a/sf_base/views/mrs_common_view.xml +++ b/sf_base/views/mrs_common_view.xml @@ -293,24 +293,10 @@ sf.tray.search sf.tray - - - - - - - - - - - - - - @@ -347,18 +333,5 @@ - - 托盘 - ir.actions.act_window - sf.tray - tree,form - -

- 创建托盘吧 -

-
-
- - \ No newline at end of file diff --git a/sf_bpm_api/__manifest__.py b/sf_bpm_api/__manifest__.py index b659bd14..f8e6070f 100644 --- a/sf_bpm_api/__manifest__.py +++ b/sf_bpm_api/__manifest__.py @@ -13,8 +13,7 @@ 'depends': ['sale', 'sf_base'], 'data': [ 'data/product_data.xml', - 'views/product_template_view.xml', - 'views/sale_order_view.xml' + ], 'demo': [ ], diff --git a/sf_manufacturing_orders/models/sf_production.py b/sf_manufacturing_orders/models/sf_production.py index c55cac6e..fcce77c1 100644 --- a/sf_manufacturing_orders/models/sf_production.py +++ b/sf_manufacturing_orders/models/sf_production.py @@ -99,30 +99,6 @@ class StockRule(models.Model): # in order to to batch the read. We also make a sanitary check on the # `location_src_id` field. - # list1 = [] - # for item in procurements: - # num = int(item[0].product_qty) - # if num > 1: - # for no in range(1, num+1): - # - # Procurement = namedtuple('Procurement', ['product_id', 'product_qty', - # 'product_uom', 'location_id', 'name', 'origin', - # 'company_id', - # 'values']) - # s = Procurement(product_id=item[0].product_id,product_qty=1.0,product_uom=item[0].product_uom, - # location_id=item[0].location_id, - # name=item[0].name, - # origin=item[0].origin, - # company_id=item[0].company_id, - # values=item[0].values, - # ) - # item1 = list(item) - # item1[0]=s - # - # list1.append(tuple(item1)) - # else: - # list1.append(item) - for procurement, rule in procurements: if not rule.location_src_id: msg = _('No source location defined on stock rule: %s!') % (rule.name,) diff --git a/sf_route_workcenter/models/workcenter.py b/sf_route_workcenter/models/workcenter.py index 8b0f9451..fc20a4e9 100644 --- a/sf_route_workcenter/models/workcenter.py +++ b/sf_route_workcenter/models/workcenter.py @@ -84,14 +84,15 @@ class MrpWorkOrder(models.Model): _inherit = 'mrp.workorder' _description = '工单' + cnc_id = fields.Many2one('ir.attachment', string='CNC程序') tray_ids = fields.One2many('sf.tray', 'workorder_id', string='托盘') # def get_tray_info(self): # @api.onchange('X_axis', 'Y_axis', 'Z_axis') # def get_center_point(self): # return 'X:%s,Y:%s,Z:%s' % (self.X_axis, self.Y_axis, self.Z_axis) # 加工面 - surface = fields.Selection([("前面", "前面"), ("后面", "后面"), ("左面", "左面"), ("右面", "右面"), - ("上面", "上面")], string="加工面1") + # surface = fields.Selection([("前面", "前面"), ("后面", "后面"), ("左面", "左面"), ("右面", "右面"), + # ("上面", "上面")], string="加工面1") material_center_point = fields.Char(string='配料中心点') X1_axis = fields.Float(string='Lx1', default=0) @@ -203,3 +204,10 @@ class MrpProduction(models.Model): _description = "制造订单" tray_ids = fields.One2many('sf.tray', 'production_id', string="托盘") + +class Attachment(models.Model): + _inherit = 'ir.attachment' + + cnc_model = fields.Binary('cnc文件', attachment=False) + model_name = fields.Char('模型名称') + diff --git a/sf_route_workcenter/views/sf_workorder.xml b/sf_route_workcenter/views/sf_workorder.xml index 6d79a348..f0b38b58 100644 --- a/sf_route_workcenter/views/sf_workorder.xml +++ b/sf_route_workcenter/views/sf_workorder.xml @@ -6,10 +6,20 @@ mrp.workorder + + + + + + + + + + - +