@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
import re
import logging
from datetime import timedelta
@@ -423,7 +425,8 @@ class FunctionalToolAssembly(models.Model):
def _compute_integral_product_id ( self ) :
for item in self :
if item . integral_freight_barcode :
location = self . env [ ' sf.shelf.location ' ] . sudo ( ) . search ( [ ( ' barcode ' , ' = ' , item . integral_freight_barcode ) ] )
location = self . env [ ' sf.shelf.location ' ] . sudo ( ) . search (
[ ( ' barcode ' , ' = ' , item . integral_freight_barcode ) ] )
if location :
item . integral_product_id = location . product_id . id
else :
@@ -442,7 +445,7 @@ class FunctionalToolAssembly(models.Model):
@api.depends ( ' blade_freight_barcode ' )
def _compute_blade_product_id ( self ) :
for item in self :
if item . integral _freight_barcode:
if item . blade _freight_barcode:
location = self . env [ ' sf.shelf.location ' ] . sudo ( ) . search ( [ ( ' barcode ' , ' = ' , item . blade_freight_barcode ) ] )
if location :
item . blade_product_id = location . product_id . id
@@ -462,7 +465,7 @@ class FunctionalToolAssembly(models.Model):
@api.depends ( ' bar_freight_barcode ' )
def _compute_bar_product_id ( self ) :
for item in self :
if item . integral _freight_barcode:
if item . bar _freight_barcode:
location = self . env [ ' sf.shelf.location ' ] . sudo ( ) . search ( [ ( ' barcode ' , ' = ' , item . bar_freight_barcode ) ] )
if location :
item . bar_product_id = location . product_id . id
@@ -482,7 +485,7 @@ class FunctionalToolAssembly(models.Model):
@api.depends ( ' pad_freight_barcode ' )
def _compute_pad_product_id ( self ) :
for item in self :
if item . integral _freight_barcode:
if item . pad _freight_barcode:
location = self . env [ ' sf.shelf.location ' ] . sudo ( ) . search ( [ ( ' barcode ' , ' = ' , item . pad_freight_barcode ) ] )
if location :
item . pad_product_id = location . product_id . id
@@ -523,7 +526,7 @@ class FunctionalToolAssembly(models.Model):
@api.depends ( ' chuck_freight_barcode ' )
def _compute_chuck_product_id ( self ) :
for item in self :
if item . integral _freight_barcode:
if item . chuck _freight_barcode:
location = self . env [ ' sf.shelf.location ' ] . sudo ( ) . search ( [ ( ' barcode ' , ' = ' , item . chuck_freight_barcode ) ] )
if location :
item . chuck_product_id = location . product_id . id
@@ -631,3 +634,285 @@ class FunctionalToolAssembly(models.Model):
code = self . _get_code ( obj . loading_task_source )
obj . assembly_order_code = code
return obj
class FunctionalToolDismantle ( models . Model ) :
_name = ' sf.functional.tool.dismantle '
_inherit = [ " barcodes.barcode_events_mixin " ]
_description = ' 功能刀具拆解 '
def on_barcode_scanned ( self , barcode ) :
"""
扫码
"""
# 对barcode进行校验是否为货位编码
if not re . match ( r ' ^[A-Za-z0-9]+-[A-Za-z0-9]+- \ d {3} - \ d {3} $ ' , barcode ) :
tool_id = self . env [ ' sf.functional.cutting.tool.entity ' ] . sudo ( ) . search (
[ ( ' rfid ' , ' = ' , barcode ) , ( ' functional_tool_status ' , ' != ' , ' 已拆除 ' ) ] )
if tool_id :
self . functional_tool_id = tool_id . id
else :
raise ValidationError ( ' Rfid为【 %s 】的功能刀具不存在,请重新扫描! ' % barcode )
else :
if self . dismantle_cause == ' 更换为其他刀具 ' :
location = self . env [ ' sf.shelf.location ' ] . sudo ( ) . search ( [ ( ' barcode ' , ' = ' , barcode ) ] )
if not location :
raise ValidationError ( ' 【 %s 】该货位不存在,请重新扫码! ' % barcode )
else :
if not location . product_id :
# 判断功能刀具存在哪些刀具物料需要录入库位
if self . chuck_product_id : # 夹头
if not self . chuck_freight_id :
self . chuck_freight_id = location . id
return True
if self . integral_product_id : # 整体式刀具
if not self . integral_freight_id :
self . integral_freight_id = location . id
return True
elif self . blade_product_id : # 刀片
if not self . blade_freight_id :
self . blade_freight_id = location . id
return True
if self . bar_product_id : # 刀杆
if not self . bar_freight_id :
self . bar_freight_id = location . id
return True
elif self . pad_product_id : # 刀盘
if not self . pad_freight_id :
self . pad_freight_id = location . id
return True
else :
# 判断货位存放的是那个刀具物料产品
if self . integral_product_id == location . product_id : # 整体式刀具
self . integral_freight_id = location . id
elif self . blade_product_id == location . product_id : # 刀片
self . blade_freight_id = location . id
elif self . bar_product_id == location . product_id : # 刀杆
self . bar_freight_id = location . id
elif self . pad_product_id == location . product_id : # 刀盘
self . pad_freight_id = location . id
elif self . chuck_product_id == location . product_id : # 夹头
self . chuck_freight_id = location . id
elif self . dismantle_cause in [ ' 寿命到期报废 ' , ' 崩刀报废 ' ] :
raise ValidationError ( ' 该功能刀具因为 %s 拆解,无需录入库位 ' % self . dismantle_cause )
else :
raise ValidationError ( ' 该功能刀具因为 %s 拆解,无需录入库位 ' % self . dismantle_cause )
name = fields . Char ( ' 名称 ' , related = ' functional_tool_id.name ' )
functional_tool_id = fields . Many2one ( ' sf.functional.cutting.tool.entity ' , ' 功能刀具 ' , required = True ,
domain = [ ( ' functional_tool_status ' , ' != ' , ' 已拆除 ' ) ] )
tool_type_id = fields . Many2one ( ' sf.functional.cutting.tool.model ' , string = ' 功能刀具类型 ' , store = True ,
compute = ' _compute_functional_tool_num ' )
tool_groups_id = fields . Many2one ( ' sf.tool.groups ' , ' 刀具组 ' , compute = ' _compute_functional_tool_num ' , store = True )
diameter = fields . Integer ( string = ' 刀具直径(mm) ' , compute = ' _compute_functional_tool_num ' , store = True )
knife_tip_r_angle = fields . Float ( string = ' 刀尖R角(mm) ' , compute = ' _compute_functional_tool_num ' , store = True )
rfid = fields . Char ( ' Rfid ' , compute = ' _compute_functional_tool_num ' , store = True )
rfid_dismantle = fields . Char ( ' Rfid(已拆解) ' , readonly = True )
dismantle_cause = fields . Selection (
[ ( ' 寿命到期报废 ' , ' 寿命到期报废 ' ) , ( ' 崩刀报废 ' , ' 崩刀报废 ' ) , ( ' 更换为其他刀具 ' , ' 更换为其他刀具 ' ) ,
( ' 刀具需磨削 ' , ' 刀具需磨削 ' ) ] , string = ' 拆解原因 ' , required = True )
dismantle_data = fields . Datetime ( ' 拆解日期 ' , readonly = True )
dismantle_person = fields . Char ( ' 拆解人 ' , readonly = True )
image = fields . Binary ( ' 图片 ' , readonly = True )
scrap_id = fields . Char ( ' 报废单号 ' , readonly = True )
grinding_id = fields . Char ( ' 磨削单号 ' , readonly = True )
state = fields . Selection ( [ ( ' 待拆解 ' , ' 待拆解 ' ) , ( ' 已拆解 ' , ' 已拆解 ' ) ] , default = ' 待拆解 ' )
active = fields . Boolean ( ' 有效 ' , default = True )
# 刀柄
handle_product_id = fields . Many2one ( ' product.product ' , string = ' 刀柄 ' , compute = ' _compute_functional_tool_num ' ,
store = True )
handle_type_id = fields . Many2one ( ' sf.cutting_tool.standard.library ' , string = ' 刀柄型号 ' ,
related = ' handle_product_id.cutting_tool_model_id ' )
handle_brand_id = fields . Many2one ( ' sf.machine.brand ' , string = ' 刀柄品牌 ' , related = ' handle_product_id.brand_id ' )
handle_rfid = fields . Char ( string = ' 刀柄Rfid ' , compute = ' _compute_functional_tool_num ' , store = True )
scrap_boolean = fields . Boolean ( string = ' 刀柄是否报废 ' , default = False )
# 整体式
integral_product_id = fields . Many2one ( ' product.product ' , string = ' 整体式刀具 ' ,
compute = ' _compute_functional_tool_num ' , store = True )
integral_type_id = fields . Many2one ( ' sf.cutting_tool.standard.library ' , string = ' 整体式刀具型号 ' ,
related = ' integral_product_id.cutting_tool_model_id ' )
integral_brand_id = fields . Many2one ( ' sf.machine.brand ' , string = ' 整体式刀具品牌 ' ,
related = ' integral_product_id.brand_id ' )
integral_freight_id = fields . Many2one ( ' sf.shelf.location ' , ' 整体式刀具目标货位 ' ,
domain = " [( ' product_id ' , ' in ' , (integral_product_id, False))] " )
# 刀片
blade_product_id = fields . Many2one ( ' product.product ' , string = ' 刀片 ' , compute = ' _compute_functional_tool_num ' ,
store = True )
blade_type_id = fields . Many2one ( ' sf.cutting_tool.standard.library ' , string = ' 刀片型号 ' ,
related = ' blade_product_id.cutting_tool_model_id ' )
blade_brand_id = fields . Many2one ( ' sf.machine.brand ' , string = ' 刀片品牌 ' , related = ' blade_product_id.brand_id ' )
blade_freight_id = fields . Many2one ( ' sf.shelf.location ' , ' 刀片目标货位 ' ,
domain = " [( ' product_id ' , ' in ' , (blade_product_id, False))] " )
# 刀杆
bar_product_id = fields . Many2one ( ' product.product ' , string = ' 刀杆 ' , compute = ' _compute_functional_tool_num ' ,
store = True )
bar_type_id = fields . Many2one ( ' sf.cutting_tool.standard.library ' , string = ' 刀杆型号 ' ,
related = ' bar_product_id.cutting_tool_model_id ' )
bar_brand_id = fields . Many2one ( ' sf.machine.brand ' , string = ' 刀杆品牌 ' , related = ' bar_product_id.brand_id ' )
bar_freight_id = fields . Many2one ( ' sf.shelf.location ' , ' 刀杆目标货位 ' ,
domain = " [( ' product_id ' , ' in ' , (bar_product_id, False))] " )
# 刀盘
pad_product_id = fields . Many2one ( ' product.product ' , string = ' 刀盘 ' , compute = ' _compute_functional_tool_num ' ,
store = True )
pad_type_id = fields . Many2one ( ' sf.cutting_tool.standard.library ' , string = ' 刀盘型号 ' ,
related = ' pad_product_id.cutting_tool_model_id ' )
pad_brand_id = fields . Many2one ( ' sf.machine.brand ' , string = ' 刀盘品牌 ' , related = ' pad_product_id.brand_id ' )
pad_freight_id = fields . Many2one ( ' sf.shelf.location ' , ' 刀盘目标货位 ' ,
domain = " [( ' product_id ' , ' in ' , (pad_product_id, False))] " )
# 夹头
chuck_product_id = fields . Many2one ( ' product.product ' , string = ' 夹头 ' , compute = ' _compute_functional_tool_num ' ,
store = True )
chuck_type_id = fields . Many2one ( ' sf.cutting_tool.standard.library ' , string = ' 夹头型号 ' ,
related = ' chuck_product_id.cutting_tool_model_id ' )
chuck_brand_id = fields . Many2one ( ' sf.machine.brand ' , string = ' 夹头品牌 ' , related = ' chuck_product_id.brand_id ' )
chuck_freight_id = fields . Many2one ( ' sf.shelf.location ' , ' 夹头目标货位 ' ,
domain = " [( ' product_id ' , ' in ' , (chuck_product_id, False))] " )
@api.depends ( ' functional_tool_id ' )
def _compute_functional_tool_num ( self ) :
for item in self :
if item . functional_tool_id :
item . tool_groups_id = item . functional_tool_id . tool_groups_id . id
item . tool_type_id = item . functional_tool_id . sf_cutting_tool_type_id . id
item . diameter = item . functional_tool_id . functional_tool_diameter
item . knife_tip_r_angle = item . functional_tool_id . knife_tip_r_angle
item . rfid = item . functional_tool_id . rfid
item . handle_rfid = item . functional_tool_id . rfid
item . handle_product_id = item . functional_tool_id . functional_tool_name_id . handle_product_id . id
item . integral_product_id = item . functional_tool_id . functional_tool_name_id . integral_product_id . id
item . blade_product_id = item . functional_tool_id . functional_tool_name_id . blade_product_id . id
item . bar_product_id = item . functional_tool_id . functional_tool_name_id . bar_product_id . id
item . pad_product_id = item . functional_tool_id . functional_tool_name_id . pad_product_id . id
item . chuck_product_id = item . functional_tool_id . functional_tool_name_id . chuck_product_id . id
else :
item . tool_groups_id = False
item . tool_type_id = False
item . diameter = 0
item . knife_tip_r_angle = 0
item . rfid = ' '
item . handle_rfid = ' '
item . handle_product_id = False
item . integral_product_id = False
item . blade_product_id = False
item . bar_product_id = False
item . pad_product_id = False
item . chuck_product_id = False
def confirmation_disassembly ( self ) :
logging . info ( ' %s 刀具确认开始拆解 ' % self . dismantle_cause )
if self . functional_tool_id . functional_tool_status == ' 已拆除 ' :
raise ValidationError ( ' Rfid为【 %s 】的功能刀具已经拆解,请勿重复操作! ' % self . functional_tool_id . rfid_dismantle )
location = self . env [ ' stock.location ' ] . search ( [ ( ' name ' , ' = ' , ' 刀具组装位置 ' ) ] )
location_dest = self . env [ ' stock.location ' ] . search ( [ ( ' name ' , ' = ' , ' 刀具房 ' ) ] )
# =================刀柄是否报废拆解=======
location_dest_scrap = self . env [ ' stock.location ' ] . search ( [ ( ' name ' , ' = ' , ' Scrap ' ) ] )
if self . handle_rfid :
lot = self . env [ ' stock.lot ' ] . sudo ( ) . search ( [ ( ' rfid ' , ' = ' , self . handle_rfid ) ] )
functional_tool_assembly = self . functional_tool_id . functional_tool_name_id
if self . scrap_boolean :
# 刀柄报废 入库到Scrap
lot . create_stock_quant ( location , location_dest_scrap , functional_tool_assembly . id , ' 功能刀具拆解 ' ,
functional_tool_assembly , functional_tool_assembly . tool_groups_id )
else :
# 刀柄不报废 入库到刀具房
lot . create_stock_quant ( location , location_dest , functional_tool_assembly . id , ' 功能刀具拆解 ' ,
functional_tool_assembly , functional_tool_assembly . tool_groups_id )
# ==============功能刀具报废拆解================
if self . dismantle_cause in [ ' 寿命到期报废 ' , ' 崩刀报废 ' ] :
# 除刀柄外物料报废 入库到Scrap
if self . integral_freight_id :
self . integral_product_id . dismantle_stock_moves ( False , location , location_dest_scrap )
elif self . blade_freight_id :
self . blade_product_id . dismantle_stock_moves ( False , location , location_dest_scrap )
if self . bar_freight_id :
self . bar_product_id . dismantle_stock_moves ( False , location , location_dest_scrap )
elif self . pad_freight_id :
self . pad_product_id . dismantle_stock_moves ( False , location , location_dest_scrap )
if self . chuck_freight_id :
self . chuck_product_id . dismantle_stock_moves ( False , location , location_dest_scrap )
# ===========功能刀具磨削拆解==============
elif self . dismantle_cause in [ ' 刀具需磨削 ' ] :
location_dest = self . env [ ' stock.location ' ] . search ( [ ( ' name ' , ' = ' , ' 磨削房 ' ) ] )
# 除刀柄外物料拆解 入库到具体库位
if self . integral_freight_id :
self . integral_product_id . dismantle_stock_moves ( False , location , location_dest )
elif self . blade_freight_id :
self . blade_product_id . dismantle_stock_moves ( False , location , location_dest )
if self . bar_freight_id :
self . bar_product_id . dismantle_stock_moves ( False , location , location_dest )
elif self . pad_freight_id :
self . pad_product_id . dismantle_stock_moves ( False , location , location_dest )
if self . chuck_freight_id :
self . chuck_product_id . dismantle_stock_moves ( False , location , location_dest )
# ==============功能刀具更换拆解==============
elif self . dismantle_cause in [ ' 更换为其他刀具 ' ] :
# 除刀柄外物料拆解 入库到具体库位
if self . integral_freight_id :
self . integral_product_id . dismantle_stock_moves ( self . integral_freight_id . barcode , location ,
location_dest )
elif self . blade_freight_id :
self . blade_product_id . dismantle_stock_moves ( self . blade_freight_id . barcode , location , location_dest )
if self . bar_freight_id :
self . bar_product_id . dismantle_stock_moves ( self . bar_freight_id . barcode , location , location_dest )
elif self . pad_freight_id :
self . pad_product_id . dismantle_stock_moves ( self . pad_freight_id . barcode , location , location_dest )
if self . chuck_freight_id :
self . chuck_product_id . dismantle_stock_moves ( self . chuck_freight_id . barcode , location , location_dest )
# ===============删除功能刀具的Rfid字段的值, 赋值给Rfid(已拆解)字段=====
self . functional_tool_id . write ( {
' rfid_dismantle ' : self . functional_tool_id . rfid ,
' rfid ' : ' ' ,
' functional_tool_status ' : ' 已拆除 '
} )
# 修改拆解单的值
self . write ( {
' rfid_dismantle ' : self . rfid ,
' dismantle_data ' : fields . Datetime . now ( ) ,
' dismantle_person ' : self . env . user . name ,
' rfid ' : ' ' ,
' state ' : ' 已拆解 '
} )
logging . info ( ' 刀具拆解成功! ' )
class ProductProduct ( models . Model ) :
_inherit = ' product.product '
def dismantle_stock_moves ( self , shelf_location_barcode , location_id , location_dest_id ) :
# 创建功能刀具拆解单产品库存移动记录
stock_move_id = self . env [ ' stock.move ' ] . sudo ( ) . create ( {
' name ' : ' 功能刀具拆解 ' ,
' product_id ' : self . id ,
' location_id ' : location_id . id ,
' location_dest_id ' : location_dest_id . id ,
' product_uom_qty ' : 1.00 ,
' state ' : ' done '
} )
if shelf_location_barcode :
location = self . env [ ' sf.shelf.location ' ] . sudo ( ) . search ( [ ( ' barcode ' , ' = ' , shelf_location_barcode ) ] )
location . product_num = location . product_num + 1
else :
location = False
# 创建移动历史记录
stock_move_line_id = self . env [ ' stock.move.line ' ] . sudo ( ) . create ( {
' product_id ' : self . id ,
' move_id ' : stock_move_id . id ,
' current_location_id ' : location . id or False ,
' install_tool_time ' : fields . Datetime . now ( ) ,
' qty_done ' : 1.0 ,
' state ' : ' done ' ,
} )
return stock_move_id , stock_move_line_id