From 48809cd654e10d76240bc9be08d6d20cfb3a2adf Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Fri, 29 Mar 2024 17:37:02 +0800
Subject: [PATCH 01/19] =?UTF-8?q?1=E3=80=81=E5=BA=8F=E5=88=97=E5=8F=B7?=
=?UTF-8?q?=E6=A8=A1=E5=9E=8B=E5=AF=B9=E8=B1=A1=E6=B7=BB=E5=8A=A0rfid?=
=?UTF-8?q?=E5=AD=97=E6=AE=B5=E4=B8=94rfid=E4=BB=85=E5=9C=A8=E4=BA=A7?=
=?UTF-8?q?=E5=93=81=E4=B8=BA=E5=88=80=E6=9F=84=E6=97=B6=E5=B1=95=E7=A4=BA?=
=?UTF-8?q?=EF=BC=8C=E5=BA=8F=E5=88=97=E5=8F=B7=E6=A8=A1=E5=9E=8B=E6=B7=BB?=
=?UTF-8?q?=E5=8A=A0=E8=A7=84=E6=A0=BC=E5=AD=97=E6=AE=B5=EF=BC=8C=E4=B8=94?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=8A=A8=E6=A0=B9=E6=8D=AE=E5=AF=B9?=
=?UTF-8?q?=E5=BA=94=E4=BA=A7=E5=93=81=E7=B1=BB=E5=9E=8B=E4=B8=8D=E5=90=8C?=
=?UTF-8?q?=E8=AE=A1=E7=AE=97=E5=87=BA=E5=85=B6=E5=80=BC=EF=BC=8C=E4=BA=A7?=
=?UTF-8?q?=E5=93=81=E4=B8=BA=E5=A4=B9=E5=85=B7=E6=97=B6=E7=9C=8B=E6=9D=BF?=
=?UTF-8?q?=E5=B1=95=E7=A4=BA=E5=85=B6=E8=A7=84=E6=A0=BC=E7=9A=84=E5=80=BC?=
=?UTF-8?q?=EF=BC=9B2=E3=80=81=E5=9C=A8=E9=87=87=E8=B4=AD=E5=85=A5?=
=?UTF-8?q?=E5=BA=93=E6=B5=81=E7=A8=8B=EF=BC=8C=E5=BD=95=E5=85=A5=E5=BA=8F?=
=?UTF-8?q?=E5=88=97=E5=8F=B7=E7=9A=84=E8=BF=87=E7=A8=8B=E7=95=8C=E9=9D=A2?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=BD=95=E5=85=A5rfid=E5=AD=97=E6=AE=B5?=
=?UTF-8?q?=EF=BC=8C=E5=BD=93=E4=BA=A7=E5=93=81=E6=98=AF=E5=88=80=E6=9F=84?=
=?UTF-8?q?=E6=97=B6=E9=9C=80=E5=BD=95=E5=85=A5=E5=88=80=E6=9F=84=E7=9A=84?=
=?UTF-8?q?rfid=EF=BC=8C=E5=B9=B6=E5=9C=A8=E9=AA=8C=E8=AF=81=E9=80=9A?=
=?UTF-8?q?=E8=BF=87=E5=90=8E=E5=88=80=E6=9F=84=E7=9A=84=E5=BA=8F=E5=88=97?=
=?UTF-8?q?=E5=8F=B7=E4=B8=AD=E5=B8=A6=E6=9C=89rfid=E7=A0=81=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/models/stock.py | 16 ++++++++
.../views/mrp_production_addional_change.xml | 3 +-
sf_manufacturing/views/stock_lot_views.xml | 6 +++
sf_warehouse/models/model.py | 27 ++++++++++++-
.../views/change_stock_move_views.xml | 40 +++++++++++++------
5 files changed, 78 insertions(+), 14 deletions(-)
diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py
index f255d28b..b68b0ea0 100644
--- a/sf_manufacturing/models/stock.py
+++ b/sf_manufacturing/models/stock.py
@@ -222,6 +222,22 @@ class ProductionLot(models.Model):
_name = 'stock.lot'
_inherit = ['stock.lot', 'printing.utils']
+ rfid = fields.Char('Rfid', readonly=True)
+ product_material_name = fields.Char('刀具产品物料名称', related='product_id.cutting_tool_material_id.name')
+ product_specification = fields.Char('规格', compute='_compute_product_specification', store=True)
+
+ @api.depends('product_id')
+ def _compute_product_specification(self):
+ for stock in self:
+ if stock:
+ if stock.product_id:
+ if stock.product_id.categ_id.name in '刀具':
+ stock.product_specification = stock.product_id.specification_id.name
+ elif stock.product_id.categ_id.name in '夹具':
+ stock.product_specification = stock.product_id.specification_fixture_id.name
+ else:
+ stock.product_specification = stock.product_id.default_code
+
@api.model
def generate_lot_names1(self, display_name, first_lot, count):
"""Generate `lot_names` from a string."""
diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml
index 0ae0d95f..6ba78573 100644
--- a/sf_manufacturing/views/mrp_production_addional_change.xml
+++ b/sf_manufacturing/views/mrp_production_addional_change.xml
@@ -422,7 +422,8 @@
规格:
-
+
+
[]
diff --git a/sf_manufacturing/views/stock_lot_views.xml b/sf_manufacturing/views/stock_lot_views.xml
index bd04005c..f7ef9c9b 100644
--- a/sf_manufacturing/views/stock_lot_views.xml
+++ b/sf_manufacturing/views/stock_lot_views.xml
@@ -13,6 +13,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py
index 2228d2d5..3667c62c 100644
--- a/sf_warehouse/models/model.py
+++ b/sf_warehouse/models/model.py
@@ -424,6 +424,8 @@ class Sf_stock_move_line(models.Model):
# lot_qr_code = fields.Binary(string='二维码', compute='_compute_lot_qr_code', store=True)
lot_qr_code = fields.Binary(string='二维码', compute='_compute_lot_qr_code', store=True)
+ rfid = fields.Char('Rfid')
+
def action_revert_inventory(self):
# 检查用户是否有执行操作的权限
if not self.env.user.has_group('sf_warehouse.group_sf_stock_user'):
@@ -742,6 +744,12 @@ class SfStockPicking(models.Model):
if line.current_location_id:
line.current_location_id.product_sn_id = False
line.current_location_id.location_status = '空闲'
+
+ for move in self.move_ids:
+ if move and move.product_id.cutting_tool_material_id.name in '刀柄':
+ for item in move.move_line_nosuggest_ids:
+ if item:
+ self.env['stock.lot'].search([('name', '=', item.lot_name)]).write({'rfid': item.rfid})
return res
# def print_all_barcode(self):
@@ -932,7 +940,24 @@ class SfStockScrap(models.Model):
class CustomStockMove(models.Model):
_name = 'stock.move'
- _inherit = ['stock.move', 'printing.utils']
+ _inherit = ['stock.move', 'printing.utils', 'barcodes.barcode_events_mixin']
+
+ def on_barcode_scanned(self, barcode):
+ """
+ 采购入库扫码绑定Rfid码
+ """
+ for record in self:
+ if record:
+ if '刀柄' in record.product_id.cutting_tool_material_id.name:
+ for move_line_nosuggest_id in record.move_line_nosuggest_ids:
+ if move_line_nosuggest_id.rfid:
+ if move_line_nosuggest_id.rfid == barcode:
+ raise ValidationError('该刀柄的rfid已经录入,请勿重复录入!!!')
+ else:
+ move_line_nosuggest_id.sudo().rfid = barcode
+ break
+ else:
+ raise ValidationError('该产品不是刀柄!!!')
def action_assign_serial_show_details(self):
# 首先执行原有逻辑
diff --git a/sf_warehouse/views/change_stock_move_views.xml b/sf_warehouse/views/change_stock_move_views.xml
index cc4213c6..0875fa12 100644
--- a/sf_warehouse/views/change_stock_move_views.xml
+++ b/sf_warehouse/views/change_stock_move_views.xml
@@ -31,15 +31,16 @@
-
-
-
+
+
+
-
+
+
sf.stock.move.line.form
stock.move.line
@@ -63,6 +64,9 @@
stock.move.line
+
+
+
@@ -103,10 +107,10 @@
groups="sf_warehouse.group_sf_stock_user" data-hotkey="k"/>
-
-
-
-
+
+
+
+
@@ -145,11 +149,23 @@
stock.move
-
-
-
+
+
+
- -->
+
+ -->
+
+
+
+
+
+ mrp.subcontracting.stock.move.barcode.scanned.form
+ stock.move
+
+
+
+
From 8d1e4a89c29163118a69ff3f48e27eef6204e697 Mon Sep 17 00:00:00 2001
From: "jinling.yang"
Date: Fri, 29 Mar 2024 17:38:35 +0800
Subject: [PATCH 02/19] =?UTF-8?q?1=E3=80=81=E6=B2=A1=E7=BB=91=E5=AE=9A?=
=?UTF-8?q?=E5=B7=A5=E5=8D=95=E4=B8=8D=E8=83=BD=E5=AE=8C=E5=B7=A5=EF=BC=8C?=
=?UTF-8?q?=E7=BB=91=E5=AE=9A=E5=90=8E=E6=89=8D=E5=8F=AF=E4=BB=A5=E5=AE=8C?=
=?UTF-8?q?=E5=B7=A5=202=E3=80=81=E5=B7=A5=E5=8D=95=E7=BB=91=E5=AE=9A?=
=?UTF-8?q?=E5=90=8E=E6=B2=A1=E5=AE=8C=E5=B7=A5=E5=8F=AF=E4=BB=A5=E6=8D=A2?=
=?UTF-8?q?=E7=BB=91=203=E3=80=81=E5=B7=A5=E5=8D=95=E7=82=B9=E5=AE=8C?=
=?UTF-8?q?=E5=B7=A5=E6=8C=89=E9=92=AE=E8=A6=81=E6=9C=89=E7=A1=AE=E8=AE=A4?=
=?UTF-8?q?=E5=BC=B9=E7=AA=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/models/mrp_workorder.py | 5 ++++-
sf_manufacturing/models/product_template.py | 4 ++--
sf_manufacturing/views/mrp_workorder_view.xml | 6 +++---
sf_sale/models/auto_quatotion_common.py | 2 +-
sf_sale/models/quick_easy_order.py | 4 ++--
5 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index 7b3467b7..95f484ef 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -606,6 +606,8 @@ class ResMrpWorkOrder(models.Model):
if self.routing_type == '装夹预调':
if not self.material_center_point and self.X_deviation_angle > 0:
raise UserError("请对前置三元检测定位参数进行计算定位")
+ if not self.rfid_code:
+ raise UserError("请扫RFID码进行绑定")
if self.picking_out_id:
picking_out = self.env['stock.picking'].search([('id', '=', self.picking_out_id.id)])
if picking_out.workorder_out_id:
@@ -869,7 +871,8 @@ class SfWorkOrderBarcodes(models.Model):
[('production_id', '=', workorder.production_id.id)])
if workorder_rfid:
for item in workorder_rfid:
- item.write({'rfid_code': barcode})
+ if item.state == "progress":
+ item.write({'rfid_code': barcode})
class WorkPieceDelivery(models.Model):
diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py
index be0c09ae..ddc2ee6d 100644
--- a/sf_manufacturing/models/product_template.py
+++ b/sf_manufacturing/models/product_template.py
@@ -8,8 +8,8 @@ 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/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml
index 4a766526..9797178e 100644
--- a/sf_manufacturing/views/mrp_workorder_view.xml
+++ b/sf_manufacturing/views/mrp_workorder_view.xml
@@ -104,7 +104,7 @@
-
+
-
diff --git a/sf_sale/models/auto_quatotion_common.py b/sf_sale/models/auto_quatotion_common.py
index 4feaa7dd..104cd50c 100644
--- a/sf_sale/models/auto_quatotion_common.py
+++ b/sf_sale/models/auto_quatotion_common.py
@@ -2,7 +2,7 @@
import logging
from odoo.modules import get_resource_path
from odoo import fields, models, api
-from quatotion import readSql, feature_recognize, auto_quatotion
+# from quatotion import readSql, feature_recognize, auto_quatotion
__author__ = 'jinling.yang'
_logger = logging.getLogger(__name__)
diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py
index 1ece6b86..ed52d9de 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
From f0b972e705ad5c8783d5b615b964f6934493bb11 Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Mon, 1 Apr 2024 16:56:15 +0800
Subject: [PATCH 03/19] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E5=88=80?=
=?UTF-8?q?=E6=9F=84=E7=89=A9=E6=96=99=E4=BA=A7=E5=93=81=E9=80=82=E7=94=A8?=
=?UTF-8?q?=E5=A4=B9=E5=A4=B4=E5=9E=8B=E5=8F=B7=E6=B2=A1=E6=9C=89=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=E5=88=80=E5=85=B7=E6=A0=87=E5=87=86=E5=BA=93=E5=9F=BA=E6=9C=AC?=
=?UTF-8?q?=E5=8F=82=E6=95=B0=E5=90=8C=E6=AD=A5=E6=8E=A5=E5=8F=A3=EF=BC=9B?=
=?UTF-8?q?2=E3=80=81=E4=BC=98=E5=8C=96=E5=8A=9F=E8=83=BD=E5=88=80?=
=?UTF-8?q?=E5=85=B7=E7=BB=84=E8=A3=85=E6=97=B6=EF=BC=8C=E5=8F=AA=E9=9C=80?=
=?UTF-8?q?=E6=89=AB=E5=85=A5=E5=88=80=E6=9F=84=E7=9A=84Rfid=EF=BC=8C?=
=?UTF-8?q?=E5=B0=86=E8=87=AA=E5=8A=A8=E5=B8=A6=E5=87=BA=E5=88=80=E6=9F=84?=
=?UTF-8?q?=E4=BF=A1=E6=81=AF=EF=BC=8C=E5=B9=B6=E6=A0=B9=E6=8D=AE=E5=88=80?=
=?UTF-8?q?=E6=9F=84=E9=80=82=E7=94=A8=E5=A4=B9=E5=A4=B4=E5=9E=8B=E5=8F=B7?=
=?UTF-8?q?=E5=92=8C=E9=80=82=E9=85=8D=E5=A4=B9=E5=A4=B4=E5=B0=BA=E5=AF=B8?=
=?UTF-8?q?=E9=9A=8F=E6=9C=BA=E5=B8=A6=E5=87=BA=E4=B8=80=E4=B8=AA=E5=8F=AF?=
=?UTF-8?q?=E7=94=A8=E5=A4=B9=E5=A4=B4=E7=89=A9=E6=96=99=E4=BF=A1=E6=81=AF?=
=?UTF-8?q?=EF=BC=8C=E5=90=8C=E6=97=B6=E5=B0=86=E5=88=80=E6=9F=84=E7=9A=84?=
=?UTF-8?q?Rfid=E7=A0=81=E5=A1=AB=E5=85=A5=E5=8A=9F=E8=83=BD=E5=88=80?=
=?UTF-8?q?=E5=85=B7=E7=9A=84Rfid=E7=A0=81=E3=80=823=E3=80=81=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=E5=88=80=E6=9F=84=E7=89=A9=E6=96=99=E9=87=87=E8=B4=AD?=
=?UTF-8?q?=E5=85=A5=E5=BA=93=E6=97=B6=E7=9A=84=E9=AA=8C=E8=AF=81=E7=9A=84?=
=?UTF-8?q?=E5=88=A4=E6=96=AD=E6=9D=A1=E4=BB=B6=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/models/product_template.py | 7 +-
sf_mrs_connect/models/sync_common.py | 91 ++++++++------------
sf_tool_management/views/tool_base_views.xml | 2 +-
sf_tool_management/wizard/wizard.py | 82 +++++++++++-------
sf_warehouse/models/model.py | 4 +-
5 files changed, 95 insertions(+), 91 deletions(-)
diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py
index be0c09ae..1489cddd 100644
--- a/sf_manufacturing/models/product_template.py
+++ b/sf_manufacturing/models/product_template.py
@@ -7,7 +7,6 @@ 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
@@ -107,7 +106,10 @@ class ResProductMo(models.Model):
@api.onchange('cutting_tool_model_id')
def _onchange_cutting_tool_model_id(self):
- self.specification_id = False
+ for item in self:
+ if item:
+ item.specification_id = False
+ item.cutting_tool_chuck_id = item.cutting_tool_model_id.chuck_id
@api.onchange('cutting_tool_material_id')
def _onchange_cutting_tool_material_id(self):
@@ -310,7 +312,6 @@ class ResProductMo(models.Model):
self.cutting_tool_is_safety_lock = self.specification_id.is_safe_lock
self.cutting_tool_fit_nut_model = self.specification_id.nut
self.cutting_tool_wrench = self.specification_id.spanner
- self.cutting_tool_chuck_id = self.specification_id.chuck_id.id
self.cutting_tool_jump_accuracy = self.specification_id.diameter_slip_accuracy
self.cutting_tool_taper_shank_model = self.specification_id.taper_shank_model
self.cutting_tool_cooling_type = self.specification_id.cooling_model
diff --git a/sf_mrs_connect/models/sync_common.py b/sf_mrs_connect/models/sync_common.py
index 49956f4b..3ee916e7 100644
--- a/sf_mrs_connect/models/sync_common.py
+++ b/sf_mrs_connect/models/sync_common.py
@@ -2421,7 +2421,7 @@ class CuttingToolBasicParameters(models.Model):
'active': integral_tool_item['active'],
})
else:
- self.write({
+ self.search([('code', '=', integral_tool_item['code'])]).write({
'name': integral_tool_item['name'],
'total_length': integral_tool_item['total_length'],
'blade_diameter': integral_tool_item['blade_diameter'],
@@ -2482,7 +2482,7 @@ class CuttingToolBasicParameters(models.Model):
'active': blade_item['active'],
})
else:
- self.write({
+ self.search([('code', '=', blade_item['code'])]).write({
'name': blade_item['name'],
'length': blade_item['length'],
'thickness': blade_item['thickness'],
@@ -2539,7 +2539,7 @@ class CuttingToolBasicParameters(models.Model):
'active': chuck_item['active'],
})
else:
- self.write({
+ self.search([('code', '=', chuck_item['code'])]).write({
'name': chuck_item['name'],
'er_size_model': chuck_item['size_model'],
'min_clamping_diameter': chuck_item['clamping_diameter_min'],
@@ -2598,7 +2598,7 @@ class CuttingToolBasicParameters(models.Model):
'active': cutter_arbor_item['active'],
})
else:
- self.write({
+ self.search([('code', '=', cutter_arbor_item['code'])]).write({
'name': cutter_arbor_item['name'],
'height': cutter_arbor_item['height'],
'width': cutter_arbor_item['width'],
@@ -2662,7 +2662,7 @@ class CuttingToolBasicParameters(models.Model):
'active': cutter_head_item['active'],
})
else:
- self.write({
+ self.search([('code', '=', cutter_head_item['code'])]).write({
'name': cutter_head_item['name'],
'install_blade_tip_num': cutter_head_item['number_blade_installed'],
'blade_diameter': cutter_head_item['blade_diameter'],
@@ -2691,57 +2691,38 @@ class CuttingToolBasicParameters(models.Model):
for knife_handle_item in basic_parameters_knife_handle_list:
knife_handle = self.search(
[('code', '=', knife_handle_item['code']), ('active', 'in', [True, False])])
+ val = {
+ 'name': knife_handle_item['name'],
+ 'taper_shank_model': knife_handle_item['taper_shank_model'],
+ 'total_length': knife_handle_item['total_length'],
+ 'flange_shank_length': knife_handle_item['flange_length'],
+ 'flange_diameter': knife_handle_item['flange_diameter'],
+ 'shank_length': knife_handle_item['shank_length'],
+ 'shank_diameter': knife_handle_item['shank_diameter'],
+ 'min_clamping_diameter': knife_handle_item['clamping_diameter_min'],
+ 'max_clamping_diameter': knife_handle_item['clamping_diameter_max'],
+ 'clamping_mode': knife_handle_item['clamping_way'],
+ 'tool_changing_time': knife_handle_item['tool_changing_time'],
+ 'max_rotate_speed': knife_handle_item['rotate_speed_max'],
+ 'diameter_slip_accuracy': knife_handle_item['diameter_slip_accuracy'],
+ 'cooling_model': knife_handle_item['cooling_model'],
+ 'fit_chuck_size': knife_handle_item['fit_chuck_size'],
+ 'is_quick_cutting': knife_handle_item['is_quick_cutting'],
+ 'is_safe_lock': knife_handle_item['is_safe_lock'],
+ 'screw': knife_handle_item['fit_wrench_model'],
+ 'nut': knife_handle_item['fit_nut_model'],
+ 'dynamic_balance_class': knife_handle_item['dynamic_balance_class'],
+ 'active': knife_handle_item['active'],
+ }
if not knife_handle:
- self.create({
- 'name': knife_handle_item['name'],
- 'code': knife_handle_item['code'],
- 'cutting_tool_type': '刀柄',
- 'taper_shank_model': knife_handle_item['taper_shank_model'],
- 'standard_library_id': self.env['sf.cutting_tool.standard.library'].search(
- [('code', '=', knife_handle_item['standard_library_code'].replace("JKM", result[
- 'factory_short_name']))]).id,
- 'total_length': knife_handle_item['total_length'],
- 'flange_shank_length': knife_handle_item['flange_length'],
- 'flange_diameter': knife_handle_item['flange_diameter'],
- 'shank_length': knife_handle_item['shank_length'],
- 'shank_diameter': knife_handle_item['shank_diameter'],
- 'min_clamping_diameter': knife_handle_item['clamping_diameter_min'],
- 'max_clamping_diameter': knife_handle_item['clamping_diameter_max'],
- 'clamping_mode': knife_handle_item['clamping_way'],
- 'tool_changing_time': knife_handle_item['tool_changing_time'],
- 'max_rotate_speed': knife_handle_item['rotate_speed_max'],
- 'diameter_slip_accuracy': knife_handle_item['diameter_slip_accuracy'],
- 'cooling_model': knife_handle_item['cooling_model'],
- 'is_quick_cutting': knife_handle_item['is_quick_cutting'],
- 'is_safe_lock': knife_handle_item['is_safe_lock'],
- 'screw': knife_handle_item['fit_wrench_model'],
- 'nut': knife_handle_item['fit_nut_model'],
- 'dynamic_balance_class': knife_handle_item['dynamic_balance_class'],
- 'active': knife_handle_item['active'],
- })
+ val['code'] = knife_handle_item['code']
+ val['cutting_tool_type'] = '刀柄'
+ val['standard_library_id'] = self.env['sf.cutting_tool.standard.library'].search(
+ [('code', '=', knife_handle_item['standard_library_code'].replace("JKM", result[
+ 'factory_short_name']))]).id
+ self.create(val)
else:
- self.write({
- 'name': knife_handle_item['name'],
- 'taper_shank_model': knife_handle_item['taper_shank_model'],
- 'total_length': knife_handle_item['total_length'],
- 'flange_shank_length': knife_handle_item['flange_length'],
- 'flange_diameter': knife_handle_item['flange_diameter'],
- 'shank_length': knife_handle_item['shank_length'],
- 'shank_diameter': knife_handle_item['shank_diameter'],
- 'min_clamping_diameter': knife_handle_item['clamping_diameter_min'],
- 'max_clamping_diameter': knife_handle_item['clamping_diameter_max'],
- 'clamping_mode': knife_handle_item['clamping_way'],
- 'tool_changing_time': knife_handle_item['tool_changing_time'],
- 'max_rotate_speed': knife_handle_item['rotate_speed_max'],
- 'diameter_slip_accuracy': knife_handle_item['diameter_slip_accuracy'],
- 'cooling_model': knife_handle_item['cooling_model'],
- 'is_quick_cutting': knife_handle_item['is_quick_cutting'],
- 'is_safe_lock': knife_handle_item['is_safe_lock'],
- 'screw': knife_handle_item['fit_wrench_model'],
- 'nut': knife_handle_item['fit_nut_model'],
- 'dynamic_balance_class': knife_handle_item['dynamic_balance_class'],
- 'active': knife_handle_item['active'],
- })
+ self.search([('code', '=', knife_handle_item['code'])]).write(val)
else:
raise ValidationError("刀具物料基本参数认证未通过")
@@ -3097,6 +3078,7 @@ class CuttingToolBasicParameters(models.Model):
'cooling_model': knife_handle_item['cooling_model'],
'is_quick_cutting': knife_handle_item['is_quick_cutting'],
'is_safe_lock': knife_handle_item['is_safe_lock'],
+ 'fit_chuck_size': knife_handle_item['fit_chuck_size'],
'screw': knife_handle_item['fit_wrench_model'],
'nut': knife_handle_item['fit_nut_model'],
'dynamic_balance_class': knife_handle_item['dynamic_balance_class'],
@@ -3121,6 +3103,7 @@ class CuttingToolBasicParameters(models.Model):
'max_rotate_speed': knife_handle_item['rotate_speed_max'],
'diameter_slip_accuracy': knife_handle_item['diameter_slip_accuracy'],
'cooling_model': knife_handle_item['cooling_model'],
+ 'fit_chuck_size': knife_handle_item['fit_chuck_size'],
'is_quick_cutting': knife_handle_item['is_quick_cutting'],
'is_safe_lock': knife_handle_item['is_safe_lock'],
'screw': knife_handle_item['fit_wrench_model'],
diff --git a/sf_tool_management/views/tool_base_views.xml b/sf_tool_management/views/tool_base_views.xml
index 4406a90f..b210ff29 100644
--- a/sf_tool_management/views/tool_base_views.xml
+++ b/sf_tool_management/views/tool_base_views.xml
@@ -1056,7 +1056,7 @@
-
+
diff --git a/sf_tool_management/wizard/wizard.py b/sf_tool_management/wizard/wizard.py
index dbece7b7..eac95d8c 100644
--- a/sf_tool_management/wizard/wizard.py
+++ b/sf_tool_management/wizard/wizard.py
@@ -295,35 +295,70 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
"""
for record in self:
if 'DJWL' in barcode:
- records = record.env['stock.lot'].search([('name', '=', barcode)])
- if not records:
+ lot_ids = record.env['stock.lot'].sudo().search([('name', '=', barcode)])
+ if not lot_ids:
raise ValidationError('扫描的条形码数据不存在,请重新扫描!')
- for record_stock_lot in records:
- if record_stock_lot.quant_ids[-1].location_id.name == '刀具组装位置':
- raise ValidationError('该刀具物料已使用,请重新选择!!!')
- elif record_stock_lot.quant_ids[-1].location_id.name not in '刀具房':
- raise ValidationError('该刀具物料未入库,请重新选择!!!')
- tool_material_name = record_stock_lot.product_id.cutting_tool_material_id.name
+ for lot_id in lot_ids:
+ if lot_id.quant_ids[-1].location_id.name == '刀具组装位置':
+ raise ValidationError('该刀具物料已使用,请重新扫描!!!')
+ elif lot_id.quant_ids[-1].location_id.name not in '刀具房':
+ raise ValidationError('该刀具物料未入库,请重新扫描!!!')
+ tool_material_name = lot_id.product_id.cutting_tool_material_id.name
if tool_material_name == '整体式刀具':
- record.integral_code_id = record_stock_lot.id
+ record.integral_code_id = lot_id.id
elif tool_material_name == '刀片':
- record.blade_code_id = record_stock_lot.id
+ record.blade_code_id = lot_id.id
elif tool_material_name == '刀杆':
- record.bar_code_id = record_stock_lot.id
+ record.bar_code_id = lot_id.id
elif tool_material_name == '刀盘':
- record.pad_code_id = record_stock_lot.id
+ record.pad_code_id = lot_id.id
elif tool_material_name == '刀柄':
- record.handle_code_id = record_stock_lot.id
+ record.handle_code_id = lot_id.id
+ record.chuck_code_id = record.get_chuck_code_id(lot_id).id or False
elif tool_material_name == '夹头':
- record.chuck_code_id = record_stock_lot.id
+ record.chuck_code_id = lot_id.id
else:
raise ValidationError('扫描的刀具物料不存在,请重新扫描!')
else:
- record.rfid = barcode
+ lot_ids = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
+ if not lot_ids:
+ raise ValidationError('扫描的刀具物料不存在,请重新扫描!')
+ for lot_id in lot_ids:
+ if lot_id.quant_ids[-1].location_id.name in '刀具房':
+ record.handle_code_id = lot_id.id
+ record.chuck_code_id = record.get_chuck_code_id(lot_id).id or False
+ elif lot_id.quant_ids[-1].location_id.name == '刀具组装位置':
+ raise ValidationError('该刀柄已使用,请重新扫描!!!')
+ else:
+ raise ValidationError('该刀柄未入库,请重新扫描!!!')
+
+ def get_chuck_code_id(self, lot_id):
+ # 适用夹头型号
+ cutting_tool_chuck_id = lot_id.product_id.cutting_tool_chuck_id
+ # 适用夹头尺寸
+ fit_chuck_size = lot_id.product_id.cutting_tool_fit_chuck_size
+ # 适用夹头产品
+ chuck_product_id = self.env['product.product'].sudo().search(
+ [('cutting_tool_model_id', '=', cutting_tool_chuck_id.id),
+ ('cutting_tool_er_size_model', '=', fit_chuck_size)])
+ # 适用夹头产品序列号
+ chuck_product_lot_ids = self.env['stock.lot'].sudo().search(
+ [('product_id', '=', chuck_product_id.id), ('tool_material_status', '=', '可用')])
+ for chuck_product_lot_id in chuck_product_lot_ids:
+ if chuck_product_lot_id.quant_ids[-1].location_id.name in '刀具房':
+ return chuck_product_lot_id
+
+ @api.depends('handle_code_id')
+ def _compute_rfid(self):
+ for item in self:
+ if item:
+ item.rfid = item.handle_code_id.rfid
+ else:
+ item.rfid = None
# 组装功能刀具参数信息
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号')
- rfid = fields.Char('Rfid', required=True)
+ rfid = fields.Char('Rfid', readonly=True, store=True, compute='_compute_rfid')
tool_code = fields.Char(string='功能刀具编码', readonly=True, compute='_compute_tool_code')
after_assembly_functional_tool_name = fields.Char(string='组装后功能刀具名称', compute='_compute_name')
after_assembly_functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model',
@@ -442,21 +477,6 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
if obj.after_assembly_functional_tool_length == 0:
raise ValidationError('组装参数信息【伸出长】不能为0!!!')
- @api.constrains('rfid')
- def _check_rfid(self):
- self.get_rfid()
-
- @api.onchange('rfid')
- def _onchange_rfid(self):
- self.get_rfid()
-
- def get_rfid(self):
- for obj in self:
- if obj.rfid:
- tool_entity = self.env['sf.functional.cutting.tool.entity'].sudo().search([('rfid', '=', obj.rfid)])
- if tool_entity:
- raise ValidationError('【%s】的Rfid已被使用,请重新录入!!!' % obj.rfid)
-
def functional_tool_assembly(self):
"""
功能刀具组装
diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py
index 3667c62c..328f5d43 100644
--- a/sf_warehouse/models/model.py
+++ b/sf_warehouse/models/model.py
@@ -746,9 +746,9 @@ class SfStockPicking(models.Model):
line.current_location_id.location_status = '空闲'
for move in self.move_ids:
- if move and move.product_id.cutting_tool_material_id.name in '刀柄':
+ if move and move.product_id.cutting_tool_material_id.name == '刀柄':
for item in move.move_line_nosuggest_ids:
- if item:
+ if item.location_dest_id.name == '进货':
self.env['stock.lot'].search([('name', '=', item.lot_name)]).write({'rfid': item.rfid})
return res
From 02e4987281f243508f7ad9c31dbaa200d2d26e76 Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Mon, 1 Apr 2024 17:12:47 +0800
Subject: [PATCH 04/19] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=80=89=E5=8F=96?=
=?UTF-8?q?=E9=80=82=E7=94=A8=E5=A4=B9=E5=A4=B4=E6=96=B9=E6=B3=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_tool_management/wizard/wizard.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/sf_tool_management/wizard/wizard.py b/sf_tool_management/wizard/wizard.py
index eac95d8c..285da727 100644
--- a/sf_tool_management/wizard/wizard.py
+++ b/sf_tool_management/wizard/wizard.py
@@ -347,6 +347,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
for chuck_product_lot_id in chuck_product_lot_ids:
if chuck_product_lot_id.quant_ids[-1].location_id.name in '刀具房':
return chuck_product_lot_id
+ return False
@api.depends('handle_code_id')
def _compute_rfid(self):
From f4f1c9f8397f48524fc79fdd430786f46cb794f3 Mon Sep 17 00:00:00 2001
From: "jinling.yang"
Date: Mon, 1 Apr 2024 17:34:56 +0800
Subject: [PATCH 05/19] =?UTF-8?q?1.=E6=96=B0=E5=A2=9E=E8=A1=A8=E9=9D=A2?=
=?UTF-8?q?=E5=B7=A5=E8=89=BA=E5=A4=96=E5=8D=8F=E8=B7=AF=E7=BA=BF=E5=88=9D?=
=?UTF-8?q?=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/data/stock_data.xml | 16 +++
sf_manufacturing/models/stock.py | 44 ++++++++
sf_sale/models/sale_order.py | 7 +-
sf_warehouse/models/model.py | 116 ++-------------------
sf_warehouse/views/view.xml | 146 +++++++++++++--------------
5 files changed, 145 insertions(+), 184 deletions(-)
diff --git a/sf_manufacturing/data/stock_data.xml b/sf_manufacturing/data/stock_data.xml
index 6bd0fe53..72559691 100644
--- a/sf_manufacturing/data/stock_data.xml
+++ b/sf_manufacturing/data/stock_data.xml
@@ -67,5 +67,21 @@
search="[('barcode','=','WH-PREPRODUCTION')]"/>
+
+
+ 表面工艺外协
+
+ True
+ 11
+
+
+
+
+
+
+
+
+
+
diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py
index f255d28b..dc2fff9d 100644
--- a/sf_manufacturing/models/stock.py
+++ b/sf_manufacturing/models/stock.py
@@ -17,6 +17,50 @@ from io import BytesIO
from odoo.exceptions import ValidationError
+class stockWarehouse(models.Model):
+ _inherit = 'stock.warehouse'
+
+ subcontracting_surface_technology_pull_out_id = fields.Many2one(
+ 'stock.rule', '表面工艺规则1')
+ subcontracting_surface_technology_pull_in_id = fields.Many2one(
+ 'stock.rule', '表面工艺规则2'
+ )
+
+ def _get_global_route_rules_values(self):
+ rules = super(stockWarehouse, self)._get_global_route_rules_values()
+ location_virtual_id = self.env.ref(
+ 'sf_manufacturing.stock_location_locations_virtual_outcontract').id,
+ location_pre_id = self.env['stock.location'].search(
+ [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id,
+ rules.update({
+ 'subcontracting_surface_technology_pull_in_id': {
+ 'create_values': {
+ 'action': 'pull',
+ 'picking_type_id': self.env.ref('sf_manufacturing.outcontract_picking_in').id,
+ 'group_propagation_option': 'none',
+ 'company_id': self.company_id.id,
+ 'location_src_id': location_virtual_id,
+ 'location_dest_id': location_pre_id,
+ 'route_id': self._find_global_route('sf_manufacturing.route_surface_technology_outsourcing',
+ _('表面工艺外协')).id,
+ }
+ },
+ 'subcontracting_surface_technology_pull_out_id': {
+ 'create_values': {
+ 'action': 'pull',
+ 'picking_type_id': self.env.ref('sf_manufacturing.outcontract_picking_out').id,
+ 'group_propagation_option': 'none',
+ 'company_id': self.company_id.id,
+ 'location_src_id': location_pre_id,
+ 'location_dest_id': location_virtual_id,
+ 'route_id': self._find_global_route('sf_manufacturing.route_surface_technology_outsourcing',
+ _('表面工艺外协')).id,
+ }
+ }
+ })
+ return rules
+
+
class StockRule(models.Model):
_inherit = 'stock.rule'
diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py
index a55f9fb3..e2313ba3 100644
--- a/sf_sale/models/sale_order.py
+++ b/sf_sale/models/sale_order.py
@@ -85,11 +85,16 @@ class ReSaleOrder(models.Model):
self.check_status = 'pending'
def get_customer(self):
+ partner_tag = self.env['res.partner.category'].search([('name', '=', '业务平台')], limit=1, order='id asc')
+ if not partner_tag:
+ partner_tag = self.env['res.partner.category'].create({'name': '平台客户'})
customer = self.env['res.partner'].search([('name', '=', '业务平台')], limit=1, order='id asc')
if customer:
+ if not customer.vat:
+ customer.write({'name': '业务平台', 'vat': '91430103MA7BRH9K4M', 'phone': '0731-85115515',
+ 'email': 'jikimo@jikimo.com', 'category_id': [Command.set([partner_tag.id])]})
return customer
else:
- partner_tag = self.env['res.partner.category'].create({'name': '平台客户'})
partner = self.env['res.partner'].create(
{'name': '业务平台', 'vat': '91430103MA7BRH9K4M', 'phone': '0731-85115515',
'email': 'jikimo@jikimo.com', 'category_id': [Command.set([partner_tag.id])]})
diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py
index 2228d2d5..931c6410 100644
--- a/sf_warehouse/models/model.py
+++ b/sf_warehouse/models/model.py
@@ -19,13 +19,6 @@ class SfLocation(models.Model):
name = fields.Char('Location Name', required=True, size=20)
barcode = fields.Char('Barcode', copy=False, size=15)
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
# 仓库类别(selection:库区、库位、货位)
# location_type = fields.Selection([
@@ -822,112 +815,15 @@ class SfProcurementGroup(models.Model):
return res
-class SfWarehouse(models.Model):
- _inherit = 'stock.warehouse'
-
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfRule(models.Model):
- _inherit = 'stock.rule'
-
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfRoute(models.Model):
- _inherit = 'stock.route'
-
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
class SfPickingType(models.Model):
_inherit = 'stock.picking.type'
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfBarcodeNomenclature(models.Model):
- _inherit = 'barcode.nomenclature'
-
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfPutawayRule(models.Model):
- _inherit = 'stock.putaway.rule'
-
- check_state = fields.Selection([
- ('enable', '同意'),
- ('close', '不同意')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfWarehouseOrderpoint(models.Model):
- _inherit = 'stock.warehouse.orderpoint'
-
- check_state = fields.Selection([
- ('enable', '同意'),
- ('close', '不同意')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfStockQuant(models.Model):
- _inherit = 'stock.quant'
-
- check_state = fields.Selection([
- ('enable', '同意'),
- ('close', '不同意')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfStockScrap(models.Model):
- _inherit = 'stock.scrap'
-
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
+ def _default_show_operations(self):
+ return self.user_has_groups('stock.group_production_lot,'
+ 'stock.group_stock_multi_locations,'
+ 'stock.group_tracking_lot',
+ 'sf_warehouse.group_sf_stock_user',
+ 'sf_warehouse.group_sf_stock_manager')
class CustomStockMove(models.Model):
diff --git a/sf_warehouse/views/view.xml b/sf_warehouse/views/view.xml
index 39d5a8c0..aa3293ce 100644
--- a/sf_warehouse/views/view.xml
+++ b/sf_warehouse/views/view.xml
@@ -67,16 +67,16 @@
-
-
+
+
+
+
+
+
+
+
-
+
@@ -188,23 +188,23 @@
-
- stock.warehouse.form.sf.inherit
- stock.warehouse
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -220,23 +220,23 @@
-
- stock.route.form.sf.inherit
- stock.route
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -251,23 +251,23 @@
-
- stock.rule.form.sf.inherit
- stock.rule
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -282,23 +282,23 @@
-
- stock.picking.type.form.sf.inherit
- stock.picking.type
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
From 2580e0c795768ee0e533df03b08182c9207ea86a Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Tue, 2 Apr 2024 15:36:28 +0800
Subject: [PATCH 06/19] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E4=BA=A7?=
=?UTF-8?q?=E5=93=81=E9=87=87=E8=B4=AD=E5=88=80=E5=85=B7=E7=89=A9=E6=96=99?=
=?UTF-8?q?=E7=94=9F=E6=88=90=E7=9A=84=E5=BA=8F=E5=88=97=E5=8F=B7=E5=87=BA?=
=?UTF-8?q?=E7=8E=B0=E4=B8=8D=E8=BF=9E=E7=BB=AD=E7=9A=84=E9=97=AE=E9=A2=98?=
=?UTF-8?q?=EF=BC=9B2=E3=80=81=E9=87=87=E8=B4=AD=E5=88=80=E6=9F=84?=
=?UTF-8?q?=E7=89=A9=E6=96=99=E6=97=B6=EF=BC=8C=E5=9C=A8=E5=85=A5=E5=BA=93?=
=?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=8E=AF=E8=8A=82=E5=A2=9E=E5=8A=A0Rfid?=
=?UTF-8?q?=E6=98=AF=E5=90=A6=E5=85=A8=E9=83=A8=E5=BD=95=E5=85=A5=E6=A3=80?=
=?UTF-8?q?=E9=AA=8C=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/models/stock.py | 2 +-
sf_warehouse/models/model.py | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py
index d777d48b..6ea88c4c 100644
--- a/sf_manufacturing/models/stock.py
+++ b/sf_manufacturing/models/stock.py
@@ -280,7 +280,7 @@ class ProductionLot(models.Model):
if not last_serial:
return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, 1)
else:
- return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, int(last_serial.name[-3:]) + 2)
+ return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, int(last_serial.name[-3:]) + 1)
else:
raise ValidationError('该刀具物料产品的型号字段为空,请补充完整!!!')
diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py
index 84e2a771..6e1dd356 100644
--- a/sf_warehouse/models/model.py
+++ b/sf_warehouse/models/model.py
@@ -749,6 +749,8 @@ class SfStockPicking(models.Model):
if move and move.product_id.cutting_tool_material_id.name == '刀柄':
for item in move.move_line_nosuggest_ids:
if item.location_dest_id.name == '进货':
+ if not item.rfid:
+ raise ValidationError('你需要提供%s的Rfid' % move.product_id.name)
self.env['stock.lot'].search([('name', '=', item.lot_name)]).write({'rfid': item.rfid})
return res
From aac5195b4d8d44692e2435751ee4d987bb1c9de4 Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Tue, 2 Apr 2024 16:38:19 +0800
Subject: [PATCH 07/19] =?UTF-8?q?=E5=BD=93=E4=BA=A7=E5=93=81=E7=9A=84?=
=?UTF-8?q?=E5=88=80=E5=85=B7=E7=89=A9=E6=96=99=E4=B8=8D=E6=98=AF=E5=88=80?=
=?UTF-8?q?=E6=9F=84=E6=97=B6=EF=BC=8C=E9=9A=90=E8=97=8F=E5=AF=B9=E5=BA=94?=
=?UTF-8?q?=E5=BA=8F=E5=88=97=E5=8F=B7=E6=A8=A1=E5=9E=8B=E7=9A=84Rfid?=
=?UTF-8?q?=E5=AD=97=E6=AE=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/views/stock_lot_views.xml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sf_manufacturing/views/stock_lot_views.xml b/sf_manufacturing/views/stock_lot_views.xml
index f7ef9c9b..1d371102 100644
--- a/sf_manufacturing/views/stock_lot_views.xml
+++ b/sf_manufacturing/views/stock_lot_views.xml
@@ -14,7 +14,8 @@
-
+
+
From 02e597227213401873a73cb48d8e4dbd69c3d7f1 Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Wed, 3 Apr 2024 16:52:16 +0800
Subject: [PATCH 08/19] =?UTF-8?q?1=E3=80=81=E6=96=B0=E5=A2=9E=E8=A3=85?=
=?UTF-8?q?=E5=A4=B9=E9=A2=84=E8=B0=83=E5=B7=A5=E5=8D=95=E6=89=AB=E6=8B=96?=
=?UTF-8?q?=E7=9B=98Rfid=E7=BB=91=E5=AE=9A=E6=89=98=E7=9B=98=EF=BC=9B2?=
=?UTF-8?q?=E3=80=81=E5=88=A0=E9=99=A4=E5=B7=A5=E5=8D=95=E7=9A=84Rfid?=
=?UTF-8?q?=E5=AD=97=E6=AE=B5=E7=9A=84customRFID=E6=A0=B7=E5=BC=8F?=
=?UTF-8?q?=EF=BC=9B3=E3=80=81=E4=BF=AE=E6=94=B9=E5=BA=8F=E5=88=97?=
=?UTF-8?q?=E5=8F=B7=E6=A8=A1=E5=9E=8B=E7=9A=84Rfid=E5=AD=97=E6=AE=B5?=
=?UTF-8?q?=E7=9A=84=E9=9A=90=E8=97=8F=E6=9D=A1=E4=BB=B6=EF=BC=9B4?=
=?UTF-8?q?=E3=80=81=E4=BC=98=E5=8C=96=E5=88=80=E6=9F=84=E3=80=81=E6=89=98?=
=?UTF-8?q?=E7=9B=98=E7=89=A9=E6=96=99=E9=87=87=E8=B4=AD=E6=97=B6=E7=BB=91?=
=?UTF-8?q?=E5=AE=9ARfid=E7=9A=84=E5=88=A4=E6=96=AD=E6=9D=A1=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/models/mrp_workorder.py | 120 +++++++++++-------
sf_manufacturing/models/stock.py | 1 -
sf_manufacturing/views/mrp_workorder_view.xml | 5 +-
sf_manufacturing/views/stock_lot_views.xml | 3 +-
sf_warehouse/models/model.py | 21 ++-
5 files changed, 89 insertions(+), 61 deletions(-)
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index 7b3467b7..c71411c3 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -1,3 +1,5 @@
+import re
+
import logging
import base64
import urllib.parse
@@ -819,57 +821,77 @@ class SfWorkOrderBarcodes(models.Model):
workorder = self.env['mrp.workorder'].browse(self.ids)
# workorder = self.env['mrp.workorder'].search(
# [('routing_type', '=', '装夹预调'), ('production_id', '=', self.production_id.id)])
+ workorder_old = self.env['mrp.workorder'].search([('rfid_code', '=', barcode)])
+ if workorder_old:
+ raise UserError('该托盘已绑定工件,请先解除绑定!!!')
if workorder:
if workorder.routing_type == '装夹预调':
- stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)])
- 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,
- '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()
- # return {
- # 'type': 'ir.actions.act_window',
- # 'res_model': 'mrp.workorder',
- # 'view_mode': 'form',
- # 'domain': [('id', 'in', workorder.id)],
- # 'target': 'current'
- # }
- else:
- embryo_stock_lot = self.env['stock.lot'].search([('name', '=', barcode)])
- if embryo_stock_lot:
- embryo_stock_move_line = self.env['stock.move.line'].search(
- [('product_id', '=', embryo_stock_lot.product_id.id),
- ('reference', '=', workorder.production_id.name),
- ('lot_id', '=', embryo_stock_lot.id),
- ('product_category_name', '=', '坯料')])
- if embryo_stock_move_line:
- bom_production = self.env['mrp.production'].search(
- [('product_id', '=', embryo_stock_lot.product_id.id),
- ('origin', '=', workorder.production_id.name)], limit=1, order='id asc')
- workpiece_delivery = self.env['sf.workpiece.delivery'].search(
- [('workorder_id', '=', workorder.id)], limit=1, order='id asc')
- if workpiece_delivery:
- embryo_workpiece_code = workpiece_delivery.workpiece_code
- if bom_production:
- if workpiece_delivery.workpiece_code and bom_production.name not in \
- workpiece_delivery.workpiece_code:
- embryo_workpiece_code = workpiece_delivery.workpiece_code + ',' + \
- bom_production.name
- if not workpiece_delivery.workpiece_code:
- embryo_workpiece_code = bom_production.name
- workpiece_delivery.write({'workpiece_code': embryo_workpiece_code})
- else:
- raise UserError('工件生产线不一致,请重新确认')
- else:
- workorder_rfid = self.env['mrp.workorder'].search(
- [('production_id', '=', workorder.production_id.id)])
- if workorder_rfid:
- for item in workorder_rfid:
- item.write({'rfid_code': barcode})
+ lots = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
+ if lots:
+ for lot in lots:
+ if lot.product_id.categ_type == '夹具':
+ workorder.write({
+ 'tray_serial_number': lot.name,
+ 'tray_product_id': lot.product_id.id,
+ 'tray_brand_id': lot.product_id.brand_id.id,
+ 'tray_type_id': lot.product_id.fixture_material_id.id,
+ 'tray_model_id': lot.product_id.fixture_model_id.id
+ })
+ workorder_rfid = self.env['mrp.workorder'].search(
+ [('production_id', '=', workorder.production_id.id)])
+ if workorder_rfid:
+ for item in workorder_rfid:
+ item.write({'rfid_code': barcode})
+ workorder.env.cr.commit()
+ # stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)])
+ # 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,
+ # '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()
+ # # return {
+ # # 'type': 'ir.actions.act_window',
+ # # 'res_model': 'mrp.workorder',
+ # # 'view_mode': 'form',
+ # # 'domain': [('id', 'in', workorder.id)],
+ # # 'target': 'current'
+ # # }
+ # else:
+ # embryo_stock_lot = self.env['stock.lot'].search([('name', '=', barcode)])
+ # if embryo_stock_lot:
+ # embryo_stock_move_line = self.env['stock.move.line'].search(
+ # [('product_id', '=', embryo_stock_lot.product_id.id),
+ # ('reference', '=', workorder.production_id.name),
+ # ('lot_id', '=', embryo_stock_lot.id),
+ # ('product_category_name', '=', '坯料')])
+ # if embryo_stock_move_line:
+ # bom_production = self.env['mrp.production'].search(
+ # [('product_id', '=', embryo_stock_lot.product_id.id),
+ # ('origin', '=', workorder.production_id.name)], limit=1, order='id asc')
+ # workpiece_delivery = self.env['sf.workpiece.delivery'].search(
+ # [('workorder_id', '=', workorder.id)], limit=1, order='id asc')
+ # if workpiece_delivery:
+ # embryo_workpiece_code = workpiece_delivery.workpiece_code
+ # if bom_production:
+ # if workpiece_delivery.workpiece_code and bom_production.name not in \
+ # workpiece_delivery.workpiece_code:
+ # embryo_workpiece_code = workpiece_delivery.workpiece_code + ',' + \
+ # bom_production.name
+ # if not workpiece_delivery.workpiece_code:
+ # embryo_workpiece_code = bom_production.name
+ # workpiece_delivery.write({'workpiece_code': embryo_workpiece_code})
+ # else:
+ # raise UserError('工件生产线不一致,请重新确认')
+ # else:
+ # workorder_rfid = self.env['mrp.workorder'].search(
+ # [('production_id', '=', workorder.production_id.id)])
+ # if workorder_rfid:
+ # for item in workorder_rfid:
+ # item.write({'rfid_code': barcode})
class WorkPieceDelivery(models.Model):
diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py
index 6ea88c4c..5833b095 100644
--- a/sf_manufacturing/models/stock.py
+++ b/sf_manufacturing/models/stock.py
@@ -223,7 +223,6 @@ class ProductionLot(models.Model):
_inherit = ['stock.lot', 'printing.utils']
rfid = fields.Char('Rfid', readonly=True)
- product_material_name = fields.Char('刀具产品物料名称', related='product_id.cutting_tool_material_id.name')
product_specification = fields.Char('规格', compute='_compute_product_specification', store=True)
@api.depends('product_id')
diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml
index 4a766526..b1ca9946 100644
--- a/sf_manufacturing/views/mrp_workorder_view.xml
+++ b/sf_manufacturing/views/mrp_workorder_view.xml
@@ -184,10 +184,9 @@
attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/>
-
-
@@ -242,6 +241,7 @@
+
@@ -250,7 +250,6 @@
-
diff --git a/sf_manufacturing/views/stock_lot_views.xml b/sf_manufacturing/views/stock_lot_views.xml
index 1d371102..aef50e55 100644
--- a/sf_manufacturing/views/stock_lot_views.xml
+++ b/sf_manufacturing/views/stock_lot_views.xml
@@ -14,8 +14,7 @@
-
-
+
diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py
index 6e1dd356..cc2e20c8 100644
--- a/sf_warehouse/models/model.py
+++ b/sf_warehouse/models/model.py
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
+import re
+
import datetime
import logging
import base64
@@ -424,7 +426,7 @@ class Sf_stock_move_line(models.Model):
# lot_qr_code = fields.Binary(string='二维码', compute='_compute_lot_qr_code', store=True)
lot_qr_code = fields.Binary(string='二维码', compute='_compute_lot_qr_code', store=True)
- rfid = fields.Char('Rfid')
+ rfid = fields.Char('Rfid', readonly=True)
def action_revert_inventory(self):
# 检查用户是否有执行操作的权限
@@ -746,7 +748,8 @@ class SfStockPicking(models.Model):
line.current_location_id.location_status = '空闲'
for move in self.move_ids:
- if move and move.product_id.cutting_tool_material_id.name == '刀柄':
+ if move and move.product_id.cutting_tool_material_id.name == '刀柄' or '托盘' in (
+ move.product_id.fixture_material_id.name or ''):
for item in move.move_line_nosuggest_ids:
if item.location_dest_id.name == '进货':
if not item.rfid:
@@ -950,16 +953,22 @@ class CustomStockMove(models.Model):
"""
for record in self:
if record:
- if '刀柄' in record.product_id.cutting_tool_material_id.name:
+ if '刀柄' in (record.product_id.cutting_tool_material_id.name or '') or '托盘' in (
+ record.product_id.fixture_material_id.name or ''):
for move_line_nosuggest_id in record.move_line_nosuggest_ids:
if move_line_nosuggest_id.rfid:
if move_line_nosuggest_id.rfid == barcode:
- raise ValidationError('该刀柄的rfid已经录入,请勿重复录入!!!')
+ if record.product_id.cutting_tool_material_id.name:
+ raise ValidationError('该刀柄的Rfid已经录入,请勿重复录入!!!')
+ else:
+ raise ValidationError('该托盘的Rfid已经录入,请勿重复录入!!!')
else:
- move_line_nosuggest_id.sudo().rfid = barcode
+ line_id = int(re.sub(r"\D", "", str(move_line_nosuggest_id.id)))
+ self.env['stock.move.line'].sudo().search([('id', '=', line_id)]).write({'rfid': barcode})
+ move_line_nosuggest_id.rfid = barcode
break
else:
- raise ValidationError('该产品不是刀柄!!!')
+ raise ValidationError('该产品不需要录入Rfid!!!')
def action_assign_serial_show_details(self):
# 首先执行原有逻辑
From 2ef832c17ec7e04e99dbeb5033d96c2f223d2e42 Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Wed, 3 Apr 2024 17:23:57 +0800
Subject: [PATCH 09/19] =?UTF-8?q?=E6=9A=82=E6=97=B6=E5=85=B3=E9=97=AD?=
=?UTF-8?q?=E5=B7=A5=E5=8D=95=E6=89=ABRfid=E7=BB=91=E5=AE=9A=E6=89=98?=
=?UTF-8?q?=E7=9B=98=E7=9A=84Rfid=E9=87=8D=E5=A4=8D=E9=AA=8C=E8=AF=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/models/mrp_workorder.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index c71411c3..14af7aab 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -821,9 +821,9 @@ class SfWorkOrderBarcodes(models.Model):
workorder = self.env['mrp.workorder'].browse(self.ids)
# workorder = self.env['mrp.workorder'].search(
# [('routing_type', '=', '装夹预调'), ('production_id', '=', self.production_id.id)])
- workorder_old = self.env['mrp.workorder'].search([('rfid_code', '=', barcode)])
- if workorder_old:
- raise UserError('该托盘已绑定工件,请先解除绑定!!!')
+ # workorder_old = self.env['mrp.workorder'].search([('rfid_code', '=', barcode)])
+ # if workorder_old:
+ # raise UserError('该托盘已绑定工件,请先解除绑定!!!')
if workorder:
if workorder.routing_type == '装夹预调':
lots = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
From 4dd733c466a2fda0683517e2e9dc6c20f8414280 Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Sun, 7 Apr 2024 15:35:47 +0800
Subject: [PATCH 10/19] =?UTF-8?q?1=E3=80=81=E5=A4=84=E7=90=86=E5=88=80?=
=?UTF-8?q?=E5=85=B7=E7=89=A9=E6=96=99=E6=B3=A8=E5=86=8C=E6=97=B6=E6=90=9C?=
=?UTF-8?q?=E7=B4=A2=E4=B8=8D=E5=88=B0=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?=
=?UTF-8?q?2=E3=80=81=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7=E7=BB=84?=
=?UTF-8?q?=E8=A3=85=E6=97=B6=EF=BC=8C=E5=BD=93=E6=B2=A1=E6=9C=89=E9=80=89?=
=?UTF-8?q?=E6=8B=A9=E7=89=A9=E6=96=99=E7=9A=84=E6=97=B6=E5=80=99=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD=E5=88=80=E5=85=B7=E7=BC=96=E7=A0=81=E4=B8=8D=E6=98=BE?=
=?UTF-8?q?=E7=A4=BA=E6=95=B0=E6=8D=AE=EF=BC=9B=E6=B7=BB=E5=8A=A0=E6=9C=80?=
=?UTF-8?q?=E5=A4=A7=E5=AF=BF=E5=91=BD=E5=80=BC=E3=80=81=E6=8A=A5=E8=AD=A6?=
=?UTF-8?q?=E5=80=BC=E3=80=81=E6=9C=89=E6=95=88=E9=95=BF=E3=80=81=E9=81=BF?=
=?UTF-8?q?=E7=A9=BA=E9=95=BF=E7=9A=84=E5=BF=85=E5=A1=AB=E9=AA=8C=E8=AF=81?=
=?UTF-8?q?=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_tool_management/models/functional_tool_enroll.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sf_tool_management/models/functional_tool_enroll.py b/sf_tool_management/models/functional_tool_enroll.py
index d762c865..8fb781f8 100644
--- a/sf_tool_management/models/functional_tool_enroll.py
+++ b/sf_tool_management/models/functional_tool_enroll.py
@@ -40,7 +40,7 @@ class StockLot(models.Model):
sf_secret_key = sf_sync_config['sf_secret_key']
headers = Common.get_headers(self, token, sf_secret_key)
str_url = sf_sync_config['sf_url'] + "/api/tool_material_stock/create"
- objs_all = self.env['stock.lot'].search([('id', '=', self.id)])
+ objs_all = self.env['stock.lot'].search([('id', '=', self.id), ('active', 'in', [True, False])])
tool_material_stock_list = []
if objs_all:
for item in objs_all:
From 000280e53a00362914455e674d7999a85ab519d8 Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Sun, 7 Apr 2024 15:36:05 +0800
Subject: [PATCH 11/19] no message
---
sf_tool_management/wizard/wizard.py | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/sf_tool_management/wizard/wizard.py b/sf_tool_management/wizard/wizard.py
index 285da727..90b8da63 100644
--- a/sf_tool_management/wizard/wizard.py
+++ b/sf_tool_management/wizard/wizard.py
@@ -413,7 +413,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
num = self._get_code(str_2)
obj.tool_code = str_2 + str(num)
else:
- obj.tool_code = None
+ obj.tool_code = ''
def _get_code(self, str_2):
functional_tool_assembly = self.env['sf.functional.tool.assembly'].sudo().search(
@@ -470,13 +470,23 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
else:
record.L_D_number = 0
- @api.constrains('after_assembly_tool_loading_length', 'after_assembly_functional_tool_length')
+ @api.constrains('after_assembly_tool_loading_length', 'after_assembly_functional_tool_length',
+ 'after_assembly_max_lifetime_value', 'after_assembly_alarm_value',
+ 'after_assembly_effective_length', 'hiding_length')
def _check_length_control(self):
for obj in self:
if obj.after_assembly_tool_loading_length == 0:
raise ValidationError('组装参数信息【总长度】不能为0!!!')
if obj.after_assembly_functional_tool_length == 0:
raise ValidationError('组装参数信息【伸出长】不能为0!!!')
+ if obj.after_assembly_max_lifetime_value == 0:
+ raise ValidationError('组装参数信息【最大寿命值】不能为0!!!')
+ if obj.after_assembly_alarm_value == 0:
+ raise ValidationError('组装参数信息【报警值】不能为0!!!')
+ if obj.after_assembly_effective_length == 0:
+ raise ValidationError('组装参数信息【有效长】不能为0!!!')
+ if obj.hiding_length == 0:
+ raise ValidationError('组装参数信息【避空长】不能为0!!!')
def functional_tool_assembly(self):
"""
From 4faeda11b839b27a3745e1111eebb4566eea83ce Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Mon, 8 Apr 2024 14:43:46 +0800
Subject: [PATCH 12/19] =?UTF-8?q?1=E3=80=81=E4=BC=98=E5=8C=96=E5=B7=A5?=
=?UTF-8?q?=E5=8D=95=E6=89=AB=E6=89=98=E7=9B=98Rfid=E7=BB=91=E5=AE=9ARfid?=
=?UTF-8?q?=E7=A0=81=E5=BD=95=E5=85=A5=E4=BF=A1=E6=81=AF=E6=97=B6=EF=BC=8C?=
=?UTF-8?q?=E5=B7=A5=E5=8D=95=E7=9A=84=E5=BC=80=E5=A7=8B=E7=AD=89=E6=8C=89?=
=?UTF-8?q?=E9=94=AE=E6=B6=88=E5=A4=B1=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/models/mrp_workorder.py | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index 14af7aab..3b6e8ead 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -826,23 +826,30 @@ class SfWorkOrderBarcodes(models.Model):
# raise UserError('该托盘已绑定工件,请先解除绑定!!!')
if workorder:
if workorder.routing_type == '装夹预调':
+ if workorder.state in ['progress', 'done']:
+ work_state = {'progress': '进行中', 'done': '已完工'}
+ raise UserError('该工单%s,不能重新绑定托盘' % work_state.get(workorder.state))
lots = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
if lots:
for lot in lots:
if lot.product_id.categ_type == '夹具':
- workorder.write({
+ val = {
'tray_serial_number': lot.name,
'tray_product_id': lot.product_id.id,
'tray_brand_id': lot.product_id.brand_id.id,
'tray_type_id': lot.product_id.fixture_material_id.id,
- 'tray_model_id': lot.product_id.fixture_model_id.id
- })
+ 'tray_model_id': lot.product_id.fixture_model_id.id,
+ 'rfid_code': barcode
+ }
+ workorder.write(val)
+ self.write(val)
workorder_rfid = self.env['mrp.workorder'].search(
[('production_id', '=', workorder.production_id.id)])
if workorder_rfid:
for item in workorder_rfid:
item.write({'rfid_code': barcode})
- workorder.env.cr.commit()
+ else:
+ raise UserError('该托盘信息不存在!!!')
# stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)])
# if stock_move_line.product_id.categ_type == '夹具':
# workorder.write({
From 07230703d80afb05830821c38bfbfdb5ab596339 Mon Sep 17 00:00:00 2001
From: "jinling.yang"
Date: Mon, 8 Apr 2024 16:39:26 +0800
Subject: [PATCH 13/19] =?UTF-8?q?1.=E4=BC=98=E5=8C=96agv=E9=85=8D=E7=BD=AE?=
=?UTF-8?q?=E5=8F=8A=E6=8E=A5=E5=8F=A3=EF=BC=9A=E6=96=B0=E5=A2=9E=E7=AB=99?=
=?UTF-8?q?=E7=82=B9=E9=9B=86=E5=90=88=E5=AF=B9=E8=B1=A1=EF=BC=8Cagv?=
=?UTF-8?q?=E8=BD=A6=E8=BE=86=E7=BC=96=E5=8F=B7=E5=8F=8A=E4=BB=BB=E5=8A=A1?=
=?UTF-8?q?=E5=8D=95=E7=B1=BB=E5=9E=8B=E7=BC=96=E5=8F=B7=E5=AD=97=E6=AE=B5?=
=?UTF-8?q?=202.=E4=BC=98=E5=8C=96rfid=E5=92=8C=E5=B7=A5=E5=8D=95=E9=83=A8?=
=?UTF-8?q?=E5=88=86=E9=9C=80=E6=B1=82=EF=BC=9A=E7=82=B9=E5=AE=8C=E5=B7=A5?=
=?UTF-8?q?=E6=8C=89=E9=92=AE=EF=BC=8C=E8=8B=A5=E4=B8=BA=E5=B7=A5=E4=BB=B6?=
=?UTF-8?q?=E8=A3=85=E5=A4=B9=E5=B7=A5=E5=8D=95=EF=BC=8C=E5=AE=8C=E5=B7=A5?=
=?UTF-8?q?=E9=9C=80=E6=A0=A1=E9=AA=8C=E5=B7=A5=E4=BB=B6=E5=9D=AF=E6=96=99?=
=?UTF-8?q?=E3=80=81RFID=E7=A0=81=E3=80=81=E5=89=8D=E7=BD=AE=E4=B8=89?=
=?UTF-8?q?=E5=85=83=E5=AE=9A=E4=BD=8D=E6=98=AF=E5=90=A6=E5=A1=AB=E5=86=99?=
=?UTF-8?q?=EF=BC=9B=E8=8B=A5=E6=9C=AA=E5=A1=AB=E5=86=99=EF=BC=8C=E9=A1=B5?=
=?UTF-8?q?=E9=9D=A2=E5=BC=B9=E5=87=BA=E5=AF=B9=E5=BA=94=E6=8F=90=E7=A4=BA?=
=?UTF-8?q?=EF=BC=8C=E5=8F=8D=E4=B9=8B=E5=88=99=E9=9C=80=E8=A6=81=E4=BA=8C?=
=?UTF-8?q?=E6=AC=A1=E7=A1=AE=E8=AE=A4=E5=BC=B9=E7=AA=97=203.=E6=96=B0?=
=?UTF-8?q?=E5=A2=9E=E6=9C=80=E5=88=9D=E7=89=88=E7=9A=84=E5=BF=AB=E9=80=9F?=
=?UTF-8?q?=E8=AE=A2=E5=8D=95=EF=BC=9A=E4=B8=BA=E4=BA=86=E5=B7=A5=E5=8E=82?=
=?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=B8=8B=E5=8D=95=E8=B5=B0=E6=B5=81=E7=A8=8B?=
=?UTF-8?q?=204.=E5=B7=A5=E5=8D=95=E4=BC=98=E5=8C=96=EF=BC=9A=E6=96=B0?=
=?UTF-8?q?=E5=A2=9E=E6=A3=80=E6=B5=8B=E7=BB=93=E6=9E=9C=E5=92=8C=E6=98=AF?=
=?UTF-8?q?=E5=90=A6=E9=87=8D=E6=96=B0=E7=94=9F=E6=88=90=E5=88=B6=E9=80=A0?=
=?UTF-8?q?=E8=AE=A2=E5=8D=95=E5=AD=97=E6=AE=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/controllers/controllers.py | 5 +-
sf_manufacturing/models/mrp_workorder.py | 8 +-
sf_manufacturing/views/mrp_workorder_view.xml | 25 +-
sf_mrs_connect/models/res_config_setting.py | 24 +-
sf_mrs_connect/security/ir.model.access.csv | 1 +
.../views/res_config_settings_views.xml | 32 ++
sf_sale/models/__init__.py | 3 +-
sf_sale/models/quick_easy_order_old.py | 326 ++++++++++++++++++
8 files changed, 397 insertions(+), 27 deletions(-)
create mode 100644 sf_sale/models/quick_easy_order_old.py
diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py
index c548222a..63fd4f57 100644
--- a/sf_manufacturing/controllers/controllers.py
+++ b/sf_manufacturing/controllers/controllers.py
@@ -238,7 +238,7 @@ class Manufacturing_Connect(http.Controller):
workorder = request.env['mrp.workorder'].sudo().search(
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
if workorder:
- workorder.test_result = ret['Quality']
+ # workorder.test_results = ret['Quality']
logging.info('制造订单:%s' % workorder.production_id.name)
if 'ReportPaht' in ret:
download_state = request.env['mrp.workorder'].with_user(
@@ -261,8 +261,7 @@ class Manufacturing_Connect(http.Controller):
('picking_id', '=', stock_picking.id)])
if quality_check:
logging.info('质检单:%s' % quality_check.name)
- quality_check.write({'report_pdf': workorder.detection_report,
- 'report_result': workorder.test_result})
+ quality_check.write({'report_pdf': workorder.detection_report})
elif download_state == 2:
res = {'Succeed': False, 'ErrorCode': 205,
'Error': 'ReportPaht中的工件号与制造订单%s不匹配,请检查ReportPaht是否正确' % workorder.production_id.name}
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index 95f484ef..2258062f 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -96,7 +96,8 @@ class ResMrpWorkOrder(models.Model):
Y10_axis = fields.Float(default=0)
Z10_axis = fields.Float(default=0)
X_deviation_angle = fields.Integer(string="X轴偏差度", default=0)
- test_result = fields.Char("检测结果")
+ test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], default='合格',
+ string="检测结果")
cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工程序")
cmm_ids = fields.One2many("sf.cmm.program", 'workorder_id', string="CMM程序")
tray_code = fields.Char(string="托盘编码")
@@ -141,6 +142,7 @@ 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)
def get_plan_workorder(self, production_line):
tomorrow = (date.today() + timedelta(days=+1)).strftime("%Y-%m-%d")
@@ -444,7 +446,7 @@ class ResMrpWorkOrder(models.Model):
"""
重新生成制造订单或者重新生成工单
"""
- if self.test_result == '报废':
+ if self.test_results == '报废':
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(
@@ -476,7 +478,7 @@ class ResMrpWorkOrder(models.Model):
'mail.message_origin_link',
values={'self': production, 'origin': origin_production},
subtype_id=self.env.ref('mail.mt_note').id)
- if self.test_result == '返工':
+ 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())
diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml
index 9797178e..7fb05ae1 100644
--- a/sf_manufacturing/views/mrp_workorder_view.xml
+++ b/sf_manufacturing/views/mrp_workorder_view.xml
@@ -106,16 +106,12 @@
+ groups="sf_base.group_sf_mrp_user"/>
+ groups="sf_base.group_sf_mrp_user" confirm="是否确认完工"/>
-
@@ -437,16 +433,17 @@
-
+
+
-
-
-
+
+
+
+
+
diff --git a/sf_mrs_connect/models/res_config_setting.py b/sf_mrs_connect/models/res_config_setting.py
index cbefba19..f34ab06f 100644
--- a/sf_mrs_connect/models/res_config_setting.py
+++ b/sf_mrs_connect/models/res_config_setting.py
@@ -13,10 +13,11 @@ class ResConfigSettings(models.TransientModel):
token = fields.Char(string='TOKEN', default='b811ac06-3f00-11ed-9aed-0242ac110003')
sf_secret_key = fields.Char(string='密钥', default='wBmxej38OkErKhD6')
sf_url = fields.Char(string='访问地址', default='https://sf.cs.jikimo.com')
- agv_rcms_url = fields.Char(string='avg_rcms访问地址',
- default='http://IP:PORT/rcms/services/rest/hikRpcService/genAgvSchedulingTask')
- agv_rcs_url = fields.Char(string='avg_rcs访问地址', default='http://IP:PORT/xxx/agv/agvCallbackService/agvCallback')
+ agv_rcs_url = fields.Char(string='avg_rcs访问地址',
+ default='http://172.16.10.114:8182/rcms/services/rest/hikRpcService/genAgvSchedulingTask')
wbcode = fields.Char('地码')
+ agv_code = fields.Char(string='agv编号')
+ task_type_no = fields.Char('任务单类型编号')
model_parser_url = fields.Char('特征识别路径')
ftp_host = fields.Char(string='FTP的ip')
ftp_port = fields.Char(string='FTP端口')
@@ -95,8 +96,9 @@ class ResConfigSettings(models.TransientModel):
token = config.get_param('token', default='')
sf_secret_key = config.get_param('sf_secret_key', default='')
sf_url = config.get_param('sf_url', default='')
- agv_rcms_url = config.get_param('agv_rcms_url', default='')
agv_rcs_url = config.get_param('agv_rcs_url', default='')
+ agv_code = config.get_param('agv_code', default='')
+ task_type_no = config.get_param('task_type_no', default='')
ftp_host = config.get_param('ftp_host', default='')
ftp_port = config.get_param('ftp_port', default='')
ftp_user = config.get_param('ftp_user', default='')
@@ -106,8 +108,9 @@ class ResConfigSettings(models.TransientModel):
token=token,
sf_secret_key=sf_secret_key,
sf_url=sf_url,
- agv_rcms_url=agv_rcms_url,
agv_rcs_url=agv_rcs_url,
+ agv_code=agv_code,
+ task_type_no=task_type_no,
ftp_host=ftp_host,
ftp_port=ftp_port,
ftp_user=ftp_user,
@@ -121,9 +124,18 @@ class ResConfigSettings(models.TransientModel):
ir_config.set_param("token", self.token or "")
ir_config.set_param("sf_secret_key", self.sf_secret_key or "")
ir_config.set_param("sf_url", self.sf_url or "")
- ir_config.set_param("agv_rcms_url", self.agv_rcms_url or "")
ir_config.set_param("agv_rcs_url", self.agv_rcs_url or "")
+ ir_config.set_param("agv_code", self.agv_code or "")
+ ir_config.set_param("task_type_no", self.task_type_no or "")
ir_config.set_param("ftp_host", self.ftp_host or "")
ir_config.set_param("ftp_port", self.ftp_port or "")
ir_config.set_param("ftp_user", self.ftp_user or "")
ir_config.set_param("ftp_password", self.ftp_password or "")
+
+
+class ResAgvSite(models.Model):
+ _name = 'res.agv.site'
+ _description = 'agv站点'
+
+ type = fields.Selection([('00', '位置编号'), ('01', '库区编号'), ('02', '货架编号')], '类型')
+ content = fields.Char('内容')
diff --git a/sf_mrs_connect/security/ir.model.access.csv b/sf_mrs_connect/security/ir.model.access.csv
index 0ed43a62..f512ec84 100644
--- a/sf_mrs_connect/security/ir.model.access.csv
+++ b/sf_mrs_connect/security/ir.model.access.csv
@@ -1,5 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sf_static_resource_datasync,sf_static_resource_datasync,model_sf_static_resource_datasync,base.group_user,1,1,1,1
+access_res_agv_site,access_res_agv_site,model_res_agv_site,base.group_system,1,1,1,1
diff --git a/sf_mrs_connect/views/res_config_settings_views.xml b/sf_mrs_connect/views/res_config_settings_views.xml
index 5f457b4f..e297f0eb 100644
--- a/sf_mrs_connect/views/res_config_settings_views.xml
+++ b/sf_mrs_connect/views/res_config_settings_views.xml
@@ -1,6 +1,26 @@
+
+ agv站点集合
+ res.agv.site
+
+
+
+
+
+
+
+
+
+ 站点集合
+ res.agv.site
+ tree
+
+
+
+
res.config.settings.view.form.inherit.sf_sync
res.config.settings
@@ -84,10 +104,22 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sf_sale/models/__init__.py b/sf_sale/models/__init__.py
index 99b143c7..97400237 100644
--- a/sf_sale/models/__init__.py
+++ b/sf_sale/models/__init__.py
@@ -1,5 +1,6 @@
from . import sale_order
-from . import quick_easy_order
+# from . import quick_easy_order
+from . import quick_easy_order_old
from . import auto_quatotion_common
from . import parser_and_calculate_work_time
from . import preload_datas_functions
diff --git a/sf_sale/models/quick_easy_order_old.py b/sf_sale/models/quick_easy_order_old.py
new file mode 100644
index 00000000..28618488
--- /dev/null
+++ b/sf_sale/models/quick_easy_order_old.py
@@ -0,0 +1,326 @@
+import logging
+import base64
+import hashlib
+import os
+import platform
+import json
+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 odoo import models, fields, api
+from odoo.modules import get_resource_path
+from odoo.exceptions import ValidationError, UserError
+from odoo.addons.sf_base.commons.common import Common
+from . import parser_and_calculate_work_time as pc
+
+
+class QuickEasyOrder(models.Model):
+ _name = 'quick.easy.order'
+ _description = '简易下单'
+ _order = 'id desc'
+
+ name = fields.Char('订单编号', default=lambda self: self.env['ir.sequence'].next_by_code('quick.easy.order'))
+ model_length = 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_processing_side = fields.Char('加工面', default='A')
+ model_feature = fields.Char('特征')
+ machining_precision = fields.Selection([
+ ('0.10', '±0.10mm'),
+ ('0.05', '±0.05mm'),
+ ('0.03', '±0.03mm'),
+ ('0.02', '±0.02mm'),
+ ('0.01', '±0.01mm')], string='加工精度', default='0.10')
+ material_id = fields.Many2one('sf.production.materials', '材料')
+ material_model_id = fields.Many2one('sf.materials.model', '型号')
+ # process_id = fields.Many2one('sf.production.process', string='表面工艺')
+ parameter_ids = fields.Many2many('sf.production.process.parameter', 'process_item_order_rel', string='可选参数')
+ quantity = fields.Integer('数量', default=1)
+ unit_price = fields.Float('单价')
+ price = fields.Float('总价')
+ model_file = fields.Binary('glb模型文件')
+ upload_model_file = fields.Many2many('ir.attachment', 'upload_qf_model_file_attachment_ref', string='上传模型文件')
+ delivery_time = fields.Date('交货日期')
+ customer_id = fields.Many2one('res.partner', string='客户', default=lambda self: self.env.user.partner_id.id)
+ state = fields.Selection([('草稿', '草稿'), ('待派单', '待派单'),
+ ('待接单', '待接单'), ('加工中', '加工中'),
+ ('物流中', '物流中'), ('已交付', '已交付')], string='订单状态', default='草稿',
+ readonly=True)
+ model_color_state = fields.Selection([
+ ('success', '成功'),
+ ('fail', '失败')], string='模型上色状态')
+ processing_time = fields.Integer('加工时长(min)')
+
+ @api.depends('unit_price', 'quantity')
+ def _compute_total_amount(self):
+ for item in self:
+ item.price = item.unit_price * item.quantity
+
+ @api.depends('material_id', 'material_model_id')
+ def _compute_material_model(self):
+ for item in self:
+ materials = self.env['sf.production.materials'].search([], limit=1, order='id desc')
+ item.material_id = materials.id
+ item.material_model_id = self.env['sf.materials.model'].search(
+ [('materials_id', '=', materials.id)],
+ limit=1, order='id desc')
+
+ @api.model
+ def create(self, vals):
+ if vals.get('upload_model_file'):
+ logging.info('create-attachment:%s' % vals['upload_model_file'][0])
+ for item in vals['upload_model_file']:
+ print(len(item[2]))
+ if len(item[2]) > 0:
+ logging.info('create-attachment:%s' % int(item[2][0]))
+ attachment = self.env['ir.attachment'].sudo().search([('id', '=', int(item[2][0]))])
+ base64_data = base64.b64encode(attachment.datas)
+ base64_datas = base64_data.decode('utf-8')
+ model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
+ report_path = attachment._full_path(attachment.store_fname)
+ vals['model_file'] = self.transition_glb_file(report_path, model_code)
+ logging.info('create-model_file:%s' % len(vals['model_file']))
+ obj = super(QuickEasyOrder, self).create(vals)
+ self.model_coloring(obj)
+ logging.info('---------开始派单到工厂-------')
+ self.distribute_to_factory(obj)
+ obj.state = '待接单'
+ return obj
+
+ # 将attach的datas内容转为glb文件
+ def transition_glb_file(self, report_path, model_code):
+ shapes = read_step_file(report_path)
+ output_file = os.path.join('/tmp', str(model_code) + '.stl')
+ write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
+ # 转化为glb
+ output_glb_file = os.path.join('/tmp', str(model_code) + '.glb')
+ util_path = get_resource_path('sf_base', 'static/util')
+ cmd = 'python3 %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file)
+ os.system(cmd)
+ # 转base64
+ with open(output_glb_file, 'rb') as fileObj:
+ image_data = fileObj.read()
+ base64_data = base64.b64encode(image_data)
+ return base64_data
+
+ # return False
+
+ @api.onchange('upload_model_file')
+ def onchange_model_file(self):
+ for item in self:
+ if len(item.upload_model_file) > 1:
+ raise ValidationError('只允许上传一个文件')
+ if item.upload_model_file:
+ file_attachment_id = item.upload_model_file[0]
+ # 附件路径
+ report_path = file_attachment_id._full_path(file_attachment_id.store_fname)
+ logging.info("模型路径: %s" % report_path)
+ base64_data = base64.b64encode(file_attachment_id.datas)
+ base64_datas = base64_data.decode('utf-8')
+ model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
+ logging.info("模型编码: %s" % model_code)
+ item.model_file = self.transition_glb_file(report_path, model_code)
+ else:
+ item.model_file = False
+ item.model_feature = False
+ item.model_length = 0
+ item.model_width = 0
+ item.model_height = 0
+ item.model_volume = 0
+
+ def distribute_to_factory(self, obj):
+ """
+ 派单到工厂
+ :return:
+ """
+ try:
+ logging.info('---------派单到工厂-------')
+ res = {'bfm_process_order_list': []}
+ for item in obj:
+ attachment = item.upload_model_file[0]
+ base64_data = base64.b64encode(attachment.datas)
+ base64_datas = base64_data.decode('utf-8')
+ barcode = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
+ # logging.info('model_file-size: %s' % len(item.model_file))
+ res['bfm_process_order_list'].append({
+ 'model_long': item.model_length,
+ 'model_width': item.model_width,
+ 'model_height': item.model_height,
+ 'model_volume': item.model_volume,
+ 'model_machining_precision': item.machining_precision,
+ 'model_name': attachment.name,
+ 'model_data': base64_datas,
+ 'model_file': base64.b64encode(item.model_file).decode('utf-8'),
+ 'texture_code': item.material_id.materials_no,
+ 'texture_type_code': item.material_model_id.materials_no,
+ # 'surface_process_code': self.env['jikimo.surface.process']._json_surface_process_code(item),
+ 'process_parameters_code': self.env[
+ 'sf.production.process.parameter']._json_production_process_item_code(
+ item),
+ 'price': item.price,
+ 'number': item.quantity,
+ 'total_amount': item.price,
+ 'remark': '',
+ 'barcode': barcode
+ })
+ # res['bfm_process_order_list'] = json.dumps(res['bfm_process_order_list'])
+ product_id = self.env.ref('sf_dlm.product_template_sf').sudo()
+ self_machining_id = self.env.ref('sf_dlm.product_embryo_sf_self_machining').sudo()
+ outsource_id = self.env.ref('sf_dlm.product_embryo_sf_outsource').sudo()
+ purchase_id = self.env.ref('sf_dlm.product_embryo_sf_purchase').sudo()
+ company_id = self.env.ref('base.main_company').sudo()
+ # user_id = request.env.ref('base.user_admin').sudo()
+ order_id = self.env['sale.order'].sale_order_create(company_id, 'XXXXX', 'XXXXX', 'XXXXX',
+ str(datetime.now()), '现结', '支付宝')
+ i = 1
+ # 给sale_order的default_code字段赋值
+ aa = self.env['sale.order'].sudo().search([('name', '=', order_id.name)])
+ logging.info('---------aa------- %s' % aa.name)
+ aa.default_code = obj.name
+ for item in res['bfm_process_order_list']:
+ product = self.env['product.template'].sudo().product_create(product_id, item, order_id,
+ obj.name, i)
+ bom_data = self.env['mrp.bom'].get_bom(product)
+ logging.info('bom_data:%s' % bom_data)
+ if bom_data:
+ bom = self.env['mrp.bom'].bom_create(product, 'normal', False)
+ bom.bom_create_line_has(bom_data)
+ else:
+ if product.materials_type_id.gain_way == '自加工':
+ # 创建坯料
+ self_machining_embryo = self.env['product.template'].sudo().no_bom_product_create(
+ self_machining_id,
+ item, order_id,
+ 'self_machining',
+ i)
+ # 创建坯料的bom
+ self_machining_bom = self.env['mrp.bom'].bom_create(self_machining_embryo, 'normal', False)
+ # 创建坯料里bom的组件
+ self_machining_bom_line = self_machining_bom.bom_create_line(self_machining_embryo)
+ if self_machining_bom_line is False:
+ self.cr.rollback()
+ return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配')
+ # 产品配置bom
+ product_bom_self_machining = self.env['mrp.bom'].bom_create(product, 'normal', False)
+ product_bom_self_machining.bom_create_line_has(self_machining_embryo)
+ elif product.materials_type_id.gain_way == '外协':
+ # 创建坯料
+ outsource_embryo = self.env['product.template'].sudo().no_bom_product_create(outsource_id, item,
+ order_id,
+ 'subcontract', i)
+ # 创建坯料的bom
+ outsource_bom = self.env['mrp.bom'].bom_create(outsource_embryo, 'subcontract', True)
+ # 创建坯料的bom的组件
+ outsource_bom_line = outsource_bom.with_user(
+ self.env.ref("base.user_admin")).bom_create_line(outsource_embryo)
+ if outsource_bom_line is False:
+ self.cr.rollback()
+ return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配')
+ # 产品配置bom
+ product_bom_outsource = self.env['mrp.bom'].bom_create(product, 'normal', False)
+ product_bom_outsource.bom_create_line_has(outsource_embryo)
+ elif product.materials_type_id.gain_way == '采购':
+ purchase_embryo = self.env['product.template'].sudo().no_bom_product_create(purchase_id, item,
+ order_id,
+ 'purchase', i)
+ # 产品配置bom
+ product_bom_purchase = self.env['mrp.bom'].bom_create(product, 'normal', False)
+ product_bom_purchase.bom_create_line_has(purchase_embryo)
+ order_id.with_user(self.env.ref("base.user_admin")).sale_order_create_line(product, item)
+ except Exception as e:
+ # self.cr.rollback()
+ return UserError('工厂创建销售订单和产品失败,请联系管理员')
+
+ # 特征识别
+ def feature_recognition(self, report_path, model_code):
+ feature_path = self.env['sf.auto_quatotion.common'].sudo().get_feature_full_path()
+ process_time_db_path = self.env['sf.auto_quatotion.common'].sudo().get_process_time_db_path()
+ ret = self.env['sf.auto_quatotion.common'].sudo().get_auto_quatotion(report_path, feature_path,
+ process_time_db_path,
+ model_code)
+ return ret
+
+ # 模型上色
+ def model_coloring(self, order):
+ url = '/api/library_of_models/create'
+ config = self.env['res.config.settings'].get_values()
+ config_header = Common.get_headers(self, config['token'], config['sf_secret_key'])
+ logging.info('order: %s' % order.name)
+ if order:
+ attachment = order.upload_model_file[0]
+ base64_data = base64.b64encode(attachment.datas)
+ base64_datas = base64_data.decode('utf-8')
+ model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
+ logging.info('model_file-size: %s' % len(order.model_file))
+ logging.info('attachment.datas-size: %s' % len(attachment.datas))
+ vals = {
+ 'model_code': model_code,
+ 'model_data': base64_data,
+ 'model_name': attachment.name,
+ 'model_long': order.model_length,
+ 'model_width': order.model_width,
+ 'model_height': order.model_height,
+ 'model_volume': order.model_volume,
+ 'model_order_no': order.name,
+ 'remark': '订单号:%s 客户:%s' % (order.name, order.customer_id.name)
+ }
+ try:
+ ret = requests.post((config['sf_url'] + url), json={}, data=vals, headers=config_header,
+ timeout=60)
+ ret = ret.json()
+ # result = json.loads(ret['result'])
+ if ret['status'] == 1:
+ order.model_color_state = 'success'
+ else:
+ order.model_color_state = 'fail'
+ raise UserError(ret['message'])
+ except Exception as e:
+ order.model_color_state = 'fail'
+ raise UserError("模型上色失败")
+
+ # 自动报价
+ def _get_price(self, order):
+ url = '/api/automatic_quotes'
+ config = self.env['res.config.settings'].sudo().get_values()
+ config_header = Common.get_headers(self, config['token'], config['sf_secret_key'])
+ logging.info("报价接口..........% s" % order.name)
+ try:
+ if order:
+ vals = {}
+ # mrs合作伙伴token
+ vals['token'] = config['token']
+ vals['accuracy'] = order.machining_precision
+ vals['number'] = order.quantity
+ vals['process_code'] = 0
+ vals['texture_code'] = order.material_model_id.materials_no
+ vals['delivery_days'] = 15
+ if order.model_file:
+ for item in order.upload_model_file:
+ if item.ids[0]:
+ logging.info('create-attachment:%s' % int(item.ids[0]))
+ attachment = self.env['ir.attachment'].sudo().search([('id', '=', int(item.ids[0]))])
+ vals['attachment_id'] = attachment.id
+ else:
+ vals['attachment_id'] = ''
+ vals['feature_infos'] = order.model_feature
+ vals['model_long'] = order.model_length
+ vals['model_width'] = order.model_width
+ vals['model_height'] = order.model_height
+ logging.info('vals:%s' % vals)
+ ret = requests.post((config['sf_url'] + url), json={}, data=vals, headers=config_header)
+ result = json.dumps(json.loads(ret.text), ensure_ascii=False, indent=4, separators=(',', ':'))
+ logging.info('报价接口返回:%s' % result)
+ price_result = json.loads(result)
+ # random.randint(0, 10000)
+ order.write({'price': price_result.get('price')})
+ else:
+ raise UserError("订单不存在")
+ except Exception as e:
+ if ret['status'] != 1:
+ raise UserError(e)
+ else:
+ raise UserError("自动报价失败,请联系管理员")
From 4c9fbab4712704498dc75e9bcd00d663a575c502 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E7=84=B1?=
Date: Mon, 8 Apr 2024 17:17:27 +0800
Subject: [PATCH 14/19] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=B6=E9=80=A0?=
=?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=AD=90=E9=A1=B5=E9=9D=A2=E6=A0=B7=E5=BC=8F?=
=?UTF-8?q?=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/js/custom_form_status_indicator.js | 57 ++++++++-----------
.../static/src/scss/custom_style.scss | 12 ++++
sf_base/static/src/scss/test.scss | 3 +
sf_base/views/common_view.xml | 2 +-
4 files changed, 40 insertions(+), 34 deletions(-)
diff --git a/jikimo_frontend/static/src/js/custom_form_status_indicator.js b/jikimo_frontend/static/src/js/custom_form_status_indicator.js
index 7db13b4b..100542b8 100644
--- a/jikimo_frontend/static/src/js/custom_form_status_indicator.js
+++ b/jikimo_frontend/static/src/js/custom_form_status_indicator.js
@@ -4,6 +4,7 @@ import {patch} from '@web/core/utils/patch';
// import { Dialog } from "@web/core/dialog/dialog";
import {_t} from "@web/core/l10n/translation";
import {FormStatusIndicator} from "@web/views/form/form_status_indicator/form_status_indicator";
+import {ListRenderer} from "@web/views/list/list_renderer";
import {Field} from "@web/views/fields/field";
@@ -45,6 +46,11 @@ const filedRequiredList = {
'date_planned_start': { multiple: false, noLabel: false },
'date_planned_finished': { multiple: false, noLabel: false },
}
+const tableRequiredList = [
+ 'product_template_id', 'product_uom_qty', 'price_unit','product_id','product_qty',
+ 'name', 'fault_type', 'maintenance_standards', 'Period'
+]
+
patch(FormStatusIndicator.prototype, 'jikimo_frontend.FormStatusIndicator', {
// 你可以重写或者添加一些方法和属性
async _onDiscardChanges() {
@@ -110,7 +116,24 @@ patch(Field.prototype, 'jikimo_frontend.Field', {
}
}
})
-
+patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', {
+ setup(){
+ owl.onMounted(() => {
+ this.activeElement = this.uiService.activeElement;
+ this.setRequired()
+ })
+ return this._super(...arguments);
+ },
+ setRequired() {
+ this.allColumns.forEach(_ => {
+ if( tableRequiredList.indexOf(_.name) >= 0 ) {
+ const dom = $(`th[data-name=${_.name}]`)
+ let t = dom.html()
+ dom.html('*' + t)
+ }
+ })
+ }
+})
$(function () {
document.addEventListener('click', function () {
@@ -160,45 +183,13 @@ $(function () {
}, 500)
}
- function setRequired(dom = {label: [], table: []}) {
- let domTimer = null
- let timer_count = 0
- clearInterval(domTimer)
- domTimer = setInterval(() => {
- timer_count++
- const lint = $('.o_form_view_container')
- if (lint.length) {
- clearInterval(domTimer)
- const { table} = dom
-
- if (table.length) {
- table.forEach(_ => {
- const th = $(`th[data-name=${_}]`)
- const t = th.find('span').eq(0).text().replace('*','')
- th.find('span').eq(0).html('*' + t)
-
- })
-
- }
- }
- if (timer_count == 20) {
- clearInterval(domTimer)
- }
- }, 500)
- }
-
var currentUrl = location.href
- const customRequiredDom = {
- table: ['product_template_id', 'product_uom_qty', 'price_unit','product_id','product_qty', 'name', 'fault_type', 'maintenance_standards', 'Period']
- }
const listenerUrl = setInterval(() => {
const isChange = currentUrl != location.href
if (isChange) {
currentUrl = location.href
customRequired()
- setRequired(customRequiredDom)
}
}, 500)
customRequired()
- setRequired(customRequiredDom)
})
diff --git a/jikimo_frontend/static/src/scss/custom_style.scss b/jikimo_frontend/static/src/scss/custom_style.scss
index bc1be730..f7195534 100644
--- a/jikimo_frontend/static/src/scss/custom_style.scss
+++ b/jikimo_frontend/static/src/scss/custom_style.scss
@@ -467,3 +467,15 @@ div:has(.o_required_modifier) > label::before {
background: #71639e;
color: #fff
}
+
+// 修改时间输入框宽度
+.o_datepicker_input.o_input.datetimepicker-input {
+ width: 200px;
+}
+
+
+.o_form_view .o_form_editable .o_row > .o_field_widget, .o_form_view .o_form_editable .o_row > .o_field_widget.o_field_float_time {
+ width: auto !important;
+ flex: unset;
+}
+
diff --git a/sf_base/static/src/scss/test.scss b/sf_base/static/src/scss/test.scss
index fdc5821e..c91a8a77 100644
--- a/sf_base/static/src/scss/test.scss
+++ b/sf_base/static/src/scss/test.scss
@@ -189,3 +189,6 @@ td.o_required_modifier {
flex-direction: row !important;
}
+.supplier_ids_set_css thead th[data-name=partner_id]{
+ width: 500px!important;
+}
\ No newline at end of file
diff --git a/sf_base/views/common_view.xml b/sf_base/views/common_view.xml
index 0826b51c..e829274a 100644
--- a/sf_base/views/common_view.xml
+++ b/sf_base/views/common_view.xml
@@ -269,7 +269,7 @@
-
+
From 34ea140941e19fd84eaa4fcf7f6bf871f9973cf9 Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Tue, 9 Apr 2024 10:46:08 +0800
Subject: [PATCH 15/19] =?UTF-8?q?1=E3=80=81=E6=96=B0=E5=A2=9E=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD=E5=88=80=E5=85=B7=E6=B8=85=E5=8D=95=E6=A8=A1=E5=9E=8B?=
=?UTF-8?q?=EF=BC=8C=E5=8F=8A=E5=85=B6tree=E8=A7=86=E5=9B=BE=E3=80=81?=
=?UTF-8?q?=E6=9D=83=E9=99=90=EF=BC=9B2=E3=80=81=E5=8A=9F=E8=83=BD?=
=?UTF-8?q?=E5=88=80=E5=85=B7=E5=AE=89=E5=85=A8=E5=BA=93=E5=AD=98=E6=A8=A1?=
=?UTF-8?q?=E5=9E=8B=E5=92=8C=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7=E7=BB=84?=
=?UTF-8?q?=E8=A3=85=E5=8D=95=E6=A8=A1=E5=9E=8B=E6=96=B0=E5=A2=9E=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD=E5=88=80=E5=85=B7=E5=90=8D=E7=A7=B0=E5=85=B3=E8=81=94?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7=E6=B8=85=E5=8D=95=EF=BC=8C?=
=?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8A=9F=E8=83=BD=E5=88=80=E5=85=B7=E7=BB=84?=
=?UTF-8?q?=E8=A3=85=E6=B5=81=E7=A8=8B=E7=94=9F=E6=88=90=E5=8A=9F=E8=83=BD?=
=?UTF-8?q?=E5=88=80=E5=85=B7=E5=AE=89=E5=85=A8=E5=BA=93=E5=AD=98=E4=BF=A1?=
=?UTF-8?q?=E6=81=AF=E7=9A=84=E6=B5=81=E7=A8=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_base/models/tool_base_new.py | 20 ++++++
sf_base/security/ir.model.access.csv | 9 ++-
sf_base/views/tool_menu.xml | 10 +--
sf_base/views/tool_views.xml | 65 +++++++++++++++++++-
sf_tool_management/models/base.py | 12 ++--
sf_tool_management/views/tool_base_views.xml | 7 ++-
sf_tool_management/wizard/wizard.py | 15 +++--
sf_tool_management/wizard/wizard_view.xml | 3 +-
8 files changed, 117 insertions(+), 24 deletions(-)
diff --git a/sf_base/models/tool_base_new.py b/sf_base/models/tool_base_new.py
index a3a9e172..e3b737f0 100644
--- a/sf_base/models/tool_base_new.py
+++ b/sf_base/models/tool_base_new.py
@@ -308,3 +308,23 @@ class ToolGroups(models.Model):
# records = super(ToolGroups, self).create(vals_list)
# self._register_tool_groups(records)
# return records
+
+
+class ToolInventory(models.Model):
+ _name = 'sf.tool.inventory'
+ _description = '功能刀具清单'
+
+ name = fields.Char('功能刀具名称', required=True)
+ type = fields.Char('类型')
+ prefix = fields.Char('前缀')
+ postfix = fields.Char('后缀')
+ diameter = fields.Float('直径(mm)')
+ angle = fields.Float('R角(mm)')
+ tool_length = fields.Float('刀具总长(mm)')
+ blade_length = fields.Float('避空长/刃长(mm)')
+ knife_head_name = fields.Char('刀头名称')
+ cutter_number = fields.Char('刀号')
+ blade_number = fields.Integer('刃数(个)')
+ extension = fields.Float('伸出长度(mm)')
+
+ active = fields.Boolean('已归档', default=True)
diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv
index 2a3cd471..9d027bdb 100644
--- a/sf_base/security/ir.model.access.csv
+++ b/sf_base/security/ir.model.access.csv
@@ -192,4 +192,11 @@ access_sf_machine_brand_tags_group_purchase_director,sf_machine_brand_tags_group
access_printer,printer,model_printer,base.group_user,1,1,1,1
-access_printer_configuration,printer.configuration,model_printer_configuration,base.group_user,1,1,1,1
\ No newline at end of file
+access_printer_configuration,printer.configuration,model_printer_configuration,base.group_user,1,1,1,1
+
+access_group_sf_mrp_user,sf_tool_inventory,model_sf_tool_inventory,base.group_user,1,1,1,0
+access_group_sf_mrp_user_admin,sf_tool_inventory_admin,model_sf_tool_inventory,base.group_system,1,1,1,0
+access_group_sf_mrp_user_group_purchase_director,sf_tool_inventory_group_purchase_director,model_sf_tool_inventory,sf_base.group_purchase_director,1,0,1,0
+access_group_sf_mrp_user_group_sale_director,sf_tool_inventory_group_sale_director,model_sf_tool_inventory,sf_base.group_sale_director,1,0,1,0
+access_sf_cutting_tool_material_group_plan_director,sf_tool_inventory_group_plan_director,model_sf_tool_inventory,sf_base.group_plan_director,1,0,1,0
+access_group_sf_mrp_user_group_sf_mrp_user,sf_tool_inventory_group_sf_mrp_user,model_sf_tool_inventory,sf_base.group_sf_mrp_user,1,1,0,0
\ No newline at end of file
diff --git a/sf_base/views/tool_menu.xml b/sf_base/views/tool_menu.xml
index 506a73df..bad606d6 100644
--- a/sf_base/views/tool_menu.xml
+++ b/sf_base/views/tool_menu.xml
@@ -59,14 +59,14 @@
id="menu_sf_cutting_tool_type"
parent="menu_sf_cutting_tool"
name="刀具类型"
- sequence="2"
+ sequence="10"
action="action_sf_cutting_tool_type"
/>
@@ -82,7 +82,7 @@
id="menu_sf_functional_cutting_tool_model_type"
parent="menu_sf_cutting_tool"
name="功能刀具类型"
- sequence="4"
+ sequence="30"
action="action_sf_functional_cutting_tool_model_type"
/>
@@ -91,14 +91,14 @@
name="能力特征库"
parent="menu_sf_cutting_tool"
action="action_maintenance_equipment_image"
- sequence="5"/>
+ sequence="40"/>
+ sequence="50"/>
diff --git a/sf_base/views/tool_views.xml b/sf_base/views/tool_views.xml
index 34b87a41..25d1824f 100644
--- a/sf_base/views/tool_views.xml
+++ b/sf_base/views/tool_views.xml
@@ -123,7 +123,7 @@