From 7fee98cdee64f599f8a4d46c07135eeb782c8486 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Fri, 23 Aug 2024 16:13:03 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8A=A5=E5=BA=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/product_template.py | 4 ++-- sf_manufacturing/models/stock.py | 25 +++++++++++---------- sf_sale/models/quick_easy_order.py | 4 ++-- sf_sale/models/quick_easy_order_old.py | 4 ++-- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 071f1167..37fa02bd 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -9,8 +9,8 @@ from odoo.exceptions import ValidationError, UserError from odoo.modules import get_resource_path -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file class ResProductMo(models.Model): diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index f53d7056..a6aa3e96 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -151,6 +151,8 @@ class StockRule(models.Model): list2.append(item) for procurement, rule in list2: + logging.info(rule) + logging.info(rule.procure_method) procure_method = rule.procure_method if rule.procure_method == 'mts_else_mto': qty_needed = procurement.product_uom._compute_quantity(procurement.product_qty, @@ -169,7 +171,6 @@ class StockRule(models.Model): else: forecasted_qties_by_loc[rule.location_src_id][procurement.product_id.id] -= qty_needed procure_method = 'make_to_stock' - move_values = rule._get_stock_move_values(*procurement) move_values['procure_method'] = procure_method moves_values_by_company[procurement.company_id.id].append(move_values) @@ -350,17 +351,17 @@ class StockRule(models.Model): product_id_to_production_names) # # 同一个产品多个制造订单对应一个编程单和模型库 # # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递 - if not production_item.programming_no: - production_programming = self.env['mrp.production'].search( - [('product_id.id', '=', production_item.product_id.id), - ('origin', '=', production_item.origin)], - limit=1, order='id asc') - if not production_programming.programming_no: - production_item.fetchCNC( - ', '.join(product_id_to_production_names[production_item.product_id.id])) - else: - production_item.write({'programming_no': production_programming.programming_no, - 'programming_state': '编程中'}) + # if not production_item.programming_no: + # production_programming = self.env['mrp.production'].search( + # [('product_id.id', '=', production_item.product_id.id), + # ('origin', '=', production_item.origin)], + # limit=1, order='id asc') + # if not production_programming.programming_no: + # production_item.fetchCNC( + # ', '.join(product_id_to_production_names[production_item.product_id.id])) + # else: + # production_item.write({'programming_no': production_programming.programming_no, + # 'programming_state': '编程中'}) return True diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py index 081807a4..cb1886a1 100644 --- a/sf_sale/models/quick_easy_order.py +++ b/sf_sale/models/quick_easy_order.py @@ -8,8 +8,8 @@ from datetime import datetime import requests from odoo import http from odoo.http import request -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file from odoo import models, fields, api from odoo.modules import get_resource_path from odoo.exceptions import ValidationError, UserError diff --git a/sf_sale/models/quick_easy_order_old.py b/sf_sale/models/quick_easy_order_old.py index 3ae65db3..92f6cda2 100644 --- a/sf_sale/models/quick_easy_order_old.py +++ b/sf_sale/models/quick_easy_order_old.py @@ -6,8 +6,8 @@ import os from datetime import datetime from stl import mesh # from OCC.Core.GProp import GProp_GProps -from OCC.Extend.DataExchange import read_step_file -from OCC.Extend.DataExchange import write_stl_file +# from OCC.Extend.DataExchange import read_step_file +# from OCC.Extend.DataExchange import write_stl_file from odoo.addons.sf_base.commons.common import Common from odoo import models, fields, api from odoo.modules import get_resource_path From f1780181faf1d7fac121e79ec770b234b1f37b68 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Sun, 25 Aug 2024 17:36:07 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8A=A5=E5=BA=9F?= =?UTF-8?q?=E5=90=91=E5=AF=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/controllers/controllers.py | 12 ++++++------ sf_manufacturing/models/mrp_production.py | 9 ++++++--- sf_manufacturing/wizard/production_wizard.py | 1 + sf_manufacturing/wizard/production_wizard_views.xml | 11 +++++++++++ sf_sale/models/sale_order.py | 6 +++--- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py index 23be7d38..376101c9 100644 --- a/sf_manufacturing/controllers/controllers.py +++ b/sf_manufacturing/controllers/controllers.py @@ -620,12 +620,12 @@ class Manufacturing_Connect(http.Controller): # if is_free is True: # delivery_workpiece._delivery_avg() # logging.info('agv下发下产线任务下发完成') - if ret['IsComplete'] is True: - # 向AGV任务调度下发下产线任务 - workorders = request.env['mrp.workorder'].browse(workorder_ids) - request.env['sf.agv.scheduling'].add_scheduling(ret['DeviceId'], '下产线', workorders) - else: - res = {'Succeed': False, 'ErrorCode': 203, 'Error': '未传IsComplete字段'} + # if ret['IsComplete'] is True: + # # 向AGV任务调度下发下产线任务 + # workorders = request.env['mrp.workorder'].browse(workorder_ids) + # request.env['sf.agv.scheduling'].add_scheduling(ret['DeviceId'], '下产线', workorders) + # else: + # res = {'Succeed': False, 'ErrorCode': 203, 'Error': '未传IsComplete字段'} except RepeatTaskException as e: logging.info('AGVToProduct error:%s' % e) except Exception as e: diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 8e1f7199..964f34fe 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -241,7 +241,10 @@ class MrpProduction(models.Model): res = {'programming_no': programming_no_str} logging.info('res=%s:' % res) configsettings = self.env['res.config.settings'].get_values() - config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key']) + configsettings['token'] = 'ba301c9b-2216-11ef-9d97-f8b54deb92c1' + # configsettings['sf_secret_key'] = 'rAalgsVOhDpxIWzR' + # configsettings['sf_url'] = 'http://localhost:7069' + # config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key']) url = '/api/intelligent_programming/get_state' config_url = configsettings['sf_url'] + url ret = requests.post(config_url, json=res, data=None, headers=config_header) @@ -808,8 +811,8 @@ class MrpProduction(models.Model): 'target': 'new', 'context': { 'default_production_id': self.id, - 'default_programming_state': '编程中' if cloud_programming[ - 'programming_state'] != '已下发' else '已下发', + 'default_reprogramming_num': cloud_programming['reprogramming_num'], + 'default_programming_state': cloud_programming['programming_state'], 'default_is_reprogramming': True if cloud_programming['programming_state'] in ['已下发'] else False } } diff --git a/sf_manufacturing/wizard/production_wizard.py b/sf_manufacturing/wizard/production_wizard.py index 5700ea68..323db518 100644 --- a/sf_manufacturing/wizard/production_wizard.py +++ b/sf_manufacturing/wizard/production_wizard.py @@ -13,6 +13,7 @@ class ProductionWizard(models.TransientModel): _description = '制造订单向导' production_id = fields.Many2one('mrp.production', string='制造订单号') + reprogramming_num = fields.Integer('重新编程次数', default=0) is_reprogramming = fields.Boolean(string='申请重新编程', default=False) is_remanufacture = fields.Boolean(string='重新生成制造订单', default=True) programming_state = fields.Selection( diff --git a/sf_manufacturing/wizard/production_wizard_views.xml b/sf_manufacturing/wizard/production_wizard_views.xml index 1efef116..b6619811 100644 --- a/sf_manufacturing/wizard/production_wizard_views.xml +++ b/sf_manufacturing/wizard/production_wizard_views.xml @@ -12,6 +12,17 @@ 重新生成制造订单 +
+ 注意: 该制造订单产品已申请重新编程次数为,且当前编程状态为 + +
申请重新编程 = 1: self.env['purchase.order'].sudo().create({ 'partner_id': server_product.seller_ids.partner_id.id, 'origin': ','.join(production_process), From e662490cb57b39c84e1e9201fbd58a1e823cd1c3 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Mon, 26 Aug 2024 17:31:14 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8A=A5=E5=BA=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 75 ++++++++++----- sf_manufacturing/models/stock.py | 23 +++-- .../views/mrp_production_addional_change.xml | 13 +++ sf_manufacturing/views/mrp_workorder_view.xml | 2 +- sf_manufacturing/wizard/production_wizard.py | 5 +- .../wizard/production_wizard_views.xml | 14 +-- sf_mrs_connect/controllers/controllers.py | 94 +++++++++---------- 7 files changed, 137 insertions(+), 89 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 964f34fe..0f26a6d7 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -126,6 +126,31 @@ class MrpProduction(models.Model): manual_quotation = fields.Boolean('人工编程', default=False, readonly=True) is_scrap = fields.Boolean('是否报废', default=False) is_remanufacture = fields.Boolean('是否重新制造', default=False) + remanufacture_count = fields.Integer("重新制造订单数量", compute='_compute_remanufacture_production_ids') + remanufacture_production_id = fields.Many2one('mrp.production', string='') + + @api.depends('remanufacture_production_id') + def _compute_remanufacture_production_ids(self): + for production in self: + if production.remanufacture_production_id: + remanufacture_production = self.env['mrp.production'].search( + [('id', '=', production.remanufacture_production_id.id)]) + if remanufacture_production: + production.remanufacture_count = len(remanufacture_production) + else: + production.remanufacture_count = 0 + + def action_view_remanufacture_productions(self): + self.ensure_one() + mrp_production_ids = self.env['mrp.production'].search( + [('id', '=', self.remanufacture_production_id.id)]) + action = { + 'res_model': 'mrp.production', + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_id': mrp_production_ids[0], + } + return action @api.depends( 'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state', 'tool_state', @@ -242,9 +267,9 @@ class MrpProduction(models.Model): logging.info('res=%s:' % res) configsettings = self.env['res.config.settings'].get_values() configsettings['token'] = 'ba301c9b-2216-11ef-9d97-f8b54deb92c1' - # configsettings['sf_secret_key'] = 'rAalgsVOhDpxIWzR' - # configsettings['sf_url'] = 'http://localhost:7069' - # config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key']) + configsettings['sf_secret_key'] = 'rAalgsVOhDpxIWzR' + configsettings['sf_url'] = 'http://localhost:7069' + config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key']) url = '/api/intelligent_programming/get_state' config_url = configsettings['sf_url'] + url ret = requests.post(config_url, json=res, data=None, headers=config_header) @@ -812,7 +837,7 @@ class MrpProduction(models.Model): 'context': { 'default_production_id': self.id, 'default_reprogramming_num': cloud_programming['reprogramming_num'], - 'default_programming_state': cloud_programming['programming_state'], + 'default_programming_states': cloud_programming['programming_state'], 'default_is_reprogramming': True if cloud_programming['programming_state'] in ['已下发'] else False } } @@ -959,32 +984,19 @@ class MrpProduction(models.Model): move_values = {'product_description_variants': '', 'date_planned': datetime.now(), 'date_deadline': datetime.now(), - # 'move_dest_ids': self.env['stock.move'].search([('id', '=', move.id)]), 'move_dest_ids': move, - 'group_id': False, + 'group_id': move.group_id, 'route_ids': [], 'warehouse_id': self.warehouse_id, 'priority': 0, 'orderpoint_id': False, 'product_packaging_id': False} - rule = self.env['stock.rule'].search( - [('action', '=', 'pull'), ('procure_method', '=', 'mts_else_mto'), ( - 'location_dest_id', '=', self.env['stock.location'].search([('parent_path', '=', '2/5/')]).id), - ('location_src_id', '=', self.env['stock.location'].search( - [('barcode', '=', 'CP')]).id)]) - # origin = move._prepare_procurement_origin() procurement_requests.append(self.env['procurement.group'].Procurement( move.product_id, 1.0, move.product_uom, - self.env['stock.location'].search([('barcode', '=', 'CP')]), - rule and rule.name or "/", + move.location_id, move.rule_id and move.rule_id.name or "/", sale_order.name, move.company_id, move_values)) self.env['procurement.group'].run(procurement_requests, raise_user_error=not self.env.context.get('from_orderpoint')) - # self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) - # 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() productions = self.env['mrp.production'].sudo().search( [('origin', '=', self.origin)], order='id desc', limit=1) move = self.env['stock.move'].search([('origin', '=', productions.name)], order='id desc') @@ -1012,8 +1024,29 @@ class MrpProduction(models.Model): 'picking_id': sfp_move.picking_id.id, 'picking_type_id': sfp_move.picking_type_id.id, 'production_id': False}) productions.write({'programming_no': self.programming_no, 'is_remanufacture': True}) - productions.procurement_group_id.mrp_production_ids.move_dest_ids.write( - {'group_id': self.env['procurement.group'].search([('name', '=', sale_order.name)])}) + # productions.procurement_group_id.mrp_production_ids.move_dest_ids.write( + # {'group_id': self.env['procurement.group'].search([('name', '=', sale_order.name)])}) + stock_picking = None + pc_picking = self.env['stock.picking'].search( + [('origin', '=', productions.name), ('name', 'ilike', 'WH/PC/')]) + stock_picking = pc_picking + int_picking = self.env['stock.picking'].search( + [('origin', '=', productions.name), ('name', 'ilike', 'WH/INT/')]) + stock_picking |= int_picking + for pick in stock_picking: + if pick.move_ids: + product_type_id = pick.move_ids[0].product_id.categ_id + if product_type_id.name == '坯料': + location_id = self.env['stock.location'].search([('name', '=', '坯料存货区')]) + if not location_id: + logging.info(f'没有搜索到【坯料存货区】: {location_id}') + break + if pick.picking_type_id.name == '内部调拨': + if pick.location_dest_id.product_type != product_type_id: + pick.location_dest_id = location_id.id + elif pick.picking_type_id.name == '生产发料': + if pick.location_id.product_type != product_type_id: + pick.location_id = location_id.id scarp_process_parameter_workorder = self.env['mrp.workorder'].search( [('surface_technics_parameters_id', '!=', False), ('production_id', '=', self.id), ('is_subcontract', '=', True)]) diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index a6aa3e96..a0da7ba3 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -184,7 +184,6 @@ class StockRule(models.Model): logging.info(moves) # Since action_confirm launch following procurement_group we should activate it. moves._action_confirm() - return True @api.model @@ -351,17 +350,17 @@ class StockRule(models.Model): product_id_to_production_names) # # 同一个产品多个制造订单对应一个编程单和模型库 # # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递 - # if not production_item.programming_no: - # production_programming = self.env['mrp.production'].search( - # [('product_id.id', '=', production_item.product_id.id), - # ('origin', '=', production_item.origin)], - # limit=1, order='id asc') - # if not production_programming.programming_no: - # production_item.fetchCNC( - # ', '.join(product_id_to_production_names[production_item.product_id.id])) - # else: - # production_item.write({'programming_no': production_programming.programming_no, - # 'programming_state': '编程中'}) + if not production_item.programming_no: + production_programming = self.env['mrp.production'].search( + [('product_id.id', '=', production_item.product_id.id), + ('origin', '=', production_item.origin)], + limit=1, order='id asc') + if not production_programming.programming_no: + production_item.fetchCNC( + ', '.join(product_id_to_production_names[production_item.product_id.id])) + else: + production_item.write({'programming_no': production_programming.programming_no, + 'programming_state': '编程中'}) return True diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 99d27576..8213f483 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -201,6 +201,19 @@ data-hotkey="l"/> + + + + + + + + + + + + + +