增加agv调度系统
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
'data/stock_data.xml',
|
'data/stock_data.xml',
|
||||||
'data/empty_racks_data.xml',
|
'data/empty_racks_data.xml',
|
||||||
'data/panel_data.xml',
|
'data/panel_data.xml',
|
||||||
|
'data/agv_dispatch_data.xml',
|
||||||
'security/group_security.xml',
|
'security/group_security.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'wizard/workpiece_delivery_views.xml',
|
'wizard/workpiece_delivery_views.xml',
|
||||||
|
|||||||
12
sf_manufacturing/data/agv_dispatch_data.xml
Normal file
12
sf_manufacturing/data/agv_dispatch_data.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="sequence_workpiece_delivery" model="ir.sequence">
|
||||||
|
<field name="name">AGV调度</field>
|
||||||
|
<field name="code">sf.agv.dispatch</field>
|
||||||
|
<field name="prefix">B%(year)s%(month)s%(day)s</field>
|
||||||
|
<field name="padding">4</field>
|
||||||
|
<field name="company_id" eval="False"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
@@ -1,20 +1,24 @@
|
|||||||
from odoo import models, fields, api
|
from odoo import models, fields, api, _
|
||||||
from odoo.exceptions import ValidationError
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AgvDispatch(models.Model):
|
class AgvDispatch(models.Model):
|
||||||
_name = 'sf.agv.dispatch'
|
_name = 'sf.agv.dispatch'
|
||||||
_description = 'agv调度'
|
_description = 'agv调度'
|
||||||
|
|
||||||
name = fields.Char('任务单号')
|
name = fields.Char('任务单号', index=True, copy=False)
|
||||||
|
|
||||||
def _get_agv_route_type_selection(self):
|
def _get_agv_route_type_selection(self):
|
||||||
return self.env['sf.agv.task.route'].fields_get(['route_type'])['route_type']['selection']
|
return self.env['sf.agv.task.route'].fields_get(['route_type'])['route_type']['selection']
|
||||||
|
|
||||||
agv_route_type = fields.Selection(selection=_get_agv_route_type_selection, string='任务类型')
|
agv_route_type = fields.Selection(selection=_get_agv_route_type_selection, string='任务类型', required=True)
|
||||||
agv_route_name = fields.Char('任务路线名称')
|
agv_route_name = fields.Char('任务路线名称')
|
||||||
start_site_id = fields.Many2one('sf.agv.site', '起点接驳站')
|
start_site_id = fields.Many2one('sf.agv.site', '起点接驳站', required=True)
|
||||||
end_site_id = fields.Many2one('sf.agv.site', '终点接驳站')
|
end_site_id = fields.Many2one('sf.agv.site', '终点接驳站', tracking=True)
|
||||||
site_state = fields.Selection([
|
site_state = fields.Selection([
|
||||||
('占用', '占用'),
|
('占用', '占用'),
|
||||||
('空闲', '空闲')], string='终点接驳站状态')
|
('空闲', '空闲')], string='终点接驳站状态')
|
||||||
@@ -22,7 +26,8 @@ class AgvDispatch(models.Model):
|
|||||||
('待下发', '待下发'),
|
('待下发', '待下发'),
|
||||||
('配送中', '配送中'),
|
('配送中', '配送中'),
|
||||||
('已配送', '已配送'),
|
('已配送', '已配送'),
|
||||||
('已取消', '已取消')], string='状态', default='待下发')
|
('已取消', '已取消')], string='状态', default='待下发', tracking=True)
|
||||||
|
productions = fields.Char('制造订单', compute='_compute_productions')
|
||||||
workpiece_delivery_ids = fields.One2many('sf.workpiece.delivery', 'agv_dispatch_id', string='工件配送单')
|
workpiece_delivery_ids = fields.One2many('sf.workpiece.delivery', 'agv_dispatch_id', string='工件配送单')
|
||||||
delivery_workpieces = fields.Char('配送工件', compute='_compute_delivery_workpieces')
|
delivery_workpieces = fields.Char('配送工件', compute='_compute_delivery_workpieces')
|
||||||
|
|
||||||
@@ -44,7 +49,28 @@ class AgvDispatch(models.Model):
|
|||||||
else:
|
else:
|
||||||
rec.task_duration = ''
|
rec.task_duration = ''
|
||||||
|
|
||||||
def add_queue(self, vals):
|
@api.model_create_multi
|
||||||
if not vals.get('agv_route_type') or vals.get('agv_route_type') not in self._get_agv_route_type_selection():
|
def create(self, vals_list):
|
||||||
raise ValidationError('无效的路线类型!')
|
# We generate a standard reference
|
||||||
self.env['sf.agv.dispatch'].sudo().create(vals)
|
for vals in vals_list:
|
||||||
|
vals['name'] = self.env['ir.sequence'].next_by_code('sf.agv.dispatch') or _('New')
|
||||||
|
return super().create(vals_list)
|
||||||
|
|
||||||
|
def add_queue(self, agv_start_site_id, agv_route_type, production_ids, delivery_ids):
|
||||||
|
"""
|
||||||
|
根据参数增加AGV调度任务
|
||||||
|
"""
|
||||||
|
vals = {
|
||||||
|
'start_site_id': agv_start_site_id,
|
||||||
|
'agv_route_type': agv_route_type,
|
||||||
|
'productions': '、'.join(production_ids.mapped('name')),
|
||||||
|
'workpiece_delivery_ids': delivery_ids or [],
|
||||||
|
'task_create_time': fields.Datetime.now()
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
dispatch = self.env['sf.agv.dispatch'].sudo().create(vals)
|
||||||
|
except Exception as e:
|
||||||
|
_logger.error('添加AGV调度任务失败: %s', e)
|
||||||
|
raise UserError(e)
|
||||||
|
|
||||||
|
return dispatch
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class AgvSetting(models.Model):
|
|||||||
('空闲', '空闲')], string='状态')
|
('空闲', '空闲')], string='状态')
|
||||||
divide_the_work = fields.Char('主要分工')
|
divide_the_work = fields.Char('主要分工')
|
||||||
active = fields.Boolean('有效', default=True)
|
active = fields.Boolean('有效', default=True)
|
||||||
region = fields.Many2one(string='所属区域', comodel_name='mrp.workcenter', tracking=True,
|
workcenter_id = fields.Many2one(string='所属区域', comodel_name='mrp.workcenter', tracking=True,
|
||||||
domain=[('is_agv_dispatch', '=', True)])
|
domain=[('is_agv_dispatch', '=', True)])
|
||||||
|
|
||||||
def update_site_state(self):
|
def update_site_state(self):
|
||||||
@@ -73,14 +73,16 @@ class AgvTaskRoute(models.Model):
|
|||||||
if self.end_site_id == self.start_site_id:
|
if self.end_site_id == self.start_site_id:
|
||||||
raise UserError("您选择的终点接驳站与起点接驳站重复,请重新选择")
|
raise UserError("您选择的终点接驳站与起点接驳站重复,请重新选择")
|
||||||
|
|
||||||
region = fields.Many2one(string='所属区域', comodel_name='mrp.workcenter', domain=[('is_agv_dispatch', '=', True)],
|
workcenter_id = fields.Many2one(string='所属区域', comodel_name='mrp.workcenter', domain=[('is_agv_dispatch', '=', True)],
|
||||||
compute="_compute_region")
|
compute="_compute_region")
|
||||||
|
|
||||||
@api.depends('end_site_id')
|
@api.depends('end_site_id')
|
||||||
def _compute_region(self):
|
def _compute_region(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
if record.end_site_id:
|
if record.end_site_id:
|
||||||
record.region = record.end_site_id.region
|
record.workcenter_id = record.end_site_id.workcenter_id
|
||||||
|
else:
|
||||||
|
record.workcenter_id = None
|
||||||
|
|
||||||
|
|
||||||
class Center_controlInterfaceLog(models.Model):
|
class Center_controlInterfaceLog(models.Model):
|
||||||
|
|||||||
@@ -634,25 +634,33 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
k, item),
|
k, item),
|
||||||
'cmm_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cmm.program']._json_cmm_program(k,
|
'cmm_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cmm.program']._json_cmm_program(k,
|
||||||
item),
|
item),
|
||||||
'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self._json_workpiece_delivery_list(
|
# 'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self._json_workpiece_delivery_list(
|
||||||
production)
|
# production)
|
||||||
}]
|
}]
|
||||||
return workorders_values_str
|
return workorders_values_str
|
||||||
|
|
||||||
def _json_workpiece_delivery_list(self, production):
|
def _json_workpiece_delivery_list(self):
|
||||||
up_route = self.env['sf.agv.task.route'].search([('route_type', '=', '上产线')], limit=1, order='id asc')
|
# 修改在装夹工单完成后,生成上产线的工件配送单
|
||||||
down_route = self.env['sf.agv.task.route'].search([('route_type', '=', '下产线')], limit=1, order='id asc')
|
|
||||||
|
# up_route = self.env['sf.agv.task.route'].search([('route_type', '=', '上产线')], limit=1, order='id asc')
|
||||||
|
# down_route = self.env['sf.agv.task.route'].search([('route_type', '=', '下产线')], limit=1, order='id asc')
|
||||||
return [
|
return [
|
||||||
[0, '',
|
[0, '',
|
||||||
{'production_id': production.id, 'production_line_id': production.production_line_id.id, 'type': '上产线',
|
{
|
||||||
'route_id': up_route.id,
|
'production_id': self.production_id.id,
|
||||||
'feeder_station_start_id': up_route.start_site_id.id,
|
'production_line_id': self.production_id.production_line_id.id,
|
||||||
'feeder_station_destination_id': up_route.end_site_id.id}],
|
'type': '上产线',
|
||||||
[0, '',
|
# 'route_id': up_route.id,
|
||||||
{'production_id': production.id, 'production_line_id': production.production_line_id.id, 'type': '下产线',
|
# 'feeder_station_start_id': agv_start_site_id,
|
||||||
'route_id': down_route.id,
|
# 'feeder_station_destination_id': up_route.end_site_id.id
|
||||||
'feeder_station_start_id': down_route.start_site_id.id,
|
}
|
||||||
'feeder_station_destination_id': down_route.end_site_id.id}]]
|
],
|
||||||
|
# [0, '',
|
||||||
|
# {'production_id': production.id, 'production_line_id': production.production_line_id.id, 'type': '下产线',
|
||||||
|
# 'route_id': down_route.id,
|
||||||
|
# 'feeder_station_start_id': down_route.start_site_id.id,
|
||||||
|
# 'feeder_station_destination_id': down_route.end_site_id.id}]
|
||||||
|
]
|
||||||
|
|
||||||
# 拼接工单对象属性值(表面工艺)
|
# 拼接工单对象属性值(表面工艺)
|
||||||
def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id):
|
def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id):
|
||||||
@@ -1182,6 +1190,8 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
raw_move.write({'state': 'done'})
|
raw_move.write({'state': 'done'})
|
||||||
record.production_id.button_mark_done1()
|
record.production_id.button_mark_done1()
|
||||||
# record.production_id.state = 'done'
|
# record.production_id.state = 'done'
|
||||||
|
# 生成工件配送单
|
||||||
|
record.workpiece_delivery_ids = record._json_workpiece_delivery_list()
|
||||||
|
|
||||||
# 将FTP的检测报告文件下载到临时目录
|
# 将FTP的检测报告文件下载到临时目录
|
||||||
def download_reportfile_tmp(self, workorder, reportpath):
|
def download_reportfile_tmp(self, workorder, reportpath):
|
||||||
@@ -1485,7 +1495,7 @@ class SfWorkOrderBarcodes(models.Model):
|
|||||||
|
|
||||||
class WorkPieceDelivery(models.Model):
|
class WorkPieceDelivery(models.Model):
|
||||||
_name = "sf.workpiece.delivery"
|
_name = "sf.workpiece.delivery"
|
||||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
_inherit = ['mail.thread', 'mail.activity.mixin', "barcodes.barcode_events_mixin"]
|
||||||
_description = '工件配送'
|
_description = '工件配送'
|
||||||
|
|
||||||
name = fields.Char('单据编码')
|
name = fields.Char('单据编码')
|
||||||
@@ -1501,11 +1511,14 @@ class WorkPieceDelivery(models.Model):
|
|||||||
feeder_station_destination_id = fields.Many2one('sf.agv.site', '目的接驳站')
|
feeder_station_destination_id = fields.Many2one('sf.agv.site', '目的接驳站')
|
||||||
task_delivery_time = fields.Datetime('任务下发时间')
|
task_delivery_time = fields.Datetime('任务下发时间')
|
||||||
task_completion_time = fields.Datetime('任务完成时间')
|
task_completion_time = fields.Datetime('任务完成时间')
|
||||||
type = fields.Selection(
|
|
||||||
[('上产线', '上产线'), ('下产线', '下产线'), ('运送空料架', '运送空料架')], string='类型')
|
def _get_agv_route_type_selection(self):
|
||||||
|
return self.env['sf.agv.task.route'].fields_get(['route_type'])['route_type']['selection']
|
||||||
|
|
||||||
|
type = fields.Selection(selection=_get_agv_route_type_selection, string='类型')
|
||||||
delivery_duration = fields.Float('配送时长', compute='_compute_delivery_duration')
|
delivery_duration = fields.Float('配送时长', compute='_compute_delivery_duration')
|
||||||
status = fields.Selection(
|
status = fields.Selection(
|
||||||
[('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送'), ('已取消', '已取消')], string='状态',
|
[('待下发', '待下发'), ('已下发', '已下发'), ('已配送', '已配送'), ('已取消', '已取消')], string='状态',
|
||||||
default='待下发',
|
default='待下发',
|
||||||
tracking=True)
|
tracking=True)
|
||||||
is_cnc_program_down = fields.Boolean('程序是否下发', default=False, tracking=True)
|
is_cnc_program_down = fields.Boolean('程序是否下发', default=False, tracking=True)
|
||||||
@@ -1564,82 +1577,41 @@ class WorkPieceDelivery(models.Model):
|
|||||||
production_ids = []
|
production_ids = []
|
||||||
is_cnc_down = 0
|
is_cnc_down = 0
|
||||||
is_not_production_line = 0
|
is_not_production_line = 0
|
||||||
is_not_route = 0
|
|
||||||
same_production_line_id = None
|
same_production_line_id = None
|
||||||
same_route_id = None
|
same_route_id = None
|
||||||
down_status = '待下发'
|
production_type = '上产线'
|
||||||
production_type = None
|
max_num = 4 # 最大配送数量
|
||||||
num = 0
|
if len(self) > max_num:
|
||||||
|
raise UserError('仅限于配送1-4个制造订单,请重新选择')
|
||||||
for item in self:
|
for item in self:
|
||||||
num += 1
|
if item.status != '待下发':
|
||||||
if production_type is None:
|
raise UserError('请选择状态为【待下发】的制造订单进行配送')
|
||||||
production_type = item.type
|
if same_production_line_id is None:
|
||||||
if item.type == "运送空料架":
|
same_production_line_id = item.production_line_id.id
|
||||||
if num >= 2:
|
if item.production_line_id.id != same_production_line_id:
|
||||||
raise UserError('仅选择一条路线进行配送,请重新选择')
|
is_not_production_line += 1
|
||||||
else:
|
if item.is_cnc_program_down is False:
|
||||||
delivery_ids.append(item.id)
|
is_cnc_down += 1
|
||||||
else:
|
if is_cnc_down == 0 and is_not_production_line == 0:
|
||||||
if num > 4:
|
delivery_ids.append(item.id)
|
||||||
raise UserError('仅限于配送1-4个制造订单,请重新选择')
|
production_ids.append(item.production_id.id)
|
||||||
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 item.production_id.production_line_state == '已下产线' and item.state == '待下发' and item.type == '下产线':
|
|
||||||
# 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:
|
if is_cnc_down >= 1:
|
||||||
raise UserError('您所选择制造订单的【CNC程序】暂未下发,请在程序下发后再进行配送')
|
raise UserError('您所选择制造订单的【CNC程序】暂未下发,请在程序下发后再进行配送')
|
||||||
if is_not_production_line >= 1:
|
if is_not_production_line >= 1:
|
||||||
raise UserError('您所选择制造订单的【目的生产线】不一致,请重新确认')
|
raise UserError('您所选择制造订单的【目的生产线】不一致,请重新确认')
|
||||||
if is_not_route >= 1:
|
if delivery_ids:
|
||||||
raise UserError('您所选择制造订单的【任务路线】不一致,请重新确认')
|
return {
|
||||||
is_free = self._check_avgsite_state()
|
'name': _('确认'),
|
||||||
if is_free is True:
|
'type': 'ir.actions.act_window',
|
||||||
if delivery_ids:
|
'view_mode': 'form',
|
||||||
return {
|
'res_model': 'sf.workpiece.delivery.wizard',
|
||||||
'name': _('确认'),
|
'target': 'new',
|
||||||
'type': 'ir.actions.act_window',
|
'context': {
|
||||||
'view_mode': 'form',
|
'default_delivery_ids': [(6, 0, delivery_ids)],
|
||||||
'res_model': 'sf.workpiece.delivery.wizard',
|
'default_production_ids': [(6, 0, production_ids)],
|
||||||
'target': 'new',
|
'default_type': production_type,
|
||||||
'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:
|
|
||||||
if production_type == '运送空料架':
|
|
||||||
raise UserError("您所选择的【任务路线】的【终点接驳站】已占用,请在该接驳站空闲时进行配送")
|
|
||||||
else:
|
|
||||||
raise UserError(
|
|
||||||
"您所选择制造订单的【任务路线】的【终点接驳站】已占用,请在该接驳站空闲时或选择其他路线进行配送")
|
|
||||||
|
|
||||||
# 验证agv站点是否可用
|
# 验证agv站点是否可用
|
||||||
def _check_avgsite_state(self):
|
def _check_avgsite_state(self):
|
||||||
@@ -1747,6 +1719,9 @@ class WorkPieceDelivery(models.Model):
|
|||||||
# agv调度单
|
# agv调度单
|
||||||
agv_dispatch_id = fields.Many2one('sf.agv.dispatch', 'agv调度单')
|
agv_dispatch_id = fields.Many2one('sf.agv.dispatch', 'agv调度单')
|
||||||
|
|
||||||
|
def on_barcode_scanned(self, barcode):
|
||||||
|
logging.info('Rfid:%s' % barcode)
|
||||||
|
|
||||||
|
|
||||||
class CMMprogram(models.Model):
|
class CMMprogram(models.Model):
|
||||||
_name = 'sf.cmm.program'
|
_name = 'sf.cmm.program'
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree editable="bottom">
|
<tree editable="bottom">
|
||||||
<field name="name" required="1" attrs="{'readonly': [('id', '!=', False)]}"/>
|
<field name="name" required="1" attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||||
<field name="region" required="1" options="{'no_create': True}"/>
|
<field name="workcenter_id" required="1" options="{'no_create': True}"/>
|
||||||
<field name="state" required="1" attrs="{'readonly': [('id', '!=', False)]}"/>
|
<field name="state" required="1" attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||||
<field name="divide_the_work" required="1"/>
|
<field name="divide_the_work" required="1"/>
|
||||||
</tree>
|
</tree>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
<field name="end_site_id" required="1" options="{'no_create': True}" string="终点接驳站"/>
|
<field name="end_site_id" required="1" options="{'no_create': True}" string="终点接驳站"/>
|
||||||
<!-- <field name="destination_production_line_id" required="1" options="{'no_create': True}"-->
|
<!-- <field name="destination_production_line_id" required="1" options="{'no_create': True}"-->
|
||||||
<!-- attrs="{'readonly': [('id', '!=', False)]}"/>-->
|
<!-- attrs="{'readonly': [('id', '!=', False)]}"/>-->
|
||||||
<field name="region"/>
|
<field name="workcenter_id"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|||||||
@@ -643,15 +643,15 @@
|
|||||||
<field name="production_id"/>
|
<field name="production_id"/>
|
||||||
<field name="type" readonly="1"/>
|
<field name="type" readonly="1"/>
|
||||||
<field name="production_line_id" options="{'no_create': True}" readonly="1"/>
|
<field name="production_line_id" options="{'no_create': True}" readonly="1"/>
|
||||||
<field name="route_id" options="{'no_create': True}"
|
<!-- <field name="route_id" options="{'no_create': True}"-->
|
||||||
domain="[('route_type','in',['上产线','下产线'])]"/>
|
<!-- domain="[('route_type','in',['上产线','下产线'])]"/>-->
|
||||||
<field name="feeder_station_start_id" readonly="1" force_save="1"/>
|
<field name="feeder_station_start_id" readonly="1" force_save="1"/>
|
||||||
<field name="feeder_station_destination_id" readonly="1" force_save="1"/>
|
<!-- <field name="feeder_station_destination_id" readonly="1" force_save="1"/>-->
|
||||||
<field name="is_cnc_program_down" readonly="1"/>
|
<field name="is_cnc_program_down" readonly="1"/>
|
||||||
<!-- <field name="rfid_code"/>-->
|
<!-- <field name="rfid_code"/>-->
|
||||||
<field name="task_delivery_time" readonly="1"/>
|
<!-- <field name="task_delivery_time" readonly="1"/>-->
|
||||||
<field name="task_completion_time" readonly="1"/>
|
<!-- <field name="task_completion_time" readonly="1"/>-->
|
||||||
<field name="delivery_duration" widget="float_time"/>
|
<!-- <field name="delivery_duration" widget="float_time"/>-->
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|||||||
@@ -9,23 +9,17 @@
|
|||||||
<field name="delivery_ids" invisible="True"/>
|
<field name="delivery_ids" invisible="True"/>
|
||||||
<field name="workorder_id" invisible="True"/>
|
<field name="workorder_id" invisible="True"/>
|
||||||
<field name="type" invisible="True"/>
|
<field name="type" invisible="True"/>
|
||||||
<group attrs="{'invisible': [('type', 'in', ['运送空料架'])]}">
|
<group col="1">
|
||||||
<field name="production_ids" readonly="1" widget="many2many_tags" string="制造订单号"/>
|
<field name="production_ids" readonly="1" widget="many2many_tags" string="制造订单号"/>
|
||||||
<div class="o_address_format">
|
<div class="o_address_format">
|
||||||
<lable for="rfid_code"></lable>
|
<lable for="rfid_code"></lable>
|
||||||
<field name="rfid_code" class="o_address_zip"/>
|
<field name="rfid_code" class="o_address_zip"/>
|
||||||
<button name="recognize_production" string="识别" type="object" class="oe_highlight"/>
|
<button name="recognize_production" string="识别" type="object" class="oe_highlight"/>
|
||||||
</div>
|
</div>
|
||||||
<field name="destination_production_line_id" readonly="1"/>
|
<field name="type" readonly="1"/>
|
||||||
<field name="route_id"/>
|
<field name="feeder_station_start_id" options="{'no_create': True}" require="1"/>
|
||||||
|
<field name="workcenter_id" options="{'no_create': True}"/>
|
||||||
</group>
|
</group>
|
||||||
<group attrs="{'invisible': [('type', 'in', ['运送空料架'])]}">
|
|
||||||
<field name="feeder_station_start_id" focesave="1" readonly="1"/>
|
|
||||||
<field name="feeder_station_destination_id" focesave="1" readonly="1"/>
|
|
||||||
</group>
|
|
||||||
<div attrs="{'invisible': [('type', 'in', ['上产线','下产线'])]}">
|
|
||||||
是否确定配送
|
|
||||||
</div>
|
|
||||||
<footer>
|
<footer>
|
||||||
<button string="配送" name="confirm" type="object" class="oe_highlight"/>
|
<button string="配送" name="confirm" type="object" class="oe_highlight"/>
|
||||||
<button string="取消" class="btn btn-secondary" special="cancel"/>
|
<button string="取消" class="btn btn-secondary" special="cancel"/>
|
||||||
|
|||||||
@@ -18,15 +18,40 @@ class WorkpieceDeliveryWizard(models.TransientModel):
|
|||||||
route_id = fields.Many2one('sf.agv.task.route', '任务路线', domain=[('route_type', 'in', ['上产线', '下产线'])])
|
route_id = fields.Many2one('sf.agv.task.route', '任务路线', domain=[('route_type', 'in', ['上产线', '下产线'])])
|
||||||
feeder_station_start_id = fields.Many2one('sf.agv.site', '起点接驳站')
|
feeder_station_start_id = fields.Many2one('sf.agv.site', '起点接驳站')
|
||||||
feeder_station_destination_id = fields.Many2one('sf.agv.site', '目的接驳站')
|
feeder_station_destination_id = fields.Many2one('sf.agv.site', '目的接驳站')
|
||||||
type = fields.Selection(
|
workcenter_id = fields.Many2one(string='所属区域', comodel_name='mrp.workcenter', tracking=True)
|
||||||
[('上产线', '上产线'), ('下产线', '下产线'), ('运送空料架', '运送空料架')], string='类型')
|
|
||||||
|
@api.onchange('type')
|
||||||
|
def _onchange_type(self):
|
||||||
|
routes = self.env['sf.agv.task.route'].search([('route_type', '=', self.type)])
|
||||||
|
if self.type:
|
||||||
|
start_site_ids = routes.mapped('start_site_id.id')
|
||||||
|
workcenter_ids = routes.mapped('end_site_id.workcenter_id.id')
|
||||||
|
if workcenter_ids:
|
||||||
|
self.workcenter_id = workcenter_ids[0]
|
||||||
|
return {
|
||||||
|
'domain':
|
||||||
|
{
|
||||||
|
'feeder_station_start_id': [('id', 'in', start_site_ids)],
|
||||||
|
'workcenter_id': [('id', 'in', workcenter_ids)],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
'domain':
|
||||||
|
{
|
||||||
|
'feeder_station_start_id': [],
|
||||||
|
'workcenter_id': [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def _get_agv_route_type_selection(self):
|
||||||
|
return self.env['sf.agv.task.route'].fields_get(['route_type'])['route_type']['selection']
|
||||||
|
|
||||||
|
type = fields.Selection(selection=_get_agv_route_type_selection, string='类型')
|
||||||
|
|
||||||
def confirm(self):
|
def confirm(self):
|
||||||
if self.type != '运送空料架':
|
|
||||||
if not self.route_id:
|
|
||||||
raise UserError('请选择路线')
|
|
||||||
if self.workorder_id:
|
if self.workorder_id:
|
||||||
self.workorder_id.workpiece_delivery_ids[0]._delivery_avg()
|
self.workorder_id.workpiece_delivery_ids[0].agv_dispatch_id()
|
||||||
else:
|
else:
|
||||||
is_not_production_line = 0
|
is_not_production_line = 0
|
||||||
same_production_line_id = None
|
same_production_line_id = None
|
||||||
@@ -40,7 +65,14 @@ class WorkpieceDeliveryWizard(models.TransientModel):
|
|||||||
if is_not_production_line >= 1:
|
if is_not_production_line >= 1:
|
||||||
raise UserError('制造订单号为%s的目的生产线不一致' % notsame_production_line_str)
|
raise UserError('制造订单号为%s的目的生产线不一致' % notsame_production_line_str)
|
||||||
else:
|
else:
|
||||||
self.delivery_ids._delivery_avg()
|
# self.delivery_ids._delivery_avg()
|
||||||
|
agv_dispatch_id = self.env['sf.agv.dispatch'].add_queue(
|
||||||
|
agv_start_site_id=self.feeder_station_start_id.id,
|
||||||
|
agv_route_type=self.type,
|
||||||
|
production_ids=self.production_ids,
|
||||||
|
delivery_ids=self.delivery_ids.ids
|
||||||
|
)
|
||||||
|
self.delivery_ids.agv_dispatch_id = agv_dispatch_id
|
||||||
|
|
||||||
def recognize_production(self):
|
def recognize_production(self):
|
||||||
# production_ids = []
|
# production_ids = []
|
||||||
|
|||||||
Reference in New Issue
Block a user