生产总监、机床操作岗增加agv调度菜单权限,AGV下发任务界面需二次确认
This commit is contained in:
@@ -43,6 +43,7 @@
|
|||||||
'sf_manufacturing/static/src/js/kanban_change.js',
|
'sf_manufacturing/static/src/js/kanban_change.js',
|
||||||
'sf_manufacturing/static/src/scss/kanban_change.scss',
|
'sf_manufacturing/static/src/scss/kanban_change.scss',
|
||||||
'sf_manufacturing/static/src/xml/button_show_on_tree.xml',
|
'sf_manufacturing/static/src/xml/button_show_on_tree.xml',
|
||||||
|
'sf_manufacturing/static/src/js/workpiece_delivery_wizard_confirm.js',
|
||||||
]
|
]
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -458,7 +458,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
if f'RfidCode{i}' in ret:
|
if f'RfidCode{i}' in ret:
|
||||||
rfid_code = ret[f'RfidCode{i}']
|
rfid_code = ret[f'RfidCode{i}']
|
||||||
logging.info('RfidCode:%s' % rfid_code)
|
logging.info('RfidCode:%s' % rfid_code)
|
||||||
if rfid_code is not None:
|
if rfid_code is not None and rfid_code != '':
|
||||||
rfid_codes.append(rfid_code)
|
rfid_codes.append(rfid_code)
|
||||||
domain = [
|
domain = [
|
||||||
('rfid_code', '=', rfid_code),
|
('rfid_code', '=', rfid_code),
|
||||||
@@ -531,7 +531,7 @@ class Manufacturing_Connect(http.Controller):
|
|||||||
if f'RfidCode{i}' in ret:
|
if f'RfidCode{i}' in ret:
|
||||||
rfid_code = ret[f'RfidCode{i}']
|
rfid_code = ret[f'RfidCode{i}']
|
||||||
logging.info('RfidCode:%s' % rfid_code)
|
logging.info('RfidCode:%s' % rfid_code)
|
||||||
if rfid_code is not None:
|
if rfid_code is not None and rfid_code != '':
|
||||||
domain = [
|
domain = [
|
||||||
('rfid_code', '=', rfid_code),
|
('rfid_code', '=', rfid_code),
|
||||||
('routing_type', '=', 'CNC加工'), ('state', '!=', 'rework')
|
('routing_type', '=', 'CNC加工'), ('state', '!=', 'rework')
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ class AgvScheduling(models.Model):
|
|||||||
agv_route_type: AGV任务类型
|
agv_route_type: AGV任务类型
|
||||||
workorders: 工单
|
workorders: 工单
|
||||||
"""
|
"""
|
||||||
|
_logger.info('创建AGV调度任务\r\n起点为【%s】,任务类型为【%s】,工单为【%s】' % (agv_start_site_name, agv_route_type, workorders))
|
||||||
if not workorders:
|
if not workorders:
|
||||||
raise UserError(_('工单不能为空'))
|
raise UserError(_('工单不能为空'))
|
||||||
agv_start_site = self.env['sf.agv.site'].sudo().search([('name', '=', agv_start_site_name)], limit=1)
|
agv_start_site = self.env['sf.agv.site'].sudo().search([('name', '=', agv_start_site_name)], limit=1)
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
odoo.define('sf_manufacturing.action_dispatch_confirm', function (require) {
|
||||||
|
const core = require('web.core');
|
||||||
|
const ajax = require('web.ajax');
|
||||||
|
const Dialog = require('web.Dialog');
|
||||||
|
var rpc = require('web.rpc');
|
||||||
|
var _t = core._t;
|
||||||
|
|
||||||
|
async function dispatch_confirm(parent, {params}) {
|
||||||
|
console.log(params, 'params')
|
||||||
|
console.log("<div>本次下发的工件数量为:" + params.workorder_count + ",是否确认?</div>", 'content')
|
||||||
|
const dialog = new Dialog(parent, {
|
||||||
|
title: "确认",
|
||||||
|
$content: $('<div>').append("请确认是否仅配送" + params.workorder_count + "个工件?"),
|
||||||
|
buttons: [
|
||||||
|
{ text: "确认", classes: 'btn-primary', close: true, click: () => dispatchConfirmed(parent, params) },
|
||||||
|
{ text: "取消", close: true },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
dialog.open();
|
||||||
|
|
||||||
|
|
||||||
|
async function dispatchConfirmed(parent, params) {
|
||||||
|
console.log(parent, 'parent')
|
||||||
|
rpc.query({
|
||||||
|
model: 'sf.workpiece.delivery.wizard',
|
||||||
|
method: 'confirm',
|
||||||
|
args: [params.active_id]
|
||||||
|
,
|
||||||
|
kwargs: {
|
||||||
|
context: params.context,
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
console.log(res, 'res')
|
||||||
|
console.log(res.name, 'res')
|
||||||
|
parent.services.action.doAction({
|
||||||
|
'type': 'ir.actions.client',
|
||||||
|
'tag': 'display_notification',
|
||||||
|
'target': 'new',
|
||||||
|
'params': {
|
||||||
|
'message': '任务下发成功!AGV任务调度编号为【' + res.name + '】',
|
||||||
|
'type': 'success',
|
||||||
|
'sticky': false,
|
||||||
|
'next': {'type': 'ir.actions.act_window_close'},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
core.action_registry.add('dispatch_confirm', dispatch_confirm);
|
||||||
|
return dispatch_confirm;
|
||||||
|
});
|
||||||
@@ -73,6 +73,7 @@
|
|||||||
sequence="28"
|
sequence="28"
|
||||||
action="action_agv_scheduling_tree"
|
action="action_agv_scheduling_tree"
|
||||||
parent="mrp.menu_mrp_manufacturing"
|
parent="mrp.menu_mrp_manufacturing"
|
||||||
|
groups="sf_base.group_sf_order_user,sf_base.group_sf_mrp_manager,sf_base.group_sf_equipment_user"
|
||||||
/>
|
/>
|
||||||
</data>
|
</data>
|
||||||
</odoo>
|
</odoo>
|
||||||
@@ -835,5 +835,11 @@
|
|||||||
<field name="view_mode">tree</field>
|
<field name="view_mode">tree</field>
|
||||||
<field name="domain">[('type','in',['运送空料架']),('name','not ilike','WDO')]</field>
|
<field name="domain">[('type','in',['运送空料架']),('name','not ilike','WDO')]</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<menuitem id="mrp.menu_mrp_manufacturing"
|
||||||
|
name="Operations"
|
||||||
|
sequence="10"
|
||||||
|
parent="mrp.menu_mrp_root"
|
||||||
|
groups="sf_base.group_sf_order_user,sf_base.group_sf_mrp_manager,sf_base.group_sf_equipment_user"/>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
<field name="workcenter_id" options="{'no_create': True}"/>
|
<field name="workcenter_id" options="{'no_create': True}"/>
|
||||||
</group>
|
</group>
|
||||||
<footer>
|
<footer>
|
||||||
<button string="确认配送" name="confirm" type="object" class="oe_highlight" attrs="{'invisible': [('confirm_button', '!=', '确认配送')]}"/>
|
<button string="确认配送" name="dispatch_confirm" type="object" class="oe_highlight o_wizard_confirm_button" attrs="{'invisible': [('confirm_button', '!=', '确认配送')]}"/>
|
||||||
<button string="确认解除" name="confirm" type="object" class="oe_highlight" attrs="{'invisible': [('confirm_button', '!=', '确认解除')]}"/>
|
<button string="确认解除" name="dispatch_confirm" type="object" class="oe_highlight o_wizard_confirm_button" attrs="{'invisible': [('confirm_button', '!=', '确认解除')]}"/>
|
||||||
<button string="取消" class="btn btn-secondary" special="cancel"/>
|
<button string="取消" class="btn btn-secondary" special="cancel"/>
|
||||||
<script>
|
<script>
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Part of YiZuo. See LICENSE file for full copyright and licensing details.
|
# Part of YiZuo. See LICENSE file for full copyright and licensing details.
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
from odoo.exceptions import UserError, ValidationError
|
from odoo.exceptions import UserError, ValidationError
|
||||||
from datetime import datetime
|
from datetime import datetime, date
|
||||||
from odoo import models, api, fields, _
|
from odoo import models, api, fields
|
||||||
|
|
||||||
|
|
||||||
|
def convert_datetime(obj):
|
||||||
|
if isinstance(obj, (datetime, date)):
|
||||||
|
return obj.isoformat() # 将 datetime 或 date 对象转换为 ISO 8601 字符串格式
|
||||||
|
raise TypeError(f"Type {type(obj)} not serializable")
|
||||||
|
|
||||||
|
|
||||||
class WorkpieceDeliveryWizard(models.TransientModel):
|
class WorkpieceDeliveryWizard(models.TransientModel):
|
||||||
@@ -34,18 +41,18 @@ class WorkpieceDeliveryWizard(models.TransientModel):
|
|||||||
self.workcenter_id = workcenter_ids[0]
|
self.workcenter_id = workcenter_ids[0]
|
||||||
return {
|
return {
|
||||||
'domain':
|
'domain':
|
||||||
{
|
{
|
||||||
'feeder_station_start_id': [('id', 'in', start_site_ids)],
|
'feeder_station_start_id': [('id', 'in', start_site_ids)],
|
||||||
'workcenter_id': [('id', 'in', workcenter_ids)],
|
'workcenter_id': [('id', 'in', workcenter_ids)],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
return {
|
return {
|
||||||
'domain':
|
'domain':
|
||||||
{
|
{
|
||||||
'feeder_station_start_id': [],
|
'feeder_station_start_id': [],
|
||||||
'workcenter_id': [],
|
'workcenter_id': [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_agv_route_type_selection(self):
|
def _get_agv_route_type_selection(self):
|
||||||
@@ -53,6 +60,31 @@ class WorkpieceDeliveryWizard(models.TransientModel):
|
|||||||
|
|
||||||
delivery_type = fields.Selection(selection=_get_agv_route_type_selection, string='类型')
|
delivery_type = fields.Selection(selection=_get_agv_route_type_selection, string='类型')
|
||||||
|
|
||||||
|
def dispatch_confirm(self):
|
||||||
|
if len(self.workorder_ids) < 4:
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.client',
|
||||||
|
'tag': 'dispatch_confirm',
|
||||||
|
'params': {
|
||||||
|
'workorder_count': len(self.workorder_ids),
|
||||||
|
'active_id': self.id,
|
||||||
|
'context': self.env.context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
scheduling = self.confirm()
|
||||||
|
# 显示通知
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.client',
|
||||||
|
'tag': 'display_notification',
|
||||||
|
'target': 'new',
|
||||||
|
'params': {
|
||||||
|
'message': '任务下发成功!AGV任务调度编号为【%s】' % scheduling['name'],
|
||||||
|
'type': 'success',
|
||||||
|
'sticky': False,
|
||||||
|
'next': {'type': 'ir.actions.act_window_close'},
|
||||||
|
}
|
||||||
|
}
|
||||||
def confirm(self):
|
def confirm(self):
|
||||||
try:
|
try:
|
||||||
# if self.workorder_id:
|
# if self.workorder_id:
|
||||||
@@ -89,18 +121,7 @@ class WorkpieceDeliveryWizard(models.TransientModel):
|
|||||||
item.button_start()
|
item.button_start()
|
||||||
item.button_finish()
|
item.button_finish()
|
||||||
|
|
||||||
# 显示通知
|
return scheduling.read()[0]
|
||||||
return {
|
|
||||||
'type': 'ir.actions.client',
|
|
||||||
'tag': 'display_notification',
|
|
||||||
'target': 'new',
|
|
||||||
'params': {
|
|
||||||
'message': '任务下发成功!AGV任务调度编号为【%s】' % scheduling.name,
|
|
||||||
'type': 'success',
|
|
||||||
'sticky': False,
|
|
||||||
'next': {'type': 'ir.actions.act_window_close'},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.info('%s任务下发失败:%s' % (self.delivery_type, e))
|
logging.info('%s任务下发失败:%s' % (self.delivery_type, e))
|
||||||
raise UserError('%s任务下发失败:%s' % (self.delivery_type, e))
|
raise UserError('%s任务下发失败:%s' % (self.delivery_type, e))
|
||||||
@@ -167,7 +188,8 @@ class WorkpieceDeliveryWizard(models.TransientModel):
|
|||||||
[('routing_type', '=', '解除装夹'), ('rfid_code', '=', barcode),
|
[('routing_type', '=', '解除装夹'), ('rfid_code', '=', barcode),
|
||||||
('state', '=', 'ready')])
|
('state', '=', 'ready')])
|
||||||
if workorder:
|
if workorder:
|
||||||
if len(self.production_ids) > 0 and workorder.production_line_id.id != self.production_ids[0].production_line_id.id:
|
if (len(self.production_ids) > 0 and
|
||||||
|
workorder.production_line_id.id != self.production_ids[0].production_line_id.id):
|
||||||
raise UserError('该rfid对应的制造订单号为%s的目的生产线不一致' % workorder.production_id.name)
|
raise UserError('该rfid对应的制造订单号为%s的目的生产线不一致' % workorder.production_id.name)
|
||||||
|
|
||||||
# 将对象添加到对应的同模型且是多对多类型里
|
# 将对象添加到对应的同模型且是多对多类型里
|
||||||
|
|||||||
@@ -337,6 +337,7 @@
|
|||||||
name="空料架配送"
|
name="空料架配送"
|
||||||
sequence="11"
|
sequence="11"
|
||||||
action="sf_manufacturing.sf_workpiece_delivery_empty_racks_act"
|
action="sf_manufacturing.sf_workpiece_delivery_empty_racks_act"
|
||||||
|
groups="base.group_system"
|
||||||
parent="mrp.menu_mrp_manufacturing"
|
parent="mrp.menu_mrp_manufacturing"
|
||||||
/>
|
/>
|
||||||
<!-- <menuitem -->
|
<!-- <menuitem -->
|
||||||
|
|||||||
Reference in New Issue
Block a user