From 4f0c7ad274fc76b207343a7a8d4e52d1805f185b Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Tue, 16 Jan 2024 17:25:25 +0800 Subject: [PATCH 01/40] =?UTF-8?q?1.=E6=96=B0=E5=A2=9E=E6=9C=BA=E5=8F=B0?= =?UTF-8?q?=E6=97=A5=E8=AE=A1=E5=88=92=E6=8E=A5=E5=8F=A3=202.=E6=96=B0?= =?UTF-8?q?=E5=B7=A5=E4=BB=B6=E9=A2=84=E8=B0=83(=E5=89=8D=E7=BD=AE?= =?UTF-8?q?=E4=B8=89=E5=85=83=E6=A3=80=E6=B5=8B)=E6=8E=A5=E5=8F=A3=203.,?= =?UTF-8?q?=E6=96=B0NC=E7=A8=8B=E5=BA=8F=E4=B8=8B=E8=BD=BD=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/commons/common.py | 10 ++ sf_manufacturing/controllers/controllers.py | 107 +++++++++++++++++++- 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/sf_base/commons/common.py b/sf_base/commons/common.py index 05a2143f..6bf597cc 100644 --- a/sf_base/commons/common.py +++ b/sf_base/commons/common.py @@ -19,3 +19,13 @@ class Common(models.Model): 'TIMESTAMP': str(timestamp), 'checkstr': check_sf_str} return headers + + def get_add_time(self, parse_time): + """ + 把时间增加8小时 + :return: + """ + dt = datetime.datetime.strptime(parse_time, "%Y-%m-%d %H:%M:%S") + d = dt + datetime.timedelta(hours=8) + nTime = d.strftime("%Y-%m-%d %H:%M:%S") + return nTime diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py index c4fd6b87..b00c1324 100644 --- a/sf_manufacturing/controllers/controllers.py +++ b/sf_manufacturing/controllers/controllers.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- import logging import json -import base64 from odoo import http from odoo.http import request @@ -40,3 +39,109 @@ class Manufacturing_Connect(http.Controller): res = {'Succeed': False, 'ErrorCode': 202, 'Error': e} logging.info('get_Work_Info error:%s' % e) return json.JSONEncoder().encode(res) + + @http.route('/AutoDeviceApi/GetShiftPlan', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + cors="*") + def get_ShiftPlan(self, **kw): + """ + 自动化每天获取机台日计划 + :param kw: + :return: + """ + logging.info('get_ShiftPlan:%s' % kw) + try: + res = {'Succeed': True, 'Datas': []} + datas = request.httprequest.data + ret = json.loads(datas) + ret = json.loads(ret['result']) + logging.info('RfidCode:%s' % ret) + workorder = request.env['mrp.workorder'].sudo().search([('name', '=', ret['ProductionLine'])]) + if workorder: + for item in workorder: + date_planned_start = '' + date_planned_finished = '' + if item.date_planned_start is not False: + planned_start = item.date_planned_start.strftime("%Y-%m-%d %H:%M:%S") + date_planned_start = request.env['sf.sync.common'].sudo().get_add_time(planned_start) + if item.date_planned_finished is not False: + planned_finished = item.date_planned_finished.strftime("%Y-%m-%d %H:%M:%S") + date_planned_finished = request.env['sf.sync.common'].sudo().get_add_time(planned_finished) + res['Datas'].append({ + 'BillId': item.production_id.name, + 'RfidCode': item.RfidCode, + 'CraftName': item.name, + 'Quantity': 1, + 'WortkStart': date_planned_start, + 'WorkEnd': date_planned_finished, + 'MaterialId': item.product_id.default_code, + 'MaterialName': item.product_id.name, + # 'Spec':item.mat, + 'Material': item.materials_type_id.name + }) + except Exception as e: + res = {'Succeed': False, 'ErrorCode': 202, 'Error': e} + logging.info('get_ShiftPlan error:%s' % e) + return json.JSONEncoder().encode(res) + + @http.route('/AutoDeviceApi/QcCheck', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + cors="*") + def get_qcCheck(self, **kw): + """ + 工件预调(前置三元检测) + 1、前置三元检测在产线外:三元检测设备把测量信息上传给MES, + MES生成检测定位数据。中控系统传递RFID编号给MES获取测量偏置结果。(来源为三元检测工单上的字段) + :param kw: + :return: + """ + logging.info('get_qcCheck:%s' % kw) + try: + res = {'Succeed': True, 'Datas': []} + datas = request.httprequest.data + ret = json.loads(datas) + ret = json.loads(ret['result']) + logging.info('RfidCode:%s' % ret) + workorder = request.env['mrp.workorder'].sudo().search([('routing_type', '=', '前置三元定位检测')]) + if workorder: + for item in workorder: + res['Datas'].append({ + 'XOffset': item.production_id.name, + 'YOffset': item.RfidCode, + 'ZOffet': item.name, + 'COffset': 1 + }) + except Exception as e: + res = {'Succeed': False, 'ErrorCode': 202, 'Error': e} + logging.info('get_qcCheck error:%s' % e) + return json.JSONEncoder().encode(res) + + @http.route('/AutoDeviceApi/QcCheck', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + cors="*") + def get_qcCheck(self, **kw): + """ + 工件预调(前置三元检测) + 1、前置三元检测在产线外:三元检测设备把测量信息上传给MES, + MES生成检测定位数据。中控系统传递RFID编号给MES获取测量偏置结果。(来源为三元检测工单上的字段) + :param kw: + :return: + """ + logging.info('get_qcCheck:%s' % kw) + try: + res = {'Succeed': True, 'Datas': []} + datas = request.httprequest.data + ret = json.loads(datas) + ret = json.loads(ret['result']) + logging.info('RfidCode:%s' % ret) + workorder = request.env['mrp.workorder'].sudo().search([('routing_type', '=', '前置三元定位检测')]) + if workorder: + for item in workorder: + res['Datas'].append({ + 'XOffset': item.production_id.name, + 'YOffset': item.RfidCode, + 'ZOffet': item.name, + 'COffset': 1 + }) + except Exception as e: + res = {'Succeed': False, 'ErrorCode': 202, 'Error': e} + logging.info('get_qcCheck error:%s' % e) + return json.JSONEncoder().encode(res) + From 7520d71adbc629c7a7de41bd7984a7c3d849bcea Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Tue, 16 Jan 2024 17:30:59 +0800 Subject: [PATCH 02/40] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E6=9C=BA?= =?UTF-8?q?=E5=BA=8A=E6=A8=A1=E5=9E=8B=E7=9A=84=E6=A0=87=E5=87=86=E5=88=80?= =?UTF-8?q?=E5=BA=93=E5=AF=B9=E8=B1=A1=EF=BC=8C=E5=88=A0=E9=99=A4=E4=BA=86?= =?UTF-8?q?=E5=88=B6=E9=80=A0=E6=A8=A1=E5=9D=97=E4=B8=AD=E6=9C=BA=E5=BA=8A?= =?UTF-8?q?=E5=88=80=E4=BD=8D=E6=A8=A1=E5=9E=8B=E5=A4=A7=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=8C=E5=9C=A8=E5=88=80=E5=85=B7=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E6=A8=A1=E5=9D=97=E4=B8=AD=E9=80=9A=E8=BF=87=E7=BB=A7?= =?UTF-8?q?=E6=89=BF=E6=9C=BA=E5=BA=8A=E5=88=80=E4=BD=8D=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AD=97=E6=AE=B5=EF=BC=8C=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E6=9C=BA=E5=BA=8Afrom=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=88=80=E4=BD=8D=E7=9A=84tree=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E6=96=B0=E5=A2=9E=E5=A4=A7=E9=87=8F=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=EF=BC=9B2=E3=80=81=E5=88=80=E5=85=B7=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=96=B0=E5=A2=9Econtrollers=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E6=96=87=E4=BB=B6=EF=BC=8C=E6=96=B0=E5=A2=9E=E6=9C=BA?= =?UTF-8?q?=E5=BA=8A=E5=BD=93=E5=89=8D=E5=88=80=E5=BA=93=E5=AE=9E=E6=97=B6?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=8E=A5=E5=8F=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/product_template.py | 8 ++- .../views/sf_maintenance_equipment.xml | 13 +---- sf_tool_management/__init__.py | 1 + sf_tool_management/__manifest__.py | 1 + sf_tool_management/controllers/__init__.py | 1 + sf_tool_management/controllers/controllers.py | 56 +++++++++++++++++++ .../models/maintenance_equipment.py | 15 ++++- .../views/sf_maintenance_equipment.xml | 32 +++++++++++ sf_tool_management/wizard/wizard.py | 2 +- 9 files changed, 112 insertions(+), 17 deletions(-) create mode 100644 sf_tool_management/controllers/__init__.py create mode 100644 sf_tool_management/controllers/controllers.py create mode 100644 sf_tool_management/views/sf_maintenance_equipment.xml diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 42a392e2..b9209d57 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -870,6 +870,11 @@ class SfMaintenanceEquipmentTool(models.Model): _description = '机床刀位' equipment_id = fields.Many2one('maintenance.equipment', string='设备') + + code = fields.Char('机床刀位号') + name = fields.Char('刀位号', compute='_compute_name') + + # 待删除字段 product_template_id = fields.Many2one('product.template', string='功能刀具名称', domain="[('categ_type', '=', '刀具')]") image_1920 = fields.Binary('图片', related='product_template_id.image_1920') @@ -882,9 +887,6 @@ class SfMaintenanceEquipmentTool(models.Model): life_value_max = fields.Char('最大寿命值') alarm_value = fields.Char('报警值') used_value = fields.Char('已使用值') - code = fields.Char('机床刀位号') - - name = fields.Char('', compute='_compute_name') @api.depends('code') def _compute_name(self): diff --git a/sf_manufacturing/views/sf_maintenance_equipment.xml b/sf_manufacturing/views/sf_maintenance_equipment.xml index a2d9437d..b398f994 100644 --- a/sf_manufacturing/views/sf_maintenance_equipment.xml +++ b/sf_manufacturing/views/sf_maintenance_equipment.xml @@ -1,7 +1,7 @@ - + 设备增加刀具库位table sf_manufacturing_equipment.form maintenance.equipment @@ -13,17 +13,6 @@ - - - - - - - - - - - diff --git a/sf_tool_management/__init__.py b/sf_tool_management/__init__.py index fb05df81..ea8e8e0b 100644 --- a/sf_tool_management/__init__.py +++ b/sf_tool_management/__init__.py @@ -1,6 +1,7 @@ # -*-coding:utf-8-*- from . import models from . import wizard +from . import controllers from odoo import api, SUPERUSER_ID diff --git a/sf_tool_management/__manifest__.py b/sf_tool_management/__manifest__.py index e334c32a..faf3927b 100644 --- a/sf_tool_management/__manifest__.py +++ b/sf_tool_management/__manifest__.py @@ -16,6 +16,7 @@ 'security/ir.model.access.csv', 'wizard/wizard_view.xml', 'views/tool_base_views.xml', + 'views/sf_maintenance_equipment.xml', 'views/menu_view.xml', 'views/tool_material_search.xml', ], diff --git a/sf_tool_management/controllers/__init__.py b/sf_tool_management/controllers/__init__.py new file mode 100644 index 00000000..e046e49f --- /dev/null +++ b/sf_tool_management/controllers/__init__.py @@ -0,0 +1 @@ +from . import controllers diff --git a/sf_tool_management/controllers/controllers.py b/sf_tool_management/controllers/controllers.py new file mode 100644 index 00000000..0e60a57f --- /dev/null +++ b/sf_tool_management/controllers/controllers.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +import logging +import json +import base64 +from odoo import http +from odoo.http import request + + +class Manufacturing_Connect(http.Controller): + + @http.route('/AutoDeviceApi/FeedBackOut', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False, + cors="*") + def get_equipment_tool_Info(self, **kw): + """ + 机床当前刀库实时信息 + :param kw: + :return: + """ + logging.info('get_equipment_tool_Info:%s' % kw) + try: + datas = request.httprequest.data + ret = json.loads(datas) + ret = json.loads(ret['result']) + logging.info('DeviceId:%s' % ret) + equipment = request.env['maintenance.equipment'].sudo().search([('name', '=', ret['DeviceId'])]) + + res = {'Succeed': True, 'Datas': []} + if equipment: + for item in equipment: + data = [] + for equipment_tool_id in item.product_template_ids: + functional_tool_id = self.env['sf.functional.cutting.tool.entity'].sudo().search( + [('code', '=', equipment_tool_id.tool_code)]) + alarm_time = None + if functional_tool_id.functional_tool_status == '报警': + alarm_time = self.env['sf.functional.tool.warning'].sudo().search( + [('code', '=', equipment_tool_id.tool_code)]).alarm_time + equipment_tool = { + 'RfidCode': None, + 'ToolId': equipment_tool_id.code, + 'ToolName': equipment_tool_id.functional_tool_name_id.name, + 'MaxLife': equipment_tool_id.life_value_max, + 'UseLife': equipment_tool_id.used_value, + 'AddDatetime': equipment_tool_id.tool_install_time, + 'State': functional_tool_id.functional_tool_status, + 'WarnDate': alarm_time if alarm_time else False + } + data.append(equipment_tool) + res['Datas'].append({ + 'DeviceId': item.name, + 'Data': data + }) + except Exception as e: + res = {'Succeed': False, 'ErrorCode': 202, 'Error': e} + logging.info('get_equipment_tool_Info error:%s' % e) + return json.JSONEncoder().encode(res) diff --git a/sf_tool_management/models/maintenance_equipment.py b/sf_tool_management/models/maintenance_equipment.py index f5371a3f..1f42430c 100644 --- a/sf_tool_management/models/maintenance_equipment.py +++ b/sf_tool_management/models/maintenance_equipment.py @@ -1,9 +1,22 @@ -from odoo import models, api +from odoo import models, api, fields class SfMaintenanceEquipmentTool(models.Model): _inherit = 'maintenance.equipment.tool' + functional_tool_name_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具名称') + + image = fields.Binary('图片', related='functional_tool_name_id.image') + tool_code = fields.Char('功能刀具编码', related='functional_tool_name_id.code') + functional_tool_type = fields.Char('功能刀具类型', related='functional_tool_name_id.sf_cutting_tool_type_id.name') + tool_groups = fields.Char('刀具组', related='functional_tool_name_id.tool_groups_id.name') + diameter = fields.Integer('直径(mm)', related='functional_tool_name_id.functional_tool_diameter') + knife_tip_r_angle = fields.Float('刀尖R角(mm)', related='functional_tool_name_id.knife_tip_r_angle') + life_value_max = fields.Integer('最大寿命值(min)', related='functional_tool_name_id.max_lifetime_value') + alarm_value = fields.Integer('报警值(min)', related='functional_tool_name_id.alarm_value') + used_value = fields.Integer('已使用值(min)', related='functional_tool_name_id.used_value') + tool_install_time = fields.Datetime('机内装刀时间') + @api.model_create_multi def create(self, vals_list): tools = super().create(vals_list) diff --git a/sf_tool_management/views/sf_maintenance_equipment.xml b/sf_tool_management/views/sf_maintenance_equipment.xml new file mode 100644 index 00000000..fd863a84 --- /dev/null +++ b/sf_tool_management/views/sf_maintenance_equipment.xml @@ -0,0 +1,32 @@ + + + + + sf_manufacturing_equipment.form + maintenance.equipment + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sf_tool_management/wizard/wizard.py b/sf_tool_management/wizard/wizard.py index 396aa703..9f1a1aae 100644 --- a/sf_tool_management/wizard/wizard.py +++ b/sf_tool_management/wizard/wizard.py @@ -41,7 +41,7 @@ class ToolChangeRequirementInformation(models.TransientModel): replacement_tool_setting_length = fields.Float(string='待换刀具总长度(mm)', required=True) replacement_extension_length = fields.Float(string='待换刀具伸出长(mm)') replacement_effective_length = fields.Float(string='待换刀具有效长(mm)') - replacement_tool_coarse_middle_thin = fields.Selection([("1", "粗"), ('2', '中'), ('3', '精')], requirded=True, + replacement_tool_coarse_middle_thin = fields.Selection([("1", "粗"), ('2', '中'), ('3', '精')], required=True, string='待换刀具粗/中/精', default='3') replacement_max_lifetime_value = fields.Integer(string='待换刀具最大寿命值(min)') From d9115333bfdc75cdcf21f47ef7a3b8913ce91618 Mon Sep 17 00:00:00 2001 From: yuxianghui <3437689193@qq.com> Date: Wed, 17 Jan 2024 17:30:16 +0800 Subject: [PATCH 03/40] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96CAM=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=E7=A8=8B=E5=BA=8F=E7=94=A8=E5=88=80=E8=AE=A1=E5=88=92?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=EF=BC=8C=E6=96=B0=E5=A2=9E=E5=A4=A7=E9=87=8F?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=8C=E4=BC=98=E5=8C=96tree=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E5=8F=8Aform=E8=A7=86=E5=9B=BE=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=8F=8A=E5=85=B6=E5=B8=83=E5=B1=80=EF=BC=9B2=E3=80=81?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0CAM=E6=8D=A2=E5=88=80=E7=94=B3=E8=AF=B7?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=92=8C=E6=92=A4=E9=94=80=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=8F=8A=E5=85=B6=E6=8C=89=E9=92=AE=EF=BC=9B3=E3=80=81?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=A0=B9=E6=8D=AE=E5=88=80=E5=85=B7=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=92=8C=E5=88=80=E5=85=B7=E5=90=8D=E7=A7=B0=E6=A3=80?= =?UTF-8?q?=E7=B4=A2=E7=8E=B0=E6=9C=89=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E6=BB=A1=E8=B6=B3=E9=9C=80=E6=B1=82=EF=BC=8C?= =?UTF-8?q?=E5=A6=82=E6=9E=9C=E4=B8=8D=E6=BB=A1=E8=B6=B3=E5=88=99=E5=88=9B?= =?UTF-8?q?=E5=BB=BACAM=E5=B7=A5=E5=8D=95=E7=A8=8B=E5=BA=8F=E7=94=A8?= =?UTF-8?q?=E5=88=80=E8=AE=A1=E5=88=92=E8=AE=B0=E5=BD=95=E7=9A=84=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E6=8E=A5=E5=8F=A3(=E8=BF=9B=E8=A1=8C=E4=B8=AD)?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_tool_management/models/base.py | 69 +++++++--- sf_tool_management/views/tool_base_views.xml | 128 +++++++++++-------- 2 files changed, 125 insertions(+), 72 deletions(-) diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py index 39805f58..97447936 100644 --- a/sf_tool_management/models/base.py +++ b/sf_tool_management/models/base.py @@ -594,16 +594,16 @@ class CAMWorkOrderProgramKnifePlan(models.Model): _name = 'sf.cam.work.order.program.knife.plan' _description = 'CAM工单程序用刀计划' - name = fields.Char(string='工单任务编号', readonly=False) - cam_procedure_code = fields.Char(string='CAM程序编号', readonly=False) - cam_cutter_spacing_code = fields.Char(string='CAM刀位号', readonly=False) + name = fields.Char('工单任务编号') + cam_procedure_code = fields.Char('程序名') + filename = fields.Char('文件') + cam_cutter_spacing_code = fields.Char('刀号') tool_position_interface_type = fields.Selection( [('BT刀柄式', 'BT刀柄式'), ('SK刀柄式', 'SK刀柄式'), ('HSK刀柄式', 'HSK刀柄式'), ('CAT刀柄式', 'CAT刀柄式'), ('ISO刀盘式', 'ISO刀盘式'), ('DIN刀盘式', 'DIN刀盘式'), ('直装固定式', '直装固定式')], string='刀位接口型号') - production_line_id = fields.Many2one('sf.production.line', string='生产线', readonly=False, - group_expand='_read_group_names') - machine_table_name_id = fields.Many2one('maintenance.equipment', string='机床名称', readonly=False, + production_line_id = fields.Many2one('sf.production.line', string='生产线', group_expand='_read_group_names') + machine_table_name_id = fields.Many2one('maintenance.equipment', string='机床名称', domain="[('production_line_id', '=', production_line_id)]") machine_table_name = fields.Char(string='机台号', readonly=True, related='machine_table_name_id.name') cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', required=True, @@ -616,8 +616,9 @@ class CAMWorkOrderProgramKnifePlan(models.Model): barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', domain=[('product_id.name', '=', '功能刀具')]) - functional_tool_name = fields.Char(string='功能刀具名称', required=True) + functional_tool_name = fields.Char(string='功能刀具名称', compute='_compute_functional_tool_name') functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=False) + tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组') diameter = fields.Integer(string='刀具直径(mm)', readonly=False) tool_included_angle = fields.Float(string='刀尖R角(mm)', readonly=False) tool_loading_length = fields.Float(string='总长度(mm)', readonly=False) @@ -629,12 +630,28 @@ class CAMWorkOrderProgramKnifePlan(models.Model): L_D = fields.Float(string='L/D值', readonly=False) clearance_length = fields.Float(string='避空长(mm)', readonly=False) required_cutting_time = fields.Integer(string='需切削时长', readonly=False) + process_type = fields.Char('加工类型') + margin_x_y = fields.Float('余量_X/Y') + margin_z = fields.Float('余量_Z') + finish_depth = fields.Float('加工深度') + shank_model = fields.Char('刀柄型号') + estimated_processing_time = fields.Char('预计加工时间') plan_execute_status = fields.Selection([('0', '待下发'), ('1', '执行中'), ('2', '已完成')], string='计划执行状态', default='0', readonly=False) sf_functional_tool_assembly_id = fields.Many2one('sf.functional.tool.assembly', '功能刀具组装', readonly=True) + @api.depends('diameter', 'tool_included_angle', 'tool_groups_id') + def _compute_functional_tool_name(self): + for obj in self: + if obj.tool_groups_id: + obj.functional_tool_name = '%s-D%sR%s' % ( + obj.tool_groups_id.name, obj.diameter, + obj.tool_included_angle) + else: + obj.functional_tool_name = None + @api.model def _read_group_names(self, categories, domain, order): names = categories._search([], order=order, access_rights_uid=SUPERUSER_ID) @@ -646,27 +663,34 @@ class CAMWorkOrderProgramKnifePlan(models.Model): :return: """ record = self.env['sf.functional.tool.assembly'].create({ - 'barcode_id': self.barcode_id.id, - 'functional_tool_name_id': self.functional_tool_name_id.id, + 'functional_tool_name': self.functional_tool_name, 'functional_tool_type_id': self.functional_tool_type_id.id, + 'tool_groups_id': self.tool_groups_id.id, 'functional_tool_diameter': self.diameter, - 'functional_tool_length': self.tool_loading_length, - 'loading_task_source': '0', - 'coarse_middle_thin': None, - 'tool_loading_length': None, - 'applicant': self.env.user.name, - 'reason_for_applying': self.reason_for_applying, - 'use_tool_time': self.need_knife_time, + 'knife_tip_r_angle': self.tool_included_angle, + 'tool_loading_length': self.tool_loading_length, + 'functional_tool_length': self.extension_length, + 'effective_length': self.effective_length, + 'whether_standard_knife': self.whether_standard_knife, + 'coarse_middle_thin': self.coarse_middle_thin, + 'new_former': self.new_former, + 'production_line_name_id': self.production_line_id.id, 'machine_tool_name_id': self.machine_table_name_id.id, - 'machine_tool_code': self.cam_procedure_code, - 'cutter_spacing_code': self.cam_cutter_spacing_code, + 'cutter_spacing_code_id': self.env['maintenance.equipment.tool'].sudo().search( + [('code', '=', self.cam_cutter_spacing_code), ('equipment_id', '=', self.machine_table_name_id.id)]).id, + + 'loading_task_source': '0', + 'applicant': self.env.user.name, + 'use_tool_time': self.need_knife_time, + 'reason_for_applying': '工单用刀', + 'sf_cam_work_order_program_knife_plan_id': self.id }) self.sf_functional_tool_assembly_id = record.id # 将计划执行状态改为执行中 self.env['sf.cam.work.order.program.knife.plan'].search( - [('barcode_id', '=', self.barcode_id.id)]).write( + [('name', '=', self.name), ('functional_tool_name', '=', self.functional_tool_name)]).write( {'plan_execute_status': '1', 'applicant': self.env.user.name}) @@ -676,16 +700,19 @@ class CAMWorkOrderProgramKnifePlan(models.Model): :return: """ self.env['sf.functional.tool.assembly'].search( - [('barcode_id', '=', self.barcode_id.id), + [('assembly_order_code', '=', self.sf_functional_tool_assembly_id.assembly_order_code), ('loading_task_source', '=', '0')]).unlink() # 将计划执行状态改为待执行,同时清除申请人、功能刀具组装字段数据 self.env['sf.cam.work.order.program.knife.plan'].search( - [('barcode_id', '=', self.barcode_id.id)]).write( + [('name', '=', self.name), ('functional_tool_name', '=', self.functional_tool_name)]).write( {'plan_execute_status': '0', 'applicant': None, 'sf_functional_tool_assembly_id': None}) + def create_cam_work_plan(self, **kw): + pass + class FunctionalToolAssembly(models.Model): _name = 'sf.functional.tool.assembly' diff --git a/sf_tool_management/views/tool_base_views.xml b/sf_tool_management/views/tool_base_views.xml index dd8e3bf0..fb8b3a5e 100644 --- a/sf_tool_management/views/tool_base_views.xml +++ b/sf_tool_management/views/tool_base_views.xml @@ -756,21 +756,29 @@ + + + + + + + + + + + + + + + - - - - - - - - - - - - + + - - + -
- -
- - -
-
+ + + - - stock.barcode.quant.kanban - stock.quant - 1000 - - - - - - -
- -
-
- - - + + stock.barcode.quant.kanban + stock.quant + 1000 + + + + + + +
+ + + +
+
+ + + +
-
- - - - - + + + + + - - stock.quant.kanban.barcode - stock.quant - 1000 - - - - -
-
- + + stock.quant.kanban.barcode + stock.quant + 1000 + + + + +
+
+ + + +
+
+ + + + + +
+
+ + +
+
+ + +
-
- - - - -
-
- -
-
- -
-
- - - - - + + + + + - - stock_barcode.quant.tree.inherit - stock.quant - - primary - - - UoM - show - - - hide - - - hide - - - + + stock_barcode.quant.tree.inherit + stock.quant + + primary + + + UoM + show + + + hide + + + hide + + + diff --git a/stock_barcode/views/stock_picking_views.xml b/stock_barcode/views/stock_picking_views.xml index d61de200..d516844c 100644 --- a/stock_barcode/views/stock_picking_views.xml +++ b/stock_barcode/views/stock_picking_views.xml @@ -1,181 +1,174 @@ - - - stock.move.line.operations.tree.inherit - stock.move.line - - - - - - - - {'barcode_events': True} - field_float_scannable - - - + + + + stock.move.line.kanban.inherited + stock.move.line + + + + + + + + + + - - stock.move.line.kanban.inherited - stock.move.line - - - - - - - - - - - - - stock.picking.form.view.barcode - stock.picking - 1000 - -
- - - -
- -
-
+ + + + + + +
+
+ +
+ - - Open picking form - stock.picking - form - { - 'res_id': active_id, - } - - + + Open picking form + stock.picking + form + { + 'res_id': active_id, + } + + - - stock.picking.view.kanban.barcode - stock.picking - - + + stock.picking.view.kanban.barcode + stock.picking + + - - - - - - + + + + + + - - Operation Types - stock.picking.type - - - - - - - + + Operation Types + stock.picking.type + + + + + + + - - Operation Types - stock.picking.type - - - - - - - - - - - - - - - - - - - - + Operation Types + stock.picking.type + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + From 50ced99785afdc9c7f7cd70da6c50aa6a76ee56b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E7=84=B1?= Date: Thu, 25 Jan 2024 10:03:53 +0800 Subject: [PATCH 22/40] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=B4=A7=E6=9E=B6?= =?UTF-8?q?=E8=B4=A7=E4=BD=8D=E7=A9=BA=E9=97=B2=E9=A2=9C=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_warehouse/static/src/css/kanban_color_change.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sf_warehouse/static/src/css/kanban_color_change.scss b/sf_warehouse/static/src/css/kanban_color_change.scss index aeb75150..c532bf96 100644 --- a/sf_warehouse/static/src/css/kanban_color_change.scss +++ b/sf_warehouse/static/src/css/kanban_color_change.scss @@ -52,7 +52,7 @@ } .green { - background-color: #fff !important; + background-color: #27FEA9 !important; border: 1px solid #ccc; } From 37161e2e20757202dc3e8a9cd4b2b3dd02caf291 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Thu, 25 Jan 2024 17:51:57 +0800 Subject: [PATCH 23/40] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E7=9A=84=E6=89=98=E7=9B=98=E5=BA=8F=E5=88=97=E5=8F=B7=EF=BC=8C?= =?UTF-8?q?=E6=89=98=E7=9B=98=E5=90=8D=E7=A7=B0=EF=BC=8C=E6=89=98=E7=9B=98?= =?UTF-8?q?=E5=93=81=E7=89=8C=EF=BC=8C=E6=89=98=E7=9B=98=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=EF=BC=8C=E6=89=98=E7=9B=98=E5=9E=8B=E5=8F=B7=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=EF=BC=8C=E4=B8=94=E9=A1=B5=E9=9D=A2=E5=AF=B9?= =?UTF-8?q?=E5=BA=94=E5=AD=97=E6=AE=B5=E6=94=B9=E4=B8=BA=E5=8F=AA=E8=AF=BB?= =?UTF-8?q?=202.=E8=A3=85=E5=A4=B9=E9=A2=84=E8=B0=83=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=89=AB=E6=9D=A1=E5=BD=A2=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E6=89=AB=E7=A0=81=E6=97=B6=E5=AF=B9=E8=AF=A5=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E8=87=AA=E5=8A=A8=E5=BC=80=E5=A7=8B=E5=B9=B6?= =?UTF-8?q?=E5=B0=86=E6=9D=A1=E7=A0=81=E9=87=8C=E5=AF=B9=E5=BA=94=E7=9A=84?= =?UTF-8?q?=E6=89=98=E7=9B=98=E4=BA=A7=E5=93=81=E4=BF=A1=E6=81=AF=E5=9B=9E?= =?UTF-8?q?=E5=A1=AB=E5=88=B0=E6=89=98=E7=9B=98=E5=BA=8F=E5=88=97=E5=8F=B7?= =?UTF-8?q?=EF=BC=8C=E6=89=98=E7=9B=98=E5=90=8D=E7=A7=B0=EF=BC=8C=E6=89=98?= =?UTF-8?q?=E7=9B=98=E5=93=81=E7=89=8C=EF=BC=8C=E6=89=98=E7=9B=98=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=EF=BC=8C=E6=89=98=E7=9B=98=E5=9E=8B=E5=8F=B7=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E4=B8=8A=EF=BC=8C=E7=82=B9=E5=87=BB=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E6=97=B6=E5=AF=B9=E5=89=8D=E7=BD=AE=E4=B8=89=E5=85=83=E5=AE=9A?= =?UTF-8?q?=E4=BD=8D=E6=A3=80=E6=B5=8B=E5=8F=82=E6=95=B0=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=203.=E7=A0=94=E7=A9=B6=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E5=BA=8F=E5=88=97=E5=8F=B7=EF=BC=88=E5=A4=9A=E4=B8=AA=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_manufacturing/models/mrp_workorder.py | 73 ++++++------------- sf_manufacturing/models/stock.py | 12 ++- sf_manufacturing/views/mrp_workorder_view.xml | 17 +++-- 3 files changed, 42 insertions(+), 60 deletions(-) diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 7a77fc5c..712940f0 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -122,10 +122,10 @@ class ResMrpWorkOrder(models.Model): chuck_type_id = fields.Char(string="卡盘类型") chuck_model_id = fields.Char(string="卡盘型号") tray_serial_number = fields.Char(string="托盘序列号") - tray_name = fields.Char(string="托盘名称") + tray_product_id = fields.Many2one('product.product', string="托盘名称") tray_brand_id = fields.Many2one('sf.machine.brand', string="托盘品牌") - tray_type_id = fields.Char(string="托盘类型") - tray_model_id = fields.Char(string="托盘型号") + tray_type_id = fields.Many2one('sf.fixture.material', string="托盘类型") + tray_model_id = fields.Many2one('sf.fixture.model', string="托盘型号") total_wight = fields.Float(string="总重量") maximum_carrying_weight = fields.Char(string="最大承载重量[kg]") maximum_clamping_force = fields.Char(string="最大夹持力[n]") @@ -552,6 +552,9 @@ class ResMrpWorkOrder(models.Model): raise UserError(_('请先完成上一步工单')) def button_finish(self): + if self.routing_type == '装夹预调': + if not self.material_center_point and self.X_deviation_angle > 0: + raise UserError("请对前置三元检测定位参数进行计算定位") if self.picking_out_id: picking_out = self.env['stock.picking'].search([('id', '=', self.picking_out_id.id)]) if picking_out.workorder_out_id: @@ -721,54 +724,22 @@ class SfWorkOrderBarcodes(models.Model): _name = "mrp.workorder" _inherit = ["mrp.workorder", "barcodes.barcode_events_mixin"] - # def on_barcode_scanned(self, barcode): - # workorder = self.env['mrp.workorder'].browse(self.ids) - # if "*" not in barcode: - # if self.routing_type == '装夹': - # tray_code = self.env['sf.tray'].search([('code', '=', barcode)]) - # self.tray_code = tray_code.code - # self.tray_id = workorder.gettray_auto(barcode) - # elif self.routing_type == '前置三元定位检测': - # print('我是前置三元检测') - # logging.info('我是前置三元检测') - # elif self.routing_type == 'CNC加工': - # if barcode == 'UP-ALL': - # print("我是一键合并下发") - # logging.info('我是一键合并下发') - # self.up_merge_all() - # else: - # print('CNC加工') - # # print(barcode) - # # a = self.env['sf.tray'].search([('code', '=', barcode)]) - # # print(a) - # # # workorder_obj = self.env['mrp.workorder'].search([('tray_code', '=', barcode)], limit=1) - # # workorder_obj = self.env['mrp.workorder'].search([('tray_code', '=', barcode)]) - # # e = workorder_obj.id - # # print(workorder_obj) - # # action = { - # # 'name': '工单', - # # 'type': 'ir.actions.act_window', - # # # 'view_type': 'form', - # # 'view_mode': 'form', - # # 'res_model': 'mrp.workorder', - # # 'view_id': self.env.ref('mrp.mrp_production_workorder_form_view_inherit').id, - # # # 'res_id': workorder_obj.id, - # # 'res_id': 1023, - # # 'target': 'current', - # # # 'context': self.env.context, - # # # 'flags': {'initial_mode': 'edit'}, - # # } - # # return action - # - # elif self.routing_type == '后置三元质量检测': - # print('后置三元检测') - # elif self.routing_type == '解除装夹': - # print("我是解除装夹") - # else: - # pass - # - # else: - # self.pro_code_ok = workorder.pro_code_is_ok(barcode) + def on_barcode_scanned(self, barcode): + workorder = self.env['mrp.workorder'].browse(self.ids) + # workorder = self.env['mrp.workorder'].search( + # [('routing_type', '=', '装夹预调'), ('production_id', '=', self.production_id.id)]) + if workorder: + if workorder.routing_type == '装夹预调': + stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)]) + if stock_move_line: + workorder.write({ + 'tray_serial_number': stock_move_line.lot_name, + 'tray_product_id': stock_move_line.product_id.id, + 'tray_brand_id': stock_move_line.product_id.brand_id.id, + 'tray_type_id': stock_move_line.product_id.fixture_material_id.id, + 'tray_model_id': stock_move_line.product_id.fixture_model_id.id + }) + workorder.button_start() class WorkPieceDelivery(models.Model): diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index a39bd0f4..f13abf6b 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -375,8 +375,18 @@ class ReStockMove(models.Model): def print_serial_numbers(self): if not self.next_serial: raise UserError(_("请先分配序列号再进行打印")) + label_data = [] for item in self.move_line_ids: - print(item.lot_name) + label_data.append({ + 'item_id': item.id, + }) + if label_data: + report_template = self.env.ref('stock.label_package_template') + res = report_template.report_action(label_data) + res['id'] = report_template.id + return res + else: + raise UserError(_("没有可打印的标签数据")) class ReStockQuant(models.Model): diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 42b58149..502b33a2 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -117,7 +117,7 @@ attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"/>
- - + + From 4ee4b28389149cedb6d7930cc639d516d88afd39 Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Fri, 26 Jan 2024 14:18:10 +0800 Subject: [PATCH 24/40] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/common.py | 2 +- sf_machine_connect/views/machine_monitor.xml | 4 ++-- sf_mrs_connect/models/sync_common.py | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sf_base/models/common.py b/sf_base/models/common.py index 7450fff9..6cddafd7 100644 --- a/sf_base/models/common.py +++ b/sf_base/models/common.py @@ -61,7 +61,7 @@ class MrsMaterialModel(models.Model): supplier_ids = fields.One2many('sf.supplier.sort', 'materials_model_id', string='供应商') active = fields.Boolean('有效', default=True) - @api.constrains('gain_way', 'supplier_ids') + @api.constrains('supplier_ids') def _check_gain_way(self): if not self.gain_way: raise UserError("请输入获取方式") diff --git a/sf_machine_connect/views/machine_monitor.xml b/sf_machine_connect/views/machine_monitor.xml index 9c9a21a3..d52bead8 100644 --- a/sf_machine_connect/views/machine_monitor.xml +++ b/sf_machine_connect/views/machine_monitor.xml @@ -10,7 +10,7 @@ - + @@ -143,7 +143,7 @@ - + --> diff --git a/sf_mrs_connect/models/sync_common.py b/sf_mrs_connect/models/sync_common.py index df9437ba..1ca9affa 100644 --- a/sf_mrs_connect/models/sync_common.py +++ b/sf_mrs_connect/models/sync_common.py @@ -314,12 +314,12 @@ class sfProductionProcess(models.Model): brand = self.env['sf.production.process'].search( [("code", '=', item['code'])]) if brand: - brand.name = item['name'], + brand.name = item['name'] brand.category_id = self.env['sf.production.process.category'].search( - [("code", '=', item['category_code'])]).id, - brand.code = item['code'], - brand.remark = item['remark'], - brand.active = item['active'], + [("code", '=', item['category_code'])]).id + brand.code = item['code'] + brand.remark = item['remark'] + brand.active = item['active'] brand.remark = item['remark'] production_process = self.search([("code", '=', item['code'])]) category = self.env['sf.production.process.category'].search( From cf2aaa38fed567c223dac0773c88c90543d4a4e5 Mon Sep 17 00:00:00 2001 From: "jinling.yang" Date: Fri, 26 Jan 2024 17:46:53 +0800 Subject: [PATCH 25/40] =?UTF-8?q?1.=E4=BF=AE=E5=A4=8D=E6=9D=90=E6=96=99?= =?UTF-8?q?=E5=9E=8B=E5=8F=B7=E5=90=8C=E6=AD=A5=E6=8A=A5=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E9=97=AE=E9=A2=982.=E4=BC=98=E5=8C=96=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E7=9A=84=E5=B7=A5=E4=BB=B6=E6=B4=BE=E9=80=813.=E8=AE=A1?= =?UTF-8?q?=E5=88=92=E9=87=8C=E6=96=B0=E5=A2=9E=E7=94=9F=E4=BA=A7=E7=BA=BF?= =?UTF-8?q?=E7=9A=84=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_base/models/common.py | 2 +- sf_manufacturing/models/mrp_production.py | 2 + sf_manufacturing/models/mrp_workorder.py | 43 +++++++++++++++---- .../views/mrp_production_addional_change.xml | 2 + sf_manufacturing/views/mrp_workorder_view.xml | 10 ++--- sf_plan/models/custom_plan.py | 23 +++------- sf_plan/views/view.xml | 11 ----- 7 files changed, 51 insertions(+), 42 deletions(-) diff --git a/sf_base/models/common.py b/sf_base/models/common.py index 7450fff9..6cddafd7 100644 --- a/sf_base/models/common.py +++ b/sf_base/models/common.py @@ -61,7 +61,7 @@ class MrsMaterialModel(models.Model): supplier_ids = fields.One2many('sf.supplier.sort', 'materials_model_id', string='供应商') active = fields.Boolean('有效', default=True) - @api.constrains('gain_way', 'supplier_ids') + @api.constrains('supplier_ids') def _check_gain_way(self): if not self.gain_way: raise UserError("请输入获取方式") diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 61be5b40..7c4915c1 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -50,6 +50,8 @@ class MrpProduction(models.Model): work_state = fields.Char('业务状态') programming_state = fields.Char('编程状态') glb_file = fields.Binary("glb模型文件") + production_line_id = fields.Many2one('sf.production.line', string='生产线') + plan_start_processing_time = fields.Datetime('计划开始加工时间') @api.depends( diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 712940f0..a0ba1317 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -131,7 +131,7 @@ class ResMrpWorkOrder(models.Model): maximum_clamping_force = fields.Char(string="最大夹持力[n]") production_line = fields.Char(string="生产线") preset_program_information = fields.Char(string="预调程序信息") - workpiece_delivery_id = fields.One2many('sf.workpiece.delivery', 'workorder_id', '工件配送') + workpiece_delivery_ids = fields.One2many('sf.workpiece.delivery', 'workorder_id', '工件配送') @api.onchange('is_ok') def _onchange_inspection_user_id(self): @@ -196,9 +196,24 @@ class ResMrpWorkOrder(models.Model): work = workorder.production_id.workorder_ids work.compensation_value_x = eval(self.material_center_point)[0] work.compensation_value_y = eval(self.material_center_point)[1] + workorder.button_finish() + except: raise UserError("参数计算有误") + # def button_workpiece_delivery(self): + # if self.routing_type == '装夹预调': + # if not self.workpiece_delivery_ids: + # raise UserError('请添加【工件配送】信息') + # else: + # for item in self.workpiece_delivery_ids: + # if not item.feeder_station_start: + # raise UserError('【工件配送】明细中请输入起点接驳站') + # if not item.workpiece_code: + # raise UserError('请对【同运工件】进行扫描') + # else: + # workpiece_code + # 拼接工单对象属性值 def json_workorder_str(self, k, production, route): # 计算预计时长duration_expected @@ -241,7 +256,9 @@ class ResMrpWorkOrder(models.Model): 'date_planned_finished': False, 'duration_expected': duration_expected, 'duration': 0, - + 'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self.env[ + 'sf.workpiece.delivery'].create( + {'production_id': production.id}) }] return workorders_values_str @@ -731,7 +748,7 @@ class SfWorkOrderBarcodes(models.Model): if workorder: if workorder.routing_type == '装夹预调': stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)]) - if stock_move_line: + if stock_move_line.product_id.categ_type == '夹具': workorder.write({ 'tray_serial_number': stock_move_line.lot_name, 'tray_product_id': stock_move_line.product_id.id, @@ -740,26 +757,36 @@ class SfWorkOrderBarcodes(models.Model): 'tray_model_id': stock_move_line.product_id.fixture_model_id.id }) workorder.button_start() + # elif stock_move_line.product_id.categ_type == '坯料': + # if stock_move_line.production_id.production_line_id.id == workorder.production_id.production_line_id.id + # workorder. class WorkPieceDelivery(models.Model): _name = "sf.workpiece.delivery" _description = '工件配送' - workorder_id = fields.Many2one('mrp.workorder', string='工单', - domain=[('name', 'in', ('装夹', '解除装夹'))]) - production_code = fields.Char(related='workorder_id.production_id.name', string='工件编码/任务编码', store=True) - plan_start_processing_time = fields.Datetime('计划开始加工时间') + workorder_id = fields.Many2one('mrp.workorder', string='工单', readonly=True) + production_id = fields.Many2one('mrp.production', string='制造订单', readonly=True) + production_line_id = fields.Many2one('sf.production.line', compute='_compute_production_line_id', + string='目标生产线', readonly=True, + store=True) + plan_start_processing_time = fields.Datetime('计划开始加工时间', readonly=True) workpiece_code = fields.Char('同运工件编码') feeder_station_start = fields.Char('起点接驳站') feeder_station_destination = fields.Char('目的接驳站') - production_line_id = fields.Many2one('sf.production.line', string='目标生产线') task_delivery_time = fields.Datetime('任务下发时间') task_completion_time = fields.Datetime('任务完成时间') delivery_time = fields.Char('配送时长', compute='_compute_delivery_time') status = fields.Selection([('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送')], string='状态', default='待下发') + @api.depends('production_id.production_line_id') + def _compute_production_line_id(self): + if self.production_id.production_line_id: + self.production_line_id = self.production_id.production_line_id.id + self.plan_start_processing_time = self.production_id.plan_start_processing_time + @api.depends('task_delivery_time', 'task_completion_time') def _compute_delivery_time(self): for obj in self: diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 6ba4d4d5..b93ad455 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -69,6 +69,8 @@ + +

- +

- + + @@ -178,6 +180,7 @@ + @@ -224,7 +227,8 @@ - + + @@ -250,6 +254,7 @@ + @@ -376,7 +381,7 @@ - + @@ -435,7 +440,8 @@ - + + @@ -457,6 +463,7 @@ + @@ -510,6 +517,7 @@ + @@ -529,6 +537,7 @@ 'default_machine_tool_code': machine_tool_code, 'default_cutter_spacing_code_id': cutter_spacing_code_id, 'default_barcode_id': barcode_id, + 'default_fid': fid, 'default_functional_tool_name': functional_tool_name, 'default_functional_tool_type_id': functional_tool_type_id, 'default_tool_position_interface_type': tool_position_interface_type, @@ -551,7 +560,7 @@ 'default_replacement_extension_length': extension_length, 'default_replacement_effective_length': effective_length, }" - attrs="{'invisible': [('status', '!=', '0')]}" + attrs="{'invisible': ['|',('status', '!=', '0'), ('functional_tool_name_id', '=', False)]}" class="btn-primary" groups="sf_base.group_sf_mrp_user" />