Compare commits

...

7 Commits

Author SHA1 Message Date
yuxianghui
60560fe195 1、优化工单解绑Rfid 2024-06-19 17:40:49 +08:00
yuxianghui
21f2a704db 1、对刀仪接口获取的功能刀具半径值乘二后再赋值 2024-06-19 17:03:44 +08:00
yuxianghui
c0b673bfd0 添加注释 2024-06-19 11:23:25 +08:00
yuxianghui
6dae144d76 1、功能刀具拆解单优化;2、完成 需求坯料序列号生成规则优化2; 2024-06-19 11:19:47 +08:00
yuxianghui
4497fb04c1 1、优化 托盘绑定工单逻辑优化 ;2 完成 整体式刀具批次/序列号生成的优化需求; 3、完成 坯料序列号生成规则优化需求1。 2024-06-18 17:19:41 +08:00
马广威
903fdee420 Accept Merge Request #1081: (release/release1.6 -> master)
Merge Request: 功能升级

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1081?initial=true
2024-06-17 21:34:41 +08:00
马广威
519c534a89 Accept Merge Request #1071: (release/release_1.5 -> master)
Merge Request: 添加刀具物料整个生命周期按批次管理

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1071?initial=true
2024-06-13 10:49:36 +08:00
11 changed files with 85 additions and 36 deletions

View File

@@ -25,6 +25,9 @@
<filter string="人工编程" name="manual_quotation" domain="[('manual_quotation', '=', True)]"/>
<filter string="自动编程" name="no_manual_quotation" domain="[('manual_quotation', '=', False)]"/>
</xpath>
<xpath expr="//field[@name='production_id']" position="before">
<field name="product_tmpl_name"/>
</xpath>
</field>
</record>
</odoo>

View File

@@ -21,6 +21,8 @@ class ResMrpWorkOrder(models.Model):
_inherit = 'mrp.workorder'
_order = 'sequence asc,create_date desc'
product_tmpl_name = fields.Char('坯料产品名称', related='production_bom_id.bom_line_ids.product_id.name')
product_tmpl_id_length = fields.Float(related='production_id.product_tmpl_id.length', readonly=True, store=True,
string="坯料长度(mm)")
product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True,
@@ -849,12 +851,12 @@ class ResMrpWorkOrder(models.Model):
limit=1, order='id asc')
if not cnc_workorder.cnc_ids:
raise UserError(_('该制造订单还未下发CNC程序请稍后再试'))
else:
for item in cnc_workorder.cnc_ids:
functional_cutting_tool = self.env['sf.functional.cutting.tool.entity'].search(
[('tool_name_id.name', '=', item.cutting_tool_name)])
if not functional_cutting_tool:
raise UserError(_('该制造订单的CNC程序为%s没有对应的功能刀具' % item.cutting_tool_name))
# else:
# for item in cnc_workorder.cnc_ids:
# functional_cutting_tool = self.env['sf.functional.cutting.tool.entity'].search(
# [('tool_name_id.name', '=', item.cutting_tool_name)])
# if not functional_cutting_tool:
# raise UserError(_('该制造订单的CNC程序为%s没有对应的功能刀具' % item.cutting_tool_name))
if self.routing_type == '解除装夹':
'''
记录开始时间
@@ -1009,10 +1011,15 @@ class ResMrpWorkOrder(models.Model):
for workorder in record.production_id.workorder_ids:
if workorder.state != 'done':
is_production_id = False
if is_production_id is True and record.routing_type in ['解除装夹', '表面工艺']:
if record.routing_type == '解除装夹':
for workorder in record.production_id.workorder_ids:
workorder.rfid_code_old = workorder.rfid_code
workorder.rfid_code = None
if workorder.processing_panel == record.processing_panel:
rfid_code = workorder.rfid_code
workorder.write({'rfid_code_old': rfid_code,
'rfid_code': ''})
workorder.rfid_code_old = rfid_code
workorder.rfid_code = ''
if is_production_id is True and record.routing_type in ['解除装夹', '表面工艺']:
for move_raw_id in record.production_id.move_raw_ids:
move_raw_id.quantity_done = move_raw_id.product_uom_qty
record.process_state = '已完工'
@@ -1254,11 +1261,12 @@ class SfWorkOrderBarcodes(models.Model):
workorder.write(val)
self.write(val)
workorder_rfid = self.env['mrp.workorder'].search(
[('production_id', '=', workorder.production_id.id)])
[('production_id', '=', workorder.production_id.id),
('processing_panel', '=', workorder.processing_panel)])
if workorder_rfid:
for item in workorder_rfid:
item.write({'rfid_code': barcode})
logging.info("Rfid绑定成功")
logging.info("Rfid[%s]绑定成功!!!" % barcode)
else:
raise UserError('该Rfid【%s】绑定的是【%s】, 不是托盘!!!' % (barcode, lot.product_id.name))
self.process_state = '待检测'

View File

@@ -701,13 +701,36 @@ class ReStockMove(models.Model):
),
}
def put_move_line(self):
"""
确认订单时,自动分配序列号
"""
if self.product_id.tracking == "serial":
if self.product_id.categ_id.name == '刀具':
self.next_serial = self._get_tool_next_serial(self.company_id, self.product_id, self.origin)
else:
self.next_serial = self.env['stock.lot']._get_next_serial(self.company_id, self.product_id)
self._generate_serial_numbers()
for item in self.move_line_nosuggest_ids:
if item.lot_name:
lot_name = item.lot_name
if item.product_id.categ_id.name == '坯料':
lot_name = lot_name.split('[', 1)[0]
item.lot_qr_code = self.compute_lot_qr_code(lot_name)
def _put_tool_lot(self, company, product, origin):
if product.tracking == "lot" and self.product_id.categ_id.name == '刀具':
if not self.move_line_nosuggest_ids:
lot_names = self.env['stock.lot'].generate_lot_names(
'%s-%s-%s' % ('%s-T-DJWL-%s' % (
product.cutting_tool_model_id.code.split('-')[0], product.cutting_tool_material_id.code),
datetime.now().strftime("%Y%m%d"), origin), 1)
lot_code = '%s-%s-%s' % ('%s-T-DJWL-%s' % (
product.cutting_tool_model_id.code.split('-')[0], product.cutting_tool_material_id.code),
datetime.now().strftime("%Y%m%d"), origin)
move_line_ids = self.env['stock.move.line'].sudo().search([('lot_name', 'like', lot_code)], limit=1,
order='id desc')
if not move_line_ids:
lot_code = '%s-001' % lot_code
else:
lot_code = '%s-%03d' % (lot_code, int(move_line_ids.lot_name[-3:]) + 1)
lot_names = self.env['stock.lot'].generate_lot_names(lot_code, 1)
move_lines_commands = self._generate_serial_move_line_commands_tool_lot(lot_names)
self.write({'move_line_nosuggest_ids': move_lines_commands})
for item in self.move_line_nosuggest_ids:

View File

@@ -19,6 +19,7 @@
</field>
<field name="state" position="after">
<field name="work_state" optional="hide"/>
<field name="product_tmpl_name" invisible="1"/>
</field>
<field name="product_id" position="after">
<field name="equipment_id" optional="hide"/>
@@ -214,7 +215,7 @@
attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/>
<field name="functional_fixture_type_id"
attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/>
<field name="rfid_code" cache="True"
<field name="rfid_code" force_save="1" readonly="1" cache="True"
attrs="{'invisible': [('rfid_code_old', '!=', False)]}"/>
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
</group>

View File

@@ -41,8 +41,8 @@
<field name="model">stock.lot</field>
<field name="inherit_id" ref="stock.view_production_lot_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='create_date']" position="after">
<field name="rfid" invisible="1"/>
<xpath expr="//field[@name='name']" position="after">
<field name="rfid"/>
</xpath>
</field>
</record>

View File

@@ -215,6 +215,17 @@ class RePurchaseOrder(models.Model):
if len(product_id) != len(line):
raise ValidationError('%s】已存在,请勿重复添加' % product[-1].name)
def button_confirm(self):
result = super(RePurchaseOrder, self).button_confirm()
for item in self:
# 确认订单时,自动分配序列号
if item.picking_ids:
for picking_id in item.picking_ids:
if picking_id.move_ids:
for move_id in picking_id.move_ids:
move_id.put_move_line()
return result
class ResPartnerToSale(models.Model):
_inherit = 'res.partner'

View File

@@ -121,7 +121,7 @@ class Manufacturing_Connect(http.Controller):
{'Succeed': False, 'ErrorCode': 201, 'code': data_list[0], 'Error': '没有找到正在组装的组装单!'})
tool_assembly.write({
'after_assembly_tool_loading_length': float(data_list[1] or "0"), # 高度(总长度)
'after_assembly_functional_tool_diameter': float(data_list[2] or "0"), # 直径
'after_assembly_functional_tool_diameter': float(data_list[2] or "0") * 2, # 直径
'after_assembly_knife_tip_r_angle': float(data_list[3] or "0") # R角
})
except Exception as e:

View File

@@ -926,7 +926,7 @@ class FunctionalToolDismantle(models.Model):
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')])
location_dest_scrap_ids = self.env['stock.location'].search([('name', 'in', ('Scrap', '报废'))])
if self.handle_rfid:
lot = self.env['stock.lot'].sudo().search([('rfid', '=', self.handle_rfid)])
if not lot:
@@ -934,30 +934,33 @@ class FunctionalToolDismantle(models.Model):
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, code,
lot.create_stock_quant(location, location_dest_scrap_ids[-1], functional_tool_assembly.id, code,
functional_tool_assembly, functional_tool_assembly.tool_groups_id)
lot.tool_material_status = '报废'
else:
# 刀柄不报废 入库到刀具房
lot.create_stock_quant(location, location_dest, functional_tool_assembly.id, code,
functional_tool_assembly, functional_tool_assembly.tool_groups_id)
lot.tool_material_status = '可用'
# ==============功能刀具[报废]拆解================
if self.dismantle_cause in ['寿命到期报废', '崩刀报废']:
# 除刀柄外物料报废 入库到Scrap
if self.integral_product_id:
self.integral_product_id.dismantle_stock_moves(False, self.integral_lot_id, location,
location_dest_scrap, code)
location_dest_scrap_ids[-1], code)
elif self.blade_product_id:
self.blade_product_id.dismantle_stock_moves(False, self.blade_lot_id, location, location_dest_scrap,
code)
self.blade_product_id.dismantle_stock_moves(False, self.blade_lot_id, location,
location_dest_scrap_ids[-1], code)
if self.bar_product_id:
self.bar_product_id.dismantle_stock_moves(False, self.bar_lot_id, location, location_dest_scrap,
code)
self.bar_product_id.dismantle_stock_moves(False, self.bar_lot_id, location,
location_dest_scrap_ids[-1], code)
elif self.pad_product_id:
self.pad_product_id.dismantle_stock_moves(False, self.pad_lot_id, location, location_dest_scrap,
code)
self.pad_product_id.dismantle_stock_moves(False, self.pad_lot_id, location,
location_dest_scrap_ids[-1], code)
if self.chuck_product_id:
self.chuck_product_id.dismantle_stock_moves(False, self.chuck_lot_id, location, location_dest_scrap,
code)
self.chuck_product_id.dismantle_stock_moves(False, self.chuck_lot_id, location,
location_dest_scrap_ids[-1], code)
# ===========功能刀具[磨削]拆解==============
# elif self.dismantle_cause in ['刀具需磨削']:
# location_dest = self.env['stock.location'].search([('name', '=', '磨削房')])

View File

@@ -142,9 +142,6 @@ class StockLot(models.Model):
record.tool_material_status = '报废'
else:
record.tool_material_status = '未入库'
if record.fixture_material_search_id:
# 注册夹具物料状态到cloud平台
record.enroll_fixture_material_stock()
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):

View File

@@ -854,10 +854,10 @@ class ProductProduct(models.Model):
'company_id': self.env.company.id
})
# 获取位置对象
location_inventory_id = self.env['stock.location'].search([('name', '=', 'Production')])
location_inventory_ids = self.env['stock.location'].search([('name', 'in', ('Production', '生产'))])
stock_location_id = self.env['stock.location'].search([('name', '=', '组装后')])
# 创建功能刀具该批次/序列号 库存移动和移动历史
stock_lot.create_stock_quant(location_inventory_id, stock_location_id, functional_tool_assembly.id,
stock_lot.create_stock_quant(location_inventory_ids[-1], stock_location_id, functional_tool_assembly.id,
obj.assembly_order_code, obj, obj.after_tool_groups_id)
return stock_lot

View File

@@ -1143,7 +1143,10 @@ class CustomStockMove(models.Model):
move_lines = self.move_line_ids # 获取当前 stock.move 对应的所有 stock.move.line 记录
for line in move_lines:
if line.lot_name: # 确保 lot_name 存在
qr_data = self.compute_lot_qr_code(line.lot_name)
lot_name = line.lot_name
if line.product_id.categ_id.name == '坯料':
lot_name = lot_name.split('[', 1)[0]
qr_data = self.compute_lot_qr_code(lot_name)
# 假设 stock.move.line 模型中有一个字段叫做 lot_qr_code 用于存储二维码数据
line.lot_qr_code = qr_data
return result