256 lines
11 KiB
Python
256 lines
11 KiB
Python
import logging
|
|
|
|
from datetime import timedelta, datetime, date
|
|
|
|
from odoo import api, fields, models, _
|
|
from odoo.exceptions import ValidationError
|
|
|
|
|
|
class ShelfLocation(models.Model):
|
|
_inherit = 'sf.shelf.location'
|
|
|
|
tool_rfid = fields.Char('Rfid', compute='_compute_tool', store=True)
|
|
tool_name_id = fields.Many2one('sf.functional.cutting.tool.entity', string='功能刀具名称', compute='_compute_tool',
|
|
store=True)
|
|
|
|
@api.depends('product_id')
|
|
def _compute_tool(self):
|
|
for item in self:
|
|
if item.product_id:
|
|
if item.product_id.categ_id.name == '功能刀具':
|
|
tool_id = self.env['sf.functional.cutting.tool.entity'].sudo().search(
|
|
[('barcode_id', '=', item.product_sn_id.id)])
|
|
if tool_id:
|
|
item.tool_rfid = tool_id.rfid
|
|
item.tool_name_id = tool_id.id
|
|
continue
|
|
item.tool_rfid = ''
|
|
item.tool_name_id = False
|
|
|
|
|
|
class StockMoveLine(models.Model):
|
|
_inherit = 'stock.move.line'
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
records = super(StockMoveLine, self).create(vals_list)
|
|
move_lines = records.filtered(lambda a: a.product_id.categ_id.name == '功能刀具' and a.state == 'done')
|
|
if move_lines: # 校验是否为功能刀具移动历史
|
|
self.button_function_tool_use_verify(move_lines)
|
|
return records
|
|
|
|
def button_function_tool_use_verify(self, move_lines):
|
|
"""
|
|
对所有从【刀具房】到【制造前】的功能刀具进行校验(校验是否为制造订单所缺的刀)
|
|
"""
|
|
location_id = self.env['stock.location'].search([('name', '=', '刀具房')])
|
|
location_dest_id = self.env['stock.location'].search([('name', '=', '制造前')])
|
|
line_ids = move_lines.filtered(
|
|
lambda a: a.location_id == location_id and a.location_dest_id == location_dest_id)
|
|
for line_id in line_ids:
|
|
if line_id.lot_id:
|
|
self.env['sf.functional.cutting.tool.entity'].sudo().search(
|
|
[('barcode_id', '=', line_id.lot_id.id),
|
|
('functional_tool_status', '=', '正常')]).cnc_function_tool_use_verify()
|
|
|
|
|
|
class StockPicking(models.Model):
|
|
_inherit = 'stock.picking'
|
|
|
|
def button_validate(self):
|
|
res = super().button_validate()
|
|
move_lines = self.move_line_ids.filtered(lambda a: a.product_id.categ_id.name == '功能刀具')
|
|
if move_lines:
|
|
self.env['stock.move.line'].sudo().button_function_tool_use_verify(move_lines)
|
|
return res
|
|
|
|
def create_tool_stocking_picking(self, stock_lot, obj):
|
|
"""
|
|
创建功能刀具组装入库单
|
|
"""
|
|
# 获取名称为刀具组装入库的作业类型
|
|
picking_type_id = self.env['stock.picking.type'].sudo().search([('name', '=', '刀具组装入库')])
|
|
# 创建刀具组装入库单
|
|
picking_id = self.env['stock.picking'].create({
|
|
'name': self._get_name_stock(picking_type_id),
|
|
'picking_type_id': picking_type_id.id,
|
|
'location_id': picking_type_id.default_location_src_id.id,
|
|
'location_dest_id': picking_type_id.default_location_dest_id.id,
|
|
'origin': obj.assembly_order_code
|
|
})
|
|
# 创建作业详情对象记录,并绑定到刀具组装入库单
|
|
self.env['stock.move.line'].create({
|
|
'picking_id': picking_id.id,
|
|
'product_id': stock_lot.product_id.id,
|
|
'location_id': picking_id.location_id.id,
|
|
'location_dest_id': picking_id.location_dest_id.id,
|
|
'lot_id': stock_lot.id,
|
|
'install_tool_time': fields.Datetime.now(),
|
|
'qty_done': 1,
|
|
'functional_tool_name_id': obj.id,
|
|
'functional_tool_type_id': obj.functional_tool_type_id.id,
|
|
'diameter': obj.after_assembly_functional_tool_diameter,
|
|
'knife_tip_r_angle': obj.after_assembly_knife_tip_r_angle,
|
|
'code': obj.code,
|
|
'rfid': obj.rfid,
|
|
'functional_tool_name': obj.after_assembly_functional_tool_name,
|
|
'tool_groups_id': obj.tool_groups_id.id
|
|
})
|
|
# 将刀具组装入库单的状态更改为就绪
|
|
picking_id.action_confirm()
|
|
picking_id.button_validate()
|
|
|
|
def _get_name_stock(self, picking_type_id):
|
|
name = picking_type_id.sequence_id.prefix + str(
|
|
datetime.strptime(str(fields.Date.today()), "%Y-%m-%d").strftime("%Y%m%d"))
|
|
stock_id = self.env['stock.picking'].sudo().search(
|
|
[('name', 'like', name), ('picking_type_id', '=', picking_type_id.id)],
|
|
limit=1,
|
|
order="id desc"
|
|
)
|
|
if not stock_id:
|
|
num = "%03d" % 1
|
|
else:
|
|
m = int(stock_id.name[-3:]) + 1
|
|
num = "%03d" % m
|
|
return name + str(num)
|
|
|
|
def create_tool_stocking_picking1(self, obj):
|
|
"""
|
|
创建刀具物料出库单
|
|
"""
|
|
# 获取名称为内部调拨的作业类型
|
|
picking_type_id = self.env['stock.picking.type'].sudo().search([('name', '=', '内部调拨')])
|
|
# 创建刀具物料出库单
|
|
picking_id = self.env['stock.picking'].create({
|
|
'name': self._get_name_stock1(picking_type_id),
|
|
'picking_type_id': picking_type_id.id,
|
|
'location_id': self.env['stock.location'].search([('name', '=', '刀具房')]).id,
|
|
'location_dest_id': self.env['stock.location'].search([('name', '=', '刀具组装位置')]).id,
|
|
'origin': obj.assembly_order_code
|
|
})
|
|
# =============刀具物料出库===================
|
|
stock_move_id = self.env['stock.move']
|
|
datas = {'data': [], 'picking_id': picking_id}
|
|
if obj.handle_code_id:
|
|
# 修改刀柄序列号状态为【在用】
|
|
obj.handle_code_id.sudo().write({'tool_material_status': '在用'})
|
|
datas['data'].append(
|
|
{'current_location_id': self.env['sf.shelf.location'], 'lot_id': obj.handle_code_id})
|
|
if obj.integral_product_id:
|
|
datas['data'].append(
|
|
{'current_location_id': obj.integral_freight_barcode_id, 'lot_id': obj.integral_freight_lot_id.lot_id})
|
|
if obj.blade_product_id:
|
|
datas['data'].append(
|
|
{'current_location_id': obj.blade_freight_barcode_id, 'lot_id': obj.blade_freight_lot_id.lot_id})
|
|
if obj.bar_product_id:
|
|
datas['data'].append(
|
|
{'current_location_id': obj.bar_freight_barcode_id, 'lot_id': obj.bar_freight_lot_id.lot_id})
|
|
if obj.pad_product_id:
|
|
datas['data'].append(
|
|
{'current_location_id': obj.pad_freight_barcode_id, 'lot_id': obj.pad_freight_lot_id.lot_id})
|
|
if obj.chuck_product_id:
|
|
datas['data'].append(
|
|
{'current_location_id': obj.chuck_freight_barcode_id, 'lot_id': obj.chuck_freight_lot_id.lot_id})
|
|
# 创建刀具物料出库库存移动记录
|
|
stock_move_id.create_tool_material_stock_moves(datas)
|
|
# 将刀具物料出库库单的状态更改为就绪
|
|
picking_id.action_confirm()
|
|
# 修改刀具物料出库移动历史记录
|
|
stock_move_id.write_tool_material_stock_move_lines(datas)
|
|
# 设置数量,并验证完成
|
|
picking_id.action_set_quantities_to_reservation()
|
|
picking_id.button_validate()
|
|
logging.info(f'刀具物料调拨单状态:{picking_id.state}')
|
|
|
|
def _get_name_stock1(self, picking_type_id):
|
|
name = f'{picking_type_id.sequence_id.prefix}DJ/{date.today().strftime("%y")}'
|
|
stock_id = self.env['stock.picking'].sudo().search(
|
|
[('name', 'like', name), ('picking_type_id', '=', picking_type_id.id)],
|
|
limit=1,
|
|
order="id desc"
|
|
)
|
|
if not stock_id:
|
|
num = "%05d" % 1
|
|
else:
|
|
m = int(stock_id.name[-5:]) + 1
|
|
num = "%05d" % m
|
|
return name + str(num)
|
|
|
|
|
|
class StockMove(models.Model):
|
|
_inherit = 'stock.move'
|
|
|
|
def create_tool_material_stock_moves(self, datas):
|
|
picking_id = datas['picking_id']
|
|
data = datas['data']
|
|
stock_move_ids = []
|
|
for res in data:
|
|
if res:
|
|
# 创建库存移动记录
|
|
stock_move_id = self.env['stock.move'].sudo().create({
|
|
'name': picking_id.name,
|
|
'picking_id': picking_id.id,
|
|
'product_id': res['lot_id'].product_id.id,
|
|
'location_id': picking_id.location_id.id,
|
|
'location_dest_id': picking_id.location_dest_id.id,
|
|
'product_uom_qty': 1.00,
|
|
'reserved_availability': 1.00
|
|
})
|
|
stock_move_ids.append(stock_move_id)
|
|
return stock_move_ids
|
|
|
|
def write_tool_material_stock_move_lines(self, datas):
|
|
picking_id = datas['picking_id']
|
|
data = datas['data']
|
|
move_line_ids = picking_id.move_line_ids
|
|
for move_line_id in move_line_ids:
|
|
for res in data:
|
|
if move_line_id.lot_id.product_id == res['lot_id'].product_id:
|
|
move_line_id.write({
|
|
'current_location_id': res.get('current_location_id').id,
|
|
'lot_id': res.get('lot_id').id
|
|
})
|
|
return True
|
|
|
|
|
|
class ProductProduct(models.Model):
|
|
_inherit = 'product.product'
|
|
|
|
def create_assemble_warehouse_receipt(self, obj):
|
|
"""
|
|
创建功能刀具批次/序列号记录
|
|
"""
|
|
product_id = self.env['product.product'].search([('categ_type', '=', '功能刀具'), ('tracking', '=', 'serial')])
|
|
if not product_id:
|
|
logging.info('没有搜索到功能刀具产品:%s' % product_id)
|
|
raise ValidationError('没有找到按唯一序列号追溯的功能刀具产品信息!')
|
|
stock_lot = self.env['stock.lot'].create({
|
|
'name': self.get_stock_lot_name(obj),
|
|
'product_id': product_id[0].id,
|
|
'company_id': self.env.company.id
|
|
})
|
|
return stock_lot
|
|
|
|
def get_stock_lot_name(self, obj):
|
|
"""
|
|
生成功能刀具序列号
|
|
"""
|
|
company = obj.cutting_tool_cutterhandle_model_id.code.split('-', 1)[0]
|
|
new_time = datetime.strptime(str(fields.Date.today()), "%Y-%m-%d").strftime("%Y%m%d")
|
|
code = '%s-GNDJ-%s-%s' % (company, obj.after_assembly_functional_tool_type_id.code, new_time)
|
|
stock_lot_id = self.env['stock.lot'].sudo().search(
|
|
[('name', 'like', code)], limit=1, order="id desc")
|
|
if not stock_lot_id:
|
|
num = "%03d" % 1
|
|
else:
|
|
m = int(stock_lot_id.name[-3:]) + 1
|
|
num = "%03d" % m
|
|
return '%s-%s' % (code, num)
|
|
|
|
|
|
class SfShelfLocationLot(models.Model):
|
|
_inherit = 'sf.shelf.location.lot'
|
|
|
|
|