Accept Merge Request #1286: (feature/流程用扫码完成 -> develop)

Merge Request: 扫码触发页面按钮,解除装夹起始站点根据下产线终点站点自动赋值

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1286
This commit is contained in:
胡尧
2024-09-09 17:31:25 +08:00
committed by Coding
9 changed files with 126 additions and 11 deletions

View File

@@ -0,0 +1,61 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { barcodeGenericHandlers } from '@barcodes/barcode_handlers';
import { patch } from "@web/core/utils/patch";
// 定义新的 clickOnButton 函数
function customClickOnButton(selector) {
console.log("This is the custom clickOnButton function!");
const buttons = document.body.querySelectorAll(selector);
let length = buttons.length;
if (length > 0) {
buttons[length - 1].click();
} else {
console.warn(`Button with selector ${selector} not found`);
}
}
patch(barcodeGenericHandlers, "start", {
start(env, { ui, barcode, notification }) {
// 使用新定义的 clickOnButton 函数
const COMMANDS = {
"O-CMD.EDIT": () => customClickOnButton(".o_form_button_edit"),
"O-CMD.DISCARD": () => customClickOnButton(".o_form_button_cancel"),
"O-CMD.SAVE": () => customClickOnButton(".o_form_button_save"),
"O-CMD.PREV": () => customClickOnButton(".o_pager_previous"),
"O-CMD.NEXT": () => customClickOnButton(".o_pager_next"),
"O-CMD.PAGER-FIRST": () => updatePager("first"),
"O-CMD.PAGER-LAST": () => updatePager("last"),
"O-CMD.CONFIRM": () => customClickOnButton(".jikimo_button_confirm"),
};
barcode.bus.addEventListener("barcode_scanned", (ev) => {
const barcode = ev.detail.barcode;
if (barcode.startsWith("O-BTN.")) {
let targets = [];
try {
targets = getVisibleElements(ui.activeElement, `[barcode_trigger=${barcode.slice(6)}]`);
} catch (_e) {
console.warn(`Barcode '${barcode}' is not valid`);
}
for (let elem of targets) {
elem.click();
}
}
if (barcode.startsWith("O-CMD.")) {
const fn = COMMANDS[barcode];
if (fn) {
fn();
} else {
notification.add(env._t("Barcode: ") + `'${barcode}'`, {
title: env._t("Unknown barcode command"),
type: "danger"
});
}
}
});
}
})

View File

@@ -5,9 +5,12 @@ import { registry } from '@web/core/registry';
import { formView } from '@web/views/form/form_view'; import { formView } from '@web/views/form/form_view';
import { FormController } from '@web/views/form/form_controller'; import { FormController } from '@web/views/form/form_controller';
import { listView } from '@web/views/list/list_view';
import { ListController } from '@web/views/list/list_controller'
import { onRendered, onMounted } from "@odoo/owl"; import { onRendered, onMounted } from "@odoo/owl";
export class RemoveFocusController extends FormController { export class RemoveFocusFormController extends FormController {
setup() { setup() {
super.setup(); super.setup();
@@ -17,7 +20,23 @@ export class RemoveFocusController extends FormController {
} }
} }
registry.category('views').add('remove_focus_view', { registry.category('views').add('remove_focus_form_view', {
...formView, ...formView,
Controller: RemoveFocusController, Controller: RemoveFocusFormController,
});
export class RemoveFocusListController extends ListController {
setup() {
super.setup();
onMounted(() => {
this.__owl__.bdom.el.querySelectorAll(':focus').forEach(element => element.blur());
})
}
}
registry.category('views').add('remove_focus_list_view', {
...listView,
Controller: RemoveFocusListController,
}); });

View File

@@ -45,6 +45,7 @@
'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', 'sf_manufacturing/static/src/js/workpiece_delivery_wizard_confirm.js',
'sf_manufacturing/static/src/js/custom_barcode_handlers.js',
] ]
}, },

View File

@@ -265,3 +265,17 @@ class ResMrpWorkOrder(models.Model):
'sf_agv_scheduling_mrp_workorder_ref', 'sf_agv_scheduling_mrp_workorder_ref',
string='AGV调度', string='AGV调度',
domain=[('state', '!=', '已取消')]) domain=[('state', '!=', '已取消')])
def get_down_product_agv_scheduling(self):
"""
获取关联的制造订单下产线的agv任务
"""
workorder_ids = self.production_id.workorder_ids
cnc_workorder = workorder_ids.filtered(
lambda w: w.routing_type == 'CNC加工' and w.state == 'done' and w.processing_panel == self.processing_panel
)
if cnc_workorder:
agv_schedulingss = cnc_workorder.agv_scheduling_ids
return agv_schedulingss.filtered(lambda a: a.state == '已配送' and a.agv_route_type == '下产线')
else:
return None

View File

@@ -1340,7 +1340,7 @@ class ResMrpWorkOrder(models.Model):
'name': 'button_delivery', 'name': 'button_delivery',
'type': 'object', 'type': 'object',
'string': '解除装夹', 'string': '解除装夹',
'class': 'btn-primary', 'class': 'btn-primary jikimo_button_confirm',
# 'className': 'btn-primary', # 'className': 'btn-primary',
'modifiers': '{"force_show": 1}' 'modifiers': '{"force_show": 1}'
}) })
@@ -1355,6 +1355,7 @@ class ResMrpWorkOrder(models.Model):
workorder_ids = [] workorder_ids = []
delivery_type = '运送空料架' delivery_type = '运送空料架'
max_num = 4 # 最大配送数量 max_num = 4 # 最大配送数量
feeder_station_start_id = False
if len(self) > max_num: if len(self) > max_num:
raise UserError('仅限于拆卸1-4个制造订单请重新选择') raise UserError('仅限于拆卸1-4个制造订单请重新选择')
for item in self: for item in self:
@@ -1363,6 +1364,10 @@ class ResMrpWorkOrder(models.Model):
production_ids.append(item.production_id.id) production_ids.append(item.production_id.id)
workorder_ids.append(item.id) workorder_ids.append(item.id)
if not feeder_station_start_id:
down_product_agv_scheduling = self.get_down_product_agv_scheduling()
if down_product_agv_scheduling:
feeder_station_start_id = down_product_agv_scheduling.end_site_id.id
return { return {
'name': _('确认'), 'name': _('确认'),
'type': 'ir.actions.act_window', 'type': 'ir.actions.act_window',
@@ -1375,7 +1380,8 @@ class ResMrpWorkOrder(models.Model):
'default_delivery_type': delivery_type, 'default_delivery_type': delivery_type,
'default_workorder_ids': [(6, 0, workorder_ids)], 'default_workorder_ids': [(6, 0, workorder_ids)],
'default_workcenter_id': self.env.context.get('default_workcenter_id'), 'default_workcenter_id': self.env.context.get('default_workcenter_id'),
'default_confirm_button': '确认解除' 'default_confirm_button': '确认解除',
'default_feeder_station_start_id': feeder_station_start_id,
}} }}

View File

@@ -10,7 +10,7 @@ odoo.define('sf_manufacturing.action_dispatch_confirm', function (require) {
title: "确认", title: "确认",
$content: $('<div>').append("请确认是否仅配送" + params.workorder_count + "个工件?"), $content: $('<div>').append("请确认是否仅配送" + params.workorder_count + "个工件?"),
buttons: [ buttons: [
{ text: "确认", classes: 'btn-primary', close: true, click: () => dispatchConfirmed(parent, params) }, { text: "确认", classes: 'btn-primary jikimo_button_confirm', close: true, click: () => dispatchConfirmed(parent, params) },
{ text: "取消", close: true }, { text: "取消", close: true },
], ],
}); });

View File

@@ -659,9 +659,9 @@
<field name="name">工件配送</field> <field name="name">工件配送</field>
<field name="model">sf.workpiece.delivery</field> <field name="model">sf.workpiece.delivery</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="工件配送" class="center" create="0" delete="0"> <tree string="工件配送" class="center" create="0" delete="0" js_class="remove_focus_list_view">
<header> <header>
<button name="button_delivery" type="object" string="工件配送" class="btn-primary" attrs="{'force_show':1}"/> <button name="button_delivery" type="object" string="工件配送" class="btn-primary jikimo_button_confirm" attrs="{'force_show':1}"/>
</header> </header>
<field name="status" widget="badge" <field name="status" widget="badge"
decoration-success="status == '已配送'" decoration-success="status == '已配送'"

View File

@@ -4,7 +4,7 @@
<field name="name">sf.workpiece.delivery.wizard.form.view</field> <field name="name">sf.workpiece.delivery.wizard.form.view</field>
<field name="model">sf.workpiece.delivery.wizard</field> <field name="model">sf.workpiece.delivery.wizard</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form js_class="remove_focus_view"> <form js_class="remove_focus_form_view">
<sheet> <sheet>
<field name="delivery_ids" invisible="True"/> <field name="delivery_ids" invisible="True"/>
<field name="workorder_ids" invisible="True"/> <field name="workorder_ids" invisible="True"/>
@@ -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="dispatch_confirm" type="object" class="oe_highlight o_wizard_confirm_button" attrs="{'invisible': [('confirm_button', '!=', '确认配送')]}"/> <button string="确认配送" name="dispatch_confirm" type="object" class="oe_highlight o_wizard_confirm_button jikimo_button_confirm" 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="dispatch_confirm" type="object" class="oe_highlight o_wizard_confirm_button jikimo_button_confirm" attrs="{'invisible': [('confirm_button', '!=', '确认解除')]}"/>
<button string="取消" class="btn btn-secondary" special="cancel"/> <button string="取消" class="btn btn-secondary" special="cancel"/>
</footer> </footer>
</sheet> </sheet>

View File

@@ -180,6 +180,13 @@ class WorkpieceDeliveryWizard(models.TransientModel):
self.feeder_station_destination_id = self.route_id.end_site_id.id self.feeder_station_destination_id = self.route_id.end_site_id.id
def on_barcode_scanned(self, barcode): def on_barcode_scanned(self, barcode):
# 判断barcode是否是数字
if not barcode.isdigit():
# 判断是否是AGV接驳站名称
agv_site = self.env['sf.agv.site'].search([('name', '=', barcode)])
if agv_site:
self.feeder_station_start_id = agv_site.id
return
delivery_type = self.env.context.get('default_delivery_type') delivery_type = self.env.context.get('default_delivery_type')
if delivery_type == '上产线': if delivery_type == '上产线':
workorder = self.env['mrp.workorder'].search( workorder = self.env['mrp.workorder'].search(
@@ -203,6 +210,13 @@ class WorkpieceDeliveryWizard(models.TransientModel):
# 将对象添加到对应的同模型且是多对多类型里 # 将对象添加到对应的同模型且是多对多类型里
self.production_ids |= workorder.production_id self.production_ids |= workorder.production_id
self.workorder_ids |= workorder self.workorder_ids |= workorder
if not self.feeder_station_start_id:
down_product_agv_scheduling = self.get_down_product_agv_scheduling()
if down_product_agv_scheduling:
self.feeder_station_start_id = down_product_agv_scheduling.end_site_id.id
else: else:
raise UserError('该rfid码对应的工单不存在') raise UserError('该rfid码对应的工单不存在')
return return