From 412bf4b9be9f2a0663fc012c1138712b2187541b Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Fri, 24 May 2024 17:00:44 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=BF=94=E5=B7=A5?= =?UTF-8?q?=E5=92=8C=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 | 41 ++++++++++++-- sf_manufacturing/models/mrp_workorder.py | 55 +++++++++++-------- sf_manufacturing/models/product_template.py | 4 +- sf_manufacturing/models/stock.py | 2 +- sf_manufacturing/views/mrp_workorder_view.xml | 7 ++- sf_sale/models/quick_easy_order.py | 4 +- sf_sale/models/quick_easy_order_old.py | 4 +- 7 files changed, 79 insertions(+), 38 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 45808521..69f06d03 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -154,8 +154,30 @@ class MrpProduction(models.Model): for production in self: production.maintenance_count = len(production.request_ids) + # 制造订单报废:编程单更新 + def updateCNC(self): + try: + res = {'production_no': self.name, 'programming_no': self.programming_no, + 'order_no': self.origin} + 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']) + url = '/api/intelligent_programming/update_intelligent_programmings' + config_url = configsettings['sf_url'] + url + res['token'] = configsettings['token'] + ret = requests.post(config_url, json={}, data=res, headers=config_header) + ret = ret.json() + logging.info('updateCNC-ret:%s' % ret) + if ret['status'] == 1: + self.write({'work_state': '已编程'}) + else: + raise UserError(ret['message']) + except Exception as e: + logging.info('updateCNC error:%s' % e) + raise UserError("更新程单失败,请联系管理员") + # cnc程序获取 - def fetchCNC(self, production_names): + def fetchCNC(self, production_names, scrap_production): cnc = self.env['mrp.production'].search([('id', '=', self.id)]) quick_order = self.env['quick.easy.order'].search( [('name', '=', cnc.product_id.default_code.rsplit('-', 1)[0])]) @@ -171,6 +193,8 @@ class MrpProduction(models.Model): 'production_no': production_names, 'machine_tool_code': '', 'product_name': cnc.product_id.name, + 'remanufacture_type': '' if not scrap_production else scrap_production.workorder_ids.filtered( + lambda b: b.routing_type == "CNC加工").test_results, 'model_code': cnc.product_id.model_code, 'material_code': self.env['sf.production.materials'].search( [('id', '=', cnc.product_id.materials_id.id)]).materials_no, @@ -268,7 +292,7 @@ class MrpProduction(models.Model): # 则根据设备找到工作中心;否则采用前面描述的工作中心分配机制; # 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心; - def _create_workorder3(self): + def _create_workorder3(self, is_fetchcnc=False, scrap_production=False): # 根据product_id对self进行分组 grouped_product_ids = {k: list(g) for k, g in groupby(self, key=lambda x: x.product_id.id)} # 初始化一个字典来存储每个product_id对应的生产订单名称列表 @@ -312,10 +336,15 @@ class MrpProduction(models.Model): [('product_id.id', '=', production.product_id.id), ('origin', '=', production.origin)], limit=1, order='id asc') if not production_programming.programming_no: - production.fetchCNC(', '.join(product_id_to_production_names[production.product_id.id])) + # 制造订单报废/返工也需重新编程 + if (is_fetchcnc is True and scrap_production) or ( + is_fetchcnc is False and not scrap_production): + production.fetchCNC(', '.join(product_id_to_production_names[production.product_id.id]), + scrap_production) else: production.write({'programming_no': production_programming.programming_no, - 'programming_state': '已编程' if production_programming.programming_state == '已编程' else '编程中'}) + 'programming_state': '编程中'}) + # # 根据加工面板的面数及对应的工序模板生成工单 i = 0 processing_panel_len = len(production.product_id.model_processing_panel.split(',')) @@ -482,8 +511,8 @@ class MrpProduction(models.Model): # work.button_finish() # 创建工单并进行排序 - def _create_workorder(self): - self._create_workorder3() + def _create_workorder(self, is_fetchcnc=False, scrap_production=False): + self._create_workorder3(is_fetchcnc=is_fetchcnc, scrap_production=scrap_production) self._reset_work_order_sequence() return True diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index d389ba80..f5452aaf 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -199,7 +199,12 @@ class ResMrpWorkOrder(models.Model): production_line_state = fields.Selection(related='production_id.production_line_state', string='上/下产线', store=True) detection_report = fields.Binary('检测报告', readonly=True) - is_remanufacture = fields.Boolean(string='是否重新生成制造订单', default=True) + is_remanufacture = fields.Boolean(string='重新生成制造订单', default=False) + is_fetchcnc = fields.Boolean(string='重新获取NC程序', default=False) + reason = fields.Selection( + [("programming", "编程"), ("clamping", "返工"), ("cutter", "刀具"), ("operate computer", "操机"), + ("technology", "工艺"), ("customer redrawing", "客户改图"), ("other", "其他"), ], string="原因") + detailed_reason = fields.Text('详细原因') @api.onchange('rfid_code') def _onchange(self): @@ -672,14 +677,14 @@ class ResMrpWorkOrder(models.Model): """ 重新生成制造订单或者重新生成工单 """ - if self.test_results == '报废': + if self.test_results in ['返工', '报废']: values = self.env['mrp.production'].create_production1_values(self.production_id) productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company( self.production_id.company_id).create( 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._create_workorder(is_fetchcnc=self.is_fetchcnc, scrap_production=self.production_id) productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ ( p.move_dest_ids.procure_method != 'make_to_order' and @@ -772,13 +777,13 @@ class ResMrpWorkOrder(models.Model): 'product_id': productions.product_id.id, 'state': 'draft', }) - if self.test_results == '返工': - productions = self.production_id - # self.env['stock.move'].sudo().create(productions._get_moves_raw_values()) - # self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) - productions._create_workorder2(self.processing_panel) - else: - self.results = '合格' + # if self.test_results == '返工': + # productions = self.production_id + # # self.env['stock.move'].sudo().create(productions._get_moves_raw_values()) + # # self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) + # productions._create_workorder2(self.processing_panel) + # else: + # self.results = '合格' def json_workorder_str1(self, k, production, route): workorders_values_str = [0, '', { @@ -807,24 +812,23 @@ class ResMrpWorkOrder(models.Model): def _compute_state(self): super(ResMrpWorkOrder, self)._compute_state() for item in self: - scrap_workorder = self.env['mrp.workorder'].search( - [('production_id', '=', item.production_id.id), ('routing_type', '=', 'CNC加工'), - ('state', '=', 'done'), ('is_remanufacture', '=', True)]) print(item.name) print(item.state) - if item.name == 'CNC加工(返工)' and item.state not in ['ready', 'progress', 'done']: - item.state = 'ready' + print(item.is_remanufacture) + scrap_workorder = self.env['mrp.workorder'].search( + [('production_id', '=', item.production_id.id), ('routing_type', '=', 'CNC加工'), + ('state', '=', 'done'), ('test_results', 'in', ['返工', '报废'])]) + print(scrap_workorder) + # if item.routing_type == 'CNC加工' and item.state in ['done'] and item.test_results in ['返工', '报废']: if item.routing_type == '解除装夹': - last_workorder = self.env['mrp.workorder'].search( - [('production_id', '=', item.production_id.id), ('name', '=', 'CNC加工(返工)'), - ('state', '!=', 'done')]) - if item.state != 'pending': - if last_workorder: - item.state = 'pending' - if scrap_workorder: - item.state = 'cancel' + if scrap_workorder and item.state not in ['cancel']: + item.state = 'cancel' elif item.routing_type == '表面工艺': if scrap_workorder: + stock_move = self.env['stock.move'].search( + [('origin', '=', item.production_id.name)]) + stock_move.write({'state': 'cancel'}) + item.picking_ids.write({'state': 'cancel'}) item.state = 'cancel' # 重写工单开始按钮方法 @@ -991,7 +995,10 @@ class ResMrpWorkOrder(models.Model): 'date_planned_finished': tem_date_planned_finished # 保持原值 }) if record.routing_type == 'CNC加工' and record.test_results in ['返工', '报废']: - record.recreateManufacturingOrWorkerOrder() + record.production_id.write({'state': 'cancel'}) + record.production_id.workorder_ids.write({'rfid_code': False, 'rfid_code_old': record.rfid_code}) + if record.is_remanufacture is True: + record.recreateManufacturingOrWorkerOrder() is_production_id = True for workorder in record.production_id.workorder_ids: if workorder.state != 'done': diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 7d9bbac5..49a7e483 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -7,8 +7,8 @@ import os from odoo import models, fields, api, _ from odoo.exceptions import ValidationError 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 d8a5f41f..cc4999b7 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -207,7 +207,7 @@ class StockRule(models.Model): ''' 创建工单 ''' - productions._create_workorder() + productions._create_workorder(is_fetchcnc=False, scrap_production=False) productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ ( diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 30801086..d9cbf52c 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -214,7 +214,7 @@ attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/> - @@ -478,6 +478,11 @@ + + + diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py index 259655ee..775b901a 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 dc4c588f..f26b6f4a 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 fe88a416a7d42e0a9d6b4fdbc129f39339a8677d Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Tue, 28 May 2024 17:57:27 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E5=88=B6=E9=80=A0=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=B8=80=E5=BC=A0=E7=BC=96=E7=A8=8B=E5=8D=95?= =?UTF-8?q?=E4=B8=8B=E5=8F=91=E6=97=B6=EF=BC=8C=E5=B7=A5=E4=BB=B6=E9=85=8D?= =?UTF-8?q?=E9=80=81=E8=AE=B0=E5=BD=95=E7=9A=84=E6=9C=AA=E4=B8=8B=E5=8F=91?= =?UTF-8?q?nc=E7=A8=8B=E5=BA=8F=E4=B8=BA=E6=9C=AA=E4=B8=8B=E5=8F=91?= =?UTF-8?q?=E5=8F=8Acnc=E7=A8=8B=E5=BA=8F=E6=B2=A1=E6=9C=89=E5=AF=B9?= =?UTF-8?q?=E5=BA=94ftp=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 10 ++++++-- sf_manufacturing/models/mrp_workorder.py | 31 +++++++++++++++-------- sf_manufacturing/models/stock.py | 4 +-- sf_mrs_connect/controllers/controllers.py | 14 ++++++---- sf_mrs_connect/models/ftp_operate.py | 2 ++ 5 files changed, 42 insertions(+), 19 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 69f06d03..4ed3368f 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -335,10 +335,10 @@ class MrpProduction(models.Model): production_programming = self.search( [('product_id.id', '=', production.product_id.id), ('origin', '=', production.origin)], limit=1, order='id asc') - if not production_programming.programming_no: + if not production_programming.programming_no or (is_fetchcnc is True and scrap_production): # 制造订单报废/返工也需重新编程 if (is_fetchcnc is True and scrap_production) or ( - is_fetchcnc is False and not scrap_production): + is_fetchcnc is False and scrap_production): production.fetchCNC(', '.join(product_id_to_production_names[production.product_id.id]), scrap_production) else: @@ -408,6 +408,12 @@ class MrpProduction(models.Model): workorders_values.append( self.env['mrp.workorder'].json_workorder_str('', production, route)) production.workorder_ids = workorders_values + if is_fetchcnc is False and scrap_production: + production.write({'programming_no': scrap_production.programming_no, + 'programming_state': '已编程'}) + production.workorder_ids.filtered(lambda t: t.routing_type == 'CNC加工').write({ + 'cnc_ids': scrap_production.workorder_ids.filtered( + lambda t1: t1.routing_type == 'CNC加工').cnc_ids}) for workorder in production.workorder_ids: workorder.duration_expected = workorder._get_duration_expected() diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index f5452aaf..ea76896a 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -766,6 +766,7 @@ class ResMrpWorkOrder(models.Model): sale_order = self.env['sale.order'].sudo().search([('name', '=', productions.origin)]) if sale_order: + sale_order.mrp_production_ids |= productions # sale_order.write({'schedule_status': 'to schedule'}) self.env['sf.production.plan'].sudo().with_company(self.production_id.company_id).create({ 'name': productions.name, @@ -995,7 +996,7 @@ class ResMrpWorkOrder(models.Model): 'date_planned_finished': tem_date_planned_finished # 保持原值 }) if record.routing_type == 'CNC加工' and record.test_results in ['返工', '报废']: - record.production_id.write({'state': 'cancel'}) + record.production_id.action_cancel() record.production_id.workorder_ids.write({'rfid_code': False, 'rfid_code_old': record.rfid_code}) if record.is_remanufacture is True: record.recreateManufacturingOrWorkerOrder() @@ -1130,6 +1131,8 @@ class CNCprocessing(models.Model): 'cutting_tool_extension_length': obj['cutting_tool_extension_length'], 'cutting_tool_handle_type': obj['cutting_tool_handle_type'], 'estimated_processing_time': obj['estimated_processing_time'], + 'program_path': obj['program_path'], + 'cnc_id': obj['cnc_id'].id, 'remark': obj['remark'] }) return cnc_processing_str @@ -1137,19 +1140,27 @@ class CNCprocessing(models.Model): # 根据程序名和加工面匹配到ftp里对应的Nc程序名,可优化为根据cnc_processing.program_path进行匹配 def get_cnc_processing_file(self, serverdir, cnc_processing, program_path): logging.info('serverdir:%s' % serverdir) + logging.info('cnc_processing:%s' % cnc_processing) for root, dirs, files in os.walk(serverdir): for f in files: + logging.info('splitext(f):%s' % os.path.splitext(f)[1]) if os.path.splitext(f)[1] == ".pdf": full_path = os.path.join(serverdir, root, f) - if full_path is not False: - if not cnc_processing.workorder_id.cnc_worksheet: - cnc_processing.workorder_id.cnc_worksheet = base64.b64encode( - open(full_path, 'rb').read()) - else: - if f in program_path: - # if cnc_processing.program_name == f.split('.')[0]: - cnc_file_path = os.path.join(serverdir, root, f) - self.write_file(cnc_file_path, cnc_processing) + logging.info('full_path:%s' % full_path) + logging.info('routing_type:%s' % cnc_processing.workorder_id.routing_type) + logging.info('cnc_worksheet:%s' % cnc_processing.workorder_id.cnc_worksheet) + # with open(full_path, 'rb') as pdf_file: + # file_content = pdf_file.read() + # cnc_processing.workorder_id.cnc_worksheet = base64.b64encode(file_content) + if not cnc_processing.workorder_id.cnc_worksheet: + logging.info('full_path111555:%s' % full_path) + cnc_processing.workorder_id.cnc_worksheet = base64.b64encode( + open(full_path, 'rb').read()) + else: + if f in program_path: + # if cnc_processing.program_name == f.split('.')[0]: + cnc_file_path = os.path.join(serverdir, root, f) + self.write_file(cnc_file_path, cnc_processing) # 创建附件(nc文件) def attachment_create(self, name, data): diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index cc4999b7..806a13de 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -631,8 +631,8 @@ class ReStockMove(models.Model): 'reserved_uom_qty': 1.0, 'lot_id': purchase.picking_ids.move_line_ids.lot_id.id, 'company_id': self.company_id.id, - 'workorder_id': '' if not sorted_workorders else sorted_workorders.id, - 'production_id': '' if not sorted_workorders else sorted_workorders.production_id.id, + # 'workorder_id': '' if not sorted_workorders else sorted_workorders.id, + # 'production_id': '' if not sorted_workorders else sorted_workorders.production_id.id, 'state': 'assigned', } diff --git a/sf_mrs_connect/controllers/controllers.py b/sf_mrs_connect/controllers/controllers.py index 98c2d59e..08d6d9b4 100644 --- a/sf_mrs_connect/controllers/controllers.py +++ b/sf_mrs_connect/controllers/controllers.py @@ -63,12 +63,16 @@ class Sf_Mrs_Connect(http.Controller): logging.info('cnc_processing111:%s' % cnc_processing) if cnc_processing: cnc_processing_arr.append(cnc_processing._json_cnc_processing(cnc_processing)) - if cnc_program and cnc_processing_arr: + if (cnc_program and cnc_processing_arr) or (not cnc_program and cnc_processing_arr): logging.info('cnc_processing_arr:%s' % cnc_processing_arr) - cnc_program.write({'programming_state': '已编程', 'work_state': '已编程'}) - cnc_program.workorder_ids.filtered(lambda b: b.routing_type == 'CNC加工').write( - {'cnc_ids': cnc_processing_arr, 'cnc_worksheet': cnc_production.workorder_ids.filtered( - lambda b: b.routing_type == 'CNC加工').cnc_worksheet}) + if cnc_program and cnc_processing_arr: + cnc_program.write({'programming_state': '已编程', 'work_state': '已编程'}) + cnc_program.workorder_ids.filtered(lambda b: b.routing_type == 'CNC加工').write( + {'cnc_ids': cnc_processing_arr, 'cnc_worksheet': cnc_production.workorder_ids.filtered( + lambda b: b.routing_type == 'CNC加工').cnc_worksheet}) + cnc_program |= cnc_production + if not cnc_program and cnc_processing_arr: + cnc_program = cnc_production cnc_program_ids = [item.id for item in cnc_program] workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search( [('production_id', 'in', cnc_program_ids)]) diff --git a/sf_mrs_connect/models/ftp_operate.py b/sf_mrs_connect/models/ftp_operate.py index 8b547bb3..4cd5e3ba 100644 --- a/sf_mrs_connect/models/ftp_operate.py +++ b/sf_mrs_connect/models/ftp_operate.py @@ -46,6 +46,8 @@ class FtpController(): os.makedirs(serverdir) try: logging.info("进入FTP目录 ") + self.ftp.pwd() + logging.info('当前目录:%s' % self.ftp.pwd()) logging.info('目录:%s' % target_dir) target_dir1 = target_dir.split('/') logging.info('目录1:%s' % target_dir1[1]) From a1d8b88db25e1e07d586971e8503bdb89a377d03 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Wed, 29 May 2024 10:25:23 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index ea76896a..2c3510bd 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1069,7 +1069,7 @@ class CNCprocessing(models.Model): _order = 'sequence_number,id' cnc_id = fields.Many2one('ir.attachment') - sequence_number = fields.Char('序号') + sequence_number = fields.Integer('序号') program_name = fields.Char('程序名') functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型') cutting_tool_name = fields.Char('刀具名称') From 6fc94042ee57138a9e3a99eb457d078f4cab3a4d Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Tue, 4 Jun 2024 10:42:34 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E4=B8=AD=E6=8E=A7=E8=B0=83=E5=8F=96cnc?= =?UTF-8?q?=E5=B7=A5=E5=8D=95=E6=97=B6=EF=BC=8C=E5=B7=A5=E5=8D=95=E4=B8=8D?= =?UTF-8?q?=E5=AE=8C=E6=88=90=EF=BC=8C=E5=8A=A0=E5=B7=A5=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E4=B8=BA=E5=BD=93=E5=89=8D=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/controllers/controllers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py index 6ef8a38e..024c9f79 100644 --- a/sf_manufacturing/controllers/controllers.py +++ b/sf_manufacturing/controllers/controllers.py @@ -215,7 +215,7 @@ class Manufacturing_Connect(http.Controller): if workorder.state != 'progress': res = {'Succeed': False, 'ErrorCode': 202, 'Error': '该工单未开始'} return json.JSONEncoder().encode(res) - workorder.button_finish() + workorder.write({'date_finished': datetime.now()}) # workorder.process_state = '待解除装夹' # workorder.sudo().production_id.process_state = '待解除装夹' From 8bd5841d7a9861624e43c201b4f275f630e4c4c7 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Tue, 4 Jun 2024 15:59:35 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E9=87=8D=E5=86=99state?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_production.py | 1 + sf_manufacturing/models/mrp_workorder.py | 49 +++++++++++++---------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 68c7a0d7..3e155f78 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -77,6 +77,7 @@ class MrpProduction(models.Model): part_drawing = fields.Binary('零件图纸') manual_quotation = fields.Boolean('人工编程', default=False, readonly=True) + rework_production = fields.Many2one('mrp.production', string='返工的制造订单') @api.depends( 'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state', diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index b090d942..b0e31287 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -809,28 +809,28 @@ class ResMrpWorkOrder(models.Model): }] return workorders_values_str - @api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state') - def _compute_state(self): - super(ResMrpWorkOrder, self)._compute_state() - for item in self: - print(item.name) - print(item.state) - print(item.is_remanufacture) - scrap_workorder = self.env['mrp.workorder'].search( - [('production_id', '=', item.production_id.id), ('routing_type', '=', 'CNC加工'), - ('state', '=', 'done'), ('test_results', 'in', ['返工', '报废'])]) - print(scrap_workorder) - # if item.routing_type == 'CNC加工' and item.state in ['done'] and item.test_results in ['返工', '报废']: - if item.routing_type == '解除装夹': - if scrap_workorder and item.state not in ['cancel']: - item.state = 'cancel' - elif item.routing_type == '表面工艺': - if scrap_workorder: - stock_move = self.env['stock.move'].search( - [('origin', '=', item.production_id.name)]) - stock_move.write({'state': 'cancel'}) - item.picking_ids.write({'state': 'cancel'}) - item.state = 'cancel' + # @api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state') + # def _compute_state(self): + # super(ResMrpWorkOrder, self)._compute_state() + # for item in self: + # print(item.name) + # print(item.state) + # print(item.is_remanufacture) + # scrap_workorder = self.env['mrp.workorder'].search( + # [('production_id', '=', item.production_id.id), ('routing_type', '=', 'CNC加工'), + # ('state', '=', 'done'), ('test_results', 'in', ['返工', '报废'])]) + # print(scrap_workorder) + # # if item.routing_type == 'CNC加工' and item.state in ['done'] and item.test_results in ['返工', '报废']: + # if item.routing_type == '解除装夹': + # if scrap_workorder and item.state not in ['cancel']: + # item.state = 'cancel' + # elif item.routing_type == '表面工艺': + # if scrap_workorder: + # stock_move = self.env['stock.move'].search( + # [('origin', '=', item.production_id.name)]) + # stock_move.write({'state': 'cancel'}) + # item.picking_ids.write({'state': 'cancel'}) + # item.state = 'cancel' # 重写工单开始按钮方法 def button_start(self): @@ -987,6 +987,7 @@ class ResMrpWorkOrder(models.Model): raise UserError( '请先在产品中配置表面工艺为%s相关的外协服务产品' % item.surface_technics_parameters_id.name) tem_date_planned_finished = record.date_planned_finished + tem_date_finished = record.date_finished logging.info('routing_type:%s' % record.routing_type) super().button_finish() logging.info('date_planned_finished:%s' % record.date_planned_finished) @@ -995,6 +996,10 @@ class ResMrpWorkOrder(models.Model): record.write({ 'date_planned_finished': tem_date_planned_finished # 保持原值 }) + if record.routing_type == 'CNC加工': + record.write({ + 'date_finished': tem_date_finished # 保持原值 + }) if record.routing_type == 'CNC加工' and record.test_results in ['返工', '报废']: record.production_id.action_cancel() record.production_id.workorder_ids.write({'rfid_code': False, 'rfid_code_old': record.rfid_code}) From 71246af16a4a5e632f32cf42dd432181330fa636 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Wed, 5 Jun 2024 15:52:50 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E8=BF=98=E5=8E=9F=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/product_template.py | 4 ++-- sf_sale/models/quick_easy_order.py | 4 ++-- sf_sale/models/quick_easy_order_old.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 49a7e483..7d9bbac5 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -7,8 +7,8 @@ import os from odoo import models, fields, api, _ from odoo.exceptions import ValidationError 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_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py index 775b901a..259655ee 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 f26b6f4a..dc4c588f 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