Merge branch 'feature/功能刀具安全库存注册' into feature/刀柄入库录入Rfid

This commit is contained in:
yuxianghui
2024-04-01 16:56:56 +08:00
9 changed files with 171 additions and 103 deletions

View File

@@ -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

View File

@@ -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."""

View File

@@ -422,7 +422,8 @@
<div name="product_specification_id" class="mt-1">
规格:
<field name="specification_id"></field>
<field name="specification_id"/>
<field name="specification_fixture_id"/>
</div>
<t t-if="record.default_code.value">[<field name="default_code"/>]
</t>

View File

@@ -13,6 +13,12 @@
<button string="打印二维码" name="print_single_method" type="object" class="btn-primary"/>
</header>
</xpath>
<xpath expr="//field[@name='product_id']" position="before">
<field name="rfid"/>
</xpath>
<xpath expr="//field[@name='product_id']" position="after">
<field name="product_specification"/>
</xpath>
</field>
</record>
</odoo>

View File

@@ -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'],

View File

@@ -1056,7 +1056,7 @@
<group>
<group>
<field name="barcode_id" invisible="True"/>
<field name="rfid" string="功能刀具rfid" readonly="false"/>
<field name="rfid" string="功能刀具rfid"/>
<field name="code"/>
<field name="after_assembly_functional_tool_name"
string="功能刀具名称"/>

View File

@@ -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):
"""
功能刀具组装

View File

@@ -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 == '刀柄':
for item in move.move_line_nosuggest_ids:
if item.location_dest_id.name == '进货':
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):
# 首先执行原有逻辑

View File

@@ -31,15 +31,16 @@
<field name="current_location_id" force_save="1"/>
</xpath>
<xpath expr="//field[@name='location_dest_id']" position="after">
<field name="destination_location_id" />
<!-- <field name="location_dest_id_product_type"/> -->
<!-- <field name="location_dest_id"/> -->
<field name="destination_location_id"/>
<!-- <field name="location_dest_id_product_type"/> -->
<!-- <field name="location_dest_id"/> -->
<field name="location_dest_id_value" invisible="1"/>
<!-- <button name="button_test" string="测试" type="object" class="oe_highlight"/> -->
<!-- <button name="button_test" string="测试" type="object" class="oe_highlight"/> -->
</xpath>
</field>
</record>
<record id="sf_stock_move_line_form" model="ir.ui.view">
<field name="name">sf.stock.move.line.form</field>
<field name="model">stock.move.line</field>
@@ -63,6 +64,9 @@
<field name="model">stock.move.line</field>
<field name="inherit_id" ref="stock.view_stock_move_line_operation_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='lot_name']" position="after">
<field name="rfid"/>
</xpath>
<xpath expr="//field[@name='product_uom_id']" position="after">
<field name="lot_qr_code" widget="image"/>
<button name="print_single_method" string="打印编码" type="object" class="oe_highlight"/>
@@ -103,10 +107,10 @@
groups="sf_warehouse.group_sf_stock_user" data-hotkey="k"/>
</xpath>
<!-- <xpath expr="//form//sheet//notebook//page//field[@name='move_ids_without_package']" position="before"> -->
<!-- <field name="check_in" invisible="True"/> -->
<!-- <button name="print_all_barcode" string="打印所有编码" type="object" attrs="{'invisible': [('check_in', '!=', 'IN')]}"/> -->
<!-- </xpath> -->
<!-- <xpath expr="//form//sheet//notebook//page//field[@name='move_ids_without_package']" position="before"> -->
<!-- <field name="check_in" invisible="True"/> -->
<!-- <button name="print_all_barcode" string="打印所有编码" type="object" attrs="{'invisible': [('check_in', '!=', 'IN')]}"/> -->
<!-- </xpath> -->
</field>
</record>
@@ -145,11 +149,23 @@
<field name="model">stock.move</field>
<field name="inherit_id" ref="stock.view_stock_move_operations"/>
<field name="arch" type="xml">
<!-- <xpath expr="//form//field[@name='move_line_ids']" position="before"> -->
<!-- <button name="print_all_barcode" type="object" string="打印所有编码"/> -->
<!-- </xpath> -->
<!-- <xpath expr="//form//field[@name='move_line_ids']" position="before"> -->
<!-- <button name="print_all_barcode" type="object" string="打印所有编码"/> -->
<!-- </xpath> -->
<xpath expr="//form//field[@name='product_id']" position="before">
<button name="print_all_barcode" type="object" string="打印所有编码" class="oe_highlight"/> -->
<button name="print_all_barcode" type="object" string="打印所有编码" class="oe_highlight"/>
-->
</xpath>
</field>
</record>
<record id="mrp_subcontracting_view_stock_move_barcode_scanned" model="ir.ui.view">
<field name="name">mrp.subcontracting.stock.move.barcode.scanned.form</field>
<field name="model">stock.move</field>
<field name="inherit_id" ref="stock.view_stock_move_nosuggest_operations"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='move_line_nosuggest_ids']" position="before">
<field name="_barcode_scanned" widget="barcode_handler"/>
</xpath>
</field>
</record>