Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造代码优化

# Conflicts:
#	sf_manufacturing/models/mrp_workorder.py
This commit is contained in:
mgw
2024-05-09 09:25:19 +08:00
36 changed files with 713 additions and 260 deletions

View File

@@ -180,6 +180,11 @@ class ResMrpWorkOrder(models.Model):
detection_report = fields.Binary('检测报告', readonly=True)
is_remanufacture = fields.Boolean(string='是否重新生成制造订单', default=True)
@api.onchange('rfid_code')
def _onchange(self):
if self.rfid_code and self.state == 'progress':
self.workpiece_delivery_ids[0].write({'rfid_code': self.rfid_code})
def get_plan_workorder(self, production_line):
tomorrow = (date.today() + timedelta(days=+1)).strftime("%Y-%m-%d")
tomorrow_start = tomorrow + ' 00:00:00'
@@ -422,19 +427,22 @@ class ResMrpWorkOrder(models.Model):
if not item.route_id:
raise UserError('【工件配送】明细中请选择【任务路线】')
else:
if item.is_cnc_program_down is True:
if item.status == '待下发':
return {
'name': _('确认'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'sf.workpiece.delivery.wizard',
'target': 'new',
'context': {
'default_workorder_id': self.id,
}}
if self.state == 'done':
if item.is_cnc_program_down is True:
if item.status == '待下发':
return {
'name': _('确认'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'sf.workpiece.delivery.wizard',
'target': 'new',
'context': {
'default_workorder_id': self.id,
}}
else:
raise UserError(_("该制造订单还未下发CNC程序单无法进行工件配送"))
else:
raise UserError(_("制造订单还未下发CNC程序单,无法进行工件配送"))
raise UserError(_("工单暂未完成,无法进行工件配送"))
# 拼接工单对象属性值
def json_workorder_str(self, k, production, route):
@@ -485,9 +493,8 @@ class ResMrpWorkOrder(models.Model):
def _json_workpiece_delivery_list(self, production):
return [
[0, '', {'production_id': production.id, 'type': '上产线', 'delivery_num': '%s-%s' % (production.name, 1)}],
[0, '',
{'production_id': production.id, 'type': '下产线', 'delivery_num': '%s-%s' % (production.name, 2)}]]
[0, '', {'production_id': production.id, 'type': '上产线'}],
[0, '', {'production_id': production.id, 'type': '下产线'}]]
# 拼接工单对象属性值(表面工艺)
def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id):
@@ -632,6 +639,33 @@ class ResMrpWorkOrder(models.Model):
# 'domain': [('production_id', '=', self.id)],
# 'target':'new'
# }
@api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state')
def _compute_state(self):
for workorder in self:
if workorder.routing_type == '装夹预调':
if not workorder.cnc_ids:
workorder.state = 'waiting'
else:
for item in 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:
workorder.state = 'waiting'
if workorder.state == 'pending':
if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
workorder.state = 'ready' if workorder.production_id.reservation_state == 'assigned' else 'waiting'
continue
if workorder.state not in ('waiting', 'ready'):
continue
if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
workorder.state = 'pending'
continue
if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'):
continue
if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting':
workorder.state = 'ready'
elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready':
workorder.state = 'waiting'
def recreateManufacturingOrWorkerOrder(self):
"""
@@ -701,7 +735,18 @@ class ResMrpWorkOrder(models.Model):
def button_start(self):
if self.routing_type == '装夹预调' and self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name:
self.pro_code = self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name
if self.routing_type == '装夹预调':
cnc_workorder = self.search(
[('production_id', '=', self.production_id.id), ('routing_type', '=', 'CNC加工')],
limit=1, order='id asc')
if not cnc_workorder:
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))
if self.routing_type == '解除装夹':
'''
记录开始时间
@@ -919,6 +964,9 @@ class CNCprocessing(models.Model):
if workpiece_delivery:
for item in workpiece_delivery:
item.is_cnc_program_down = True
if item.workorder_id.state == 'waiting':
item.workorder_id.state = 'ready'
# cnc_workorder.time_ids.date_end = datetime.now()
# cnc_workorder.button_finish()
@@ -1005,9 +1053,13 @@ class SfWorkOrderBarcodes(models.Model):
workorder = self.env['mrp.workorder'].browse(self.ids)
# workorder_preset = self.env['mrp.workorder'].search(
# [('routing_type', '=', '装夹预调'), ('rfid_code', '=', barcode)])
workorder_old = self.env['mrp.workorder'].search([('rfid_code', '=', barcode)])
if workorder_old:
raise UserError('该托盘已绑定【%s】制造订单,请先解除绑定!!!' % workorder_old.production_id.name)
workorder_olds = self.env['mrp.workorder'].search(
[('routing_type', '=', '装夹预调'), ('rfid_code', '=', barcode)])
if workorder_olds:
name = ''
for workorder in workorder_olds:
name = '%s %s' % (name, workorder.production_id.name)
raise UserError('该托盘已绑定【%s】制造订单,请先解除绑定!!!' % name)
if workorder:
if workorder.routing_type == '装夹预调':
if workorder.state in ['done']:
@@ -1035,6 +1087,8 @@ class SfWorkOrderBarcodes(models.Model):
for item in workorder_rfid:
item.write({'rfid_code': barcode})
logging.info("Rfid绑定成功")
else:
raise UserError('该Rfid【%s】绑定的是【%s】, 不是托盘!!!' % (barcode, lot.product_id.name))
self.process_state = '待检测'
self.date_start = datetime.now()
else:
@@ -1094,12 +1148,12 @@ class WorkPieceDelivery(models.Model):
_name = "sf.workpiece.delivery"
_description = '工件配送'
delivery_num = fields.Char('工件配送编码')
name = fields.Char('单据编号')
workorder_id = fields.Many2one('mrp.workorder', string='工单', readonly=True)
workorder_state = fields.Selection(related='workorder_id.state', string='工单状态')
rfid_code = fields.Char(related='workorder_id.rfid_code', string='rfid码', store=True)
production_id = fields.Many2one('mrp.production', string='制造订单号', readonly=True)
production_line_id = fields.Many2one('sf.production.line', compute='_compute_production_line_id',
string='目的生产线', readonly=True,
store=True)
production_line_id = fields.Many2one('sf.production.line', string='目的生产线')
plan_start_processing_time = fields.Datetime('计划开始加工时间', readonly=True)
route_id = fields.Many2one('sf.agv.task.route', '任务路线')
@@ -1113,9 +1167,24 @@ class WorkPieceDelivery(models.Model):
status = fields.Selection(
[('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送')], string='状态', default='待下发')
is_cnc_program_down = fields.Boolean('程序是否下发', default=False)
active = fields.Boolean(string="有效", default=True)
# @api.model
# def create(self, vals):
@api.model
def create(self, vals):
if vals.get('name', '/') == '/' or vals.get('name', '/') is False:
vals['name'] = self.env['ir.sequence'].next_by_code('sf.workpiece.delivery') or '/'
obj = super(WorkPieceDelivery, self).create(vals)
return obj
def action_delivery_history(self):
return {
'name': _('配送历史'),
'type': 'ir.actions.act_window',
'view_mode': 'tree',
'res_model': 'sf.workpiece.delivery',
'view_id': self.env.ref('sf_manufacturing.sf_workpiece_delivery_empty_racks_tree').id,
'domain': [('type', '=', '运送空料架'), ('route_id', '=', self.route_id.id), ('name', 'ilike', 'WDO')]
}
@api.onchange('route_id')
def onchange_route(self):
@@ -1126,6 +1195,7 @@ class WorkPieceDelivery(models.Model):
# 工件配送
def button_delivery(self):
delivery_ids = []
production_ids = []
is_cnc_down = 0
is_not_production_line = 0
is_not_route = 0
@@ -1136,29 +1206,44 @@ class WorkPieceDelivery(models.Model):
num = 0
for item in self:
num += 1
if num > 4:
raise UserError('仅限于配送1-4个制造订单请重新选择')
if item.route_id:
if same_route_id is None:
same_route_id = item.route_id.id
if item.route_id.id != same_route_id:
is_not_route += 1
else:
raise UserError('请选择【任务路线】再进行配送')
if production_type is None:
production_type = item.type
if production_type != item.type:
raise UserError('请选择类型为%s的制造订单进行配送' % production_type)
if down_status != item.status:
raise UserError('请选择状态为【待下发】的制造订单进行配送')
if same_production_line_id is None:
same_production_line_id = item.production_line_id.id
if item.production_line_id.id != same_production_line_id:
is_not_production_line += 1
if item.is_cnc_program_down is False:
is_cnc_down += 1
if is_cnc_down == 0 and is_not_production_line == 0 and is_not_route == 0:
delivery_ids.append(item.id)
if item.type == "运送空料架":
if num >= 2:
raise UserError('仅选择一条路线进行配送,请重新选择')
else:
delivery_ids.append(item.id)
else:
if num > 4:
raise UserError('仅限于配送1-4个制造订单请重新选择')
if item.status in ['待配送', '已配送']:
raise UserError('请选择状态为【待下发】的制造订单进行配送')
if item.route_id:
if same_route_id is None:
same_route_id = item.route_id.id
if item.route_id.id != same_route_id:
is_not_route += 1
else:
raise UserError('请选择【任务路线】再进行配送')
if production_type != item.type:
raise UserError('请选择类型为%s的制造订单进行配送' % production_type)
if down_status != item.status:
up_workpiece = self.search([('type', '=', '上产线'), ('production_id', '=', item.production_id),
('status', '=', '待下发')])
if up_workpiece:
raise UserError('您所选择的制造订单暂未上产线,请在上产线后再进行配送')
else:
raise UserError('请选择状态为【待下发】的制造订单进行配送')
if same_production_line_id is None:
same_production_line_id = item.production_line_id.id
if item.production_line_id.id != same_production_line_id:
is_not_production_line += 1
if item.is_cnc_program_down is False:
is_cnc_down += 1
if is_cnc_down == 0 and is_not_production_line == 0 and is_not_route == 0:
delivery_ids.append(item.id)
production_ids.append(item.production_id.id)
if is_cnc_down >= 1:
raise UserError('您所选择制造订单的【CNC程序】暂未下发请在程序下发后再进行配送')
if is_not_production_line >= 1:
@@ -1176,9 +1261,17 @@ class WorkPieceDelivery(models.Model):
'target': 'new',
'context': {
'default_delivery_ids': [(6, 0, delivery_ids)],
'default_production_ids': [(6, 0, production_ids)],
'default_destination_production_line_id': same_production_line_id,
'default_route_id': same_route_id,
'default_type': production_type,
}}
else:
raise UserError("您所选择制造订单的【任务路线】的【终点接驳站】已占用,请在该接驳站空闲时进行配送")
if self.type == '运送空料架':
raise UserError("您所选择的【任务路线】的【终点接驳站】已占用,请在该接驳站空闲时进行配送")
else:
raise UserError(
"您所选择制造订单的【任务路线】的【终点接驳站】已占用,请在该接驳站空闲时或选择其他路线进行配送")
# 验证agv站点是否可用
def _check_avgsite_state(self):
@@ -1187,15 +1280,18 @@ class WorkPieceDelivery(models.Model):
if agv_site:
agv_site.update_site_state()
for item in self:
if item.type in ["上产线", "下产线"]:
logging.info('工件配送-起点状态:%s-%s' % (
item.feeder_station_start_id.name, item.feeder_station_start_id.state))
logging.info('工件配送-终点状态:%s-%s' % (
item.feeder_station_destination_id.name, item.feeder_station_destination_id.state))
logging.info('工件配送-起点状态:%s-%s' % (
item.feeder_station_start_id.name, item.feeder_station_start_id.state))
logging.info('工件配送-终点状态:%s-%s' % (
item.feeder_station_destination_id.name, item.feeder_station_destination_id.state))
if item.type in ['上产线', '下产线']:
if (
item.feeder_station_start_id.state == '占用' and item.feeder_station_destination_id.state == '空闲') or (
item.feeder_station_start_id.state == '空闲' and item.feeder_station_destination_id.state == '空闲'):
is_free = True
else:
if item.feeder_station_destination_id.state == '空闲':
is_free = True
logging.info('is_free:%s' % is_free)
return is_free
@@ -1206,12 +1302,23 @@ class WorkPieceDelivery(models.Model):
delivery_Arr = []
feeder_station_start = None
feeder_station_destination = None
route_id = None
for item in self:
if feeder_station_start is None:
feeder_station_start = item.feeder_station_start_id.name
if feeder_station_destination is None:
feeder_station_destination = item.feeder_station_destination_id.name
delivery_Arr.append(item.delivery_num)
delivery_Arr.append(item.name)
if item.type in ['上产线', '下产线']:
if route_id is None:
route_id = item.route_id.id
if feeder_station_start is None:
feeder_station_start = item.feeder_station_start_id.name
if feeder_station_destination is None:
feeder_station_destination = item.feeder_station_destination_id.name
item.route_id = route_id
else:
self = self.create(
{'name': self.env['ir.sequence'].next_by_code('sf.workpiece.delivery'),
'route_id': self.route_id.id,
'feeder_station_start_id': self.feeder_station_start_id.id,
'feeder_station_destination_id': self.feeder_station_destination_id.id})
delivery_str = ','.join(map(str, delivery_Arr))
if feeder_station_start is not None:
positionCode_Arr.append({
@@ -1240,24 +1347,19 @@ class WorkPieceDelivery(models.Model):
req_codes = ret['reqCode'].split(',')
for delivery_item in self:
for req_code in req_codes:
if delivery_item.delivery_num == req_code.strip():
logging.info('delivery_num:%s' % delivery_item.delivery_num)
if delivery_item.name == req_code.strip():
logging.info('delivery_item-name:%s' % delivery_item.name)
delivery_item.write({
'task_delivery_time': fields.Datetime.now(),
'status': '待配送'
})
delivery_item.workorder_id.write({'is_delivery': True})
if delivery_item == "上产线":
delivery_item.workorder_id.write({'is_delivery': True})
else:
raise UserError(ret['message'])
except Exception as e:
logging.info('config-e:%s' % e)
raise UserError("工件配送请求agv失败")
@api.onchange('production_id.production_line_id')
def _compute_production_line_id(self):
if self.production_id.production_line_id:
self.production_line_id = self.production_id.production_line_id.id
self.plan_start_processing_time = self.production_id.plan_start_processing_time
raise UserError("工件配送请求agv失败:%s" % e)
@api.depends('task_delivery_time', 'task_completion_time')
def _compute_delivery_duration(self):