diff --git a/sf_base/__manifest__.py b/sf_base/__manifest__.py index 77165cde..94c9da55 100644 --- a/sf_base/__manifest__.py +++ b/sf_base/__manifest__.py @@ -10,13 +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/mrs_base_view.xml', 'views/mrs_common_view.xml', - "views/menu_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/data/process_data.xml b/sf_base/data/process_data.xml new file mode 100644 index 00000000..066f4e45 --- /dev/null +++ b/sf_base/data/process_data.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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..0f189de6 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 sf_base +from . import sf_common +from . import product_template +from . import sale_order +from . import process diff --git a/sf_base/models/process.py b/sf_base/models/process.py new file mode 100644 index 00000000..c5d22873 --- /dev/null +++ b/sf_base/models/process.py @@ -0,0 +1,39 @@ +from odoo import fields, models, api + + +class ModelType(models.Model): + _name = 'sf.model.type' + _description = '模型类型' + + name = fields.Char('名称') + routing_tmpl_ids = fields.One2many('sf.model.type.routing.sort', 'model_type_id', '工序模板') + + +class ResMrpRoutingWorkcenter(models.Model): + _inherit = 'mrp.routing.workcenter' + + 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) + bom_id = fields.Many2one('mrp.bom', required=False) + + # 获得当前登陆者公司 + def get_company_id(self): + self.company_id = self.env.user.company_id.id + + company_id = fields.Many2one('res.company', compute="get_company_id", related=False) + + +class ModelTypeRoutingSort(models.Model): + _name = 'sf.model.type.routing.sort' + _description = '工序排序' + + sequence = fields.Integer('Sequence') + 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_bpm_api/models/product_template.py b/sf_base/models/product_template.py similarity index 65% rename from sf_bpm_api/models/product_template.py rename to sf_base/models/product_template.py index 08f2237c..45c46144 100644 --- a/sf_bpm_api/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 @@ -6,19 +6,27 @@ 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_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), 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): @@ -42,6 +50,25 @@ 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): + 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.embryo_long = bom.embryo_long + 1 + item.embryo_width = bom.embryo_width + 1 + item.embryo_height = bom.embryo_height + 1 + + + + class ResProductCategory(models.Model): _inherit = "product.category" @@ -84,3 +111,14 @@ class ResMrpBom(models.Model): 'product_uom_id': 1 } return self.env['mrp.bom.line'].create(vals) + + + + + + + + + + + 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 930fcd07..ec0a074a 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -13,7 +13,12 @@ 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 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..be0d32c8 --- /dev/null +++ b/sf_base/views/mrp_routing_workcenter_view.xml @@ -0,0 +1,43 @@ + + + + #-----------------作业------------------- + + mrp.routing.workcenter.form.inherit.sf + mrp.routing.workcenter + + + + + + + + + + + + #-----------------工单------------------- + + mrp.workorder.form.inherit.sf + mrp.workorder + + + + + + + + + #-----------------制造订单------------------- + + + + + + + + + + + + \ 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..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 4f9374e1..f57d48a2 100644 --- a/sf_base/views/mrs_common_view.xml +++ b/sf_base/views/mrs_common_view.xml @@ -277,10 +277,23 @@ #------------------托盘------------------ + + 托盘 + ir.actions.act_window + sf.tray + tree,form + +

+ 创建托盘吧 +

+
+
+ sf.tray.search sf.tray +<<<<<<< HEAD @@ -292,6 +305,14 @@ +======= + + + + + + +>>>>>>> 8e337dda97a98a9a8d0a892a2c39bc076640f6ac @@ -326,17 +347,7 @@
- - 托盘 - ir.actions.act_window - sf.tray - 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 b659bd14..0447a76b 100644 --- a/sf_bpm_api/__manifest__.py +++ b/sf_bpm_api/__manifest__.py @@ -10,11 +10,10 @@ """, 'category': 'sf', 'website': 'https://www.sf.cs.jikimo.com', - 'depends': ['sale', 'sf_base'], + 'depends': ['sale', 'sf_base', 'mrp'], 'data': [ - 'data/product_data.xml', - 'views/product_template_view.xml', - 'views/sale_order_view.xml' + 'security/group_security.xml', + 'security/ir.model.access.csv', ], 'demo': [ ], diff --git a/sf_bpm_api/models/__init__.py b/sf_bpm_api/models/__init__.py index 4c183668..0d9a2937 100644 --- a/sf_bpm_api/models/__init__.py +++ b/sf_bpm_api/models/__init__.py @@ -1,6 +1,5 @@ -from . import sale_order -from . import product_template from . import http from . import models + diff --git a/sf_bpm_api/security/ir.model.access.csv b/sf_bpm_api/security/ir.model.access.csv index 963679d4..08145a00 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 - - - 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 406330e3..00000000 --- a/sf_bpm_api/views/product_template_view.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - product.template.form.inherit.sf - product.template - - - - - - - - - - - - - - - - - - - - - - - - - - - - product.category.form.inherit.sf - product.category - - - - - - - - - \ 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..164b1347 --- /dev/null +++ b/sf_manufacturing_orders/models/mrp_workorder.py @@ -0,0 +1,13 @@ +from odoo import api, fields, models, SUPERUSER_ID, _ + + +class ResWorkcenterProductivity(models.Model): + _inherit = 'mrp.workcenter.productivity' + workcenter_id = fields.Many2one('mrp.workcenter', required=False) + + +class ResMrpWorkOrder(models.Model): + _inherit = 'mrp.workorder' + + 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 6995005a..0d82dcdd 100644 --- a/sf_manufacturing_orders/models/sf_production.py +++ b/sf_manufacturing_orders/models/sf_production.py @@ -29,10 +29,70 @@ class MrpProduction(models.Model): _inherit = 'mrp.production' _description = "制造订单" + # 重载根据工序生成工单的程序:如果产品BOM中没有工序时, + # 根据产品对应的模板类型中工序,去生成工单; + # 工单对应的工作中心,根据工序中的工作中心去匹配, + # 如果只配置了一个工作中心,则默认采用该工作中心; + # 如果有多个工作中心, + # 则根据该工作中心的工单个数进行分配(优先分配给工单个数最少的); + # CNC加工工序的选取规则: + # 如果自动报价有带过来预分配的机床, + # 则根据设备找到工作中心;否则采用前面描述的工作中心分配机制; + # 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心; + + def _create_workorder(self): + for production in self: + 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', + }] + # 根据加工面板的面数及对应的工序模板生成工序 + 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() + + class StockRule(models.Model): _inherit = 'stock.rule' - @api.model def _run_pull(self, procurements): moves_values_by_company = defaultdict(list) @@ -142,6 +202,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 +317,3 @@ class StockRule(models.Model): # mo_lists.append(vals) # # return mo_lists - -