diff --git a/sf_manufacturing/__manifest__.py b/sf_manufacturing/__manifest__.py
index 35501367..71f4027a 100644
--- a/sf_manufacturing/__manifest__.py
+++ b/sf_manufacturing/__manifest__.py
@@ -45,6 +45,8 @@
'sf_manufacturing/static/src/scss/kanban_change.scss',
'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/qr.js',
+ 'sf_manufacturing/static/src/xml/qr.xml',
]
},
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index 23129578..01977926 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -1105,9 +1105,11 @@ class ResMrpWorkOrder(models.Model):
if self.routing_type == '装夹预调':
# 判断是否有坯料的序列号信息
boolean = False
- if self.production_id.move_raw_ids[0].move_line_ids:
- if self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name:
- boolean = True
+ if self.production_id.move_raw_ids:
+ if self.production_id.move_raw_ids[0].move_line_ids:
+ if self.production_id.move_raw_ids[0].move_line_ids:
+ if self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name:
+ boolean = True
if not boolean:
raise UserError('制造订单【%s】缺少组件的序列号信息!' % self.production_id.name)
self.pro_code = self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name
diff --git a/sf_manufacturing/static/src/js/qr.js b/sf_manufacturing/static/src/js/qr.js
new file mode 100644
index 00000000..fd501f27
--- /dev/null
+++ b/sf_manufacturing/static/src/js/qr.js
@@ -0,0 +1,115 @@
+/** @odoo-module **/
+import { registry } from '@web/core/registry';
+import { Component } from '@odoo/owl';
+
+class QRCodeWidget extends Component {
+ // 初始化组件
+ setup() {
+ console.log('QRCodeWidget setup');
+ this.qrCodeValue = ''; // 初始化为空字符串,用于存储条码
+ this.inputBuffer = ''; // 存储临时输入的字符
+ this.inputTimer = null; // 定时器
+
+ // 显式绑定上下文
+ this.onGlobalKeyDown = this.onGlobalKeyDown.bind(this);
+ window.addEventListener('keydown', this.onGlobalKeyDown);
+ }
+
+ // 清理事件监听器,防止内存泄漏
+ willUnmount() {
+ window.removeEventListener('keydown', this.onGlobalKeyDown);
+ if (this.inputTimer) {
+ clearTimeout(this.inputTimer);
+ }
+ }
+
+ // 全局键盘事件监听器
+ onGlobalKeyDown(event) {
+
+ // 如果是Tab键,表示扫码输入结束
+ if (event.key === 'Tab' || event.key === 'Enter') {
+ this.qrCodeValue = this.inputBuffer; // 完整条码赋值
+ console.log('完整条码:', this.qrCodeValue);
+ this.onQRCodeChange(this.qrCodeValue); // 调用父组件的 onQRCodeChange 方法
+ this.inputBuffer = ''; // 清空临时缓冲区
+ event.preventDefault(); // 阻止Tab键的默认行为
+ return;
+ }
+
+ // 只处理可打印字符
+ if (event.key.length === 1) {
+ this.inputBuffer += event.key; // 添加到缓冲区
+ // console.log('当前缓冲区:', this.inputBuffer);
+
+ // 清除之前的定时器,重新开始计时
+ if (this.inputTimer) {
+ clearTimeout(this.inputTimer);
+ }
+
+ // 启动一个定时器,如果500ms内没有新的输入,则认为条码输入完成
+ this.inputTimer = setTimeout(() => {
+ this.qrCodeValue = this.inputBuffer;
+ // console.log('定时器触发,完整条码:', this.qrCodeValue);
+ this.inputBuffer = ''; // 清空缓冲区
+ }, 500); // 可以根据需要调整时间
+ }
+
+ }
+
+ // 处理二维码输入变更
+ async onQRCodeChange(qrCodeValue) {
+ console.log('onQRCodeChange二维码输入变更', qrCodeValue); // 检查二维码的输入是否被捕获
+
+ if (qrCodeValue) {
+ // console.log('二维码输入变更');
+ try {
+ // 发起 RPC 请求
+ const result = await this.env.services.rpc('/web/dataset/call_kw', {
+ model: 'mrp.workorder',
+ method: 'search_read',
+ args: [
+ [['rfid_code', '=', qrCodeValue]], // 查询条件
+ ['id'] // 返回的字段
+ ],
+ kwargs: {}
+ });
+
+ if (result.length > 0) {
+ console.log('该二维码对应的工单存在!');
+ } else {
+ console.log('未找到对应的工单。');
+
+ const routingTypeField = document.querySelector('[name="routing_type"]');
+ if (routingTypeField) {
+ let fieldValue = routingTypeField.querySelector('span').getAttribute('raw-value');
+ console.log('Routing Type Value:', fieldValue);
+ // 清理多余的引号
+ fieldValue = fieldValue ? fieldValue.replace(/["]+/g, '') : null;
+ console.log(fieldValue);
+
+ if (fieldValue && fieldValue === '装夹预调') {
+ // console.log('routing_type 为装夹预调');
+
+ // 检查 RFID 值
+ if (!qrCodeValue || qrCodeValue.length <= 3) return;
+
+ // 查找 name="button_start" 按钮并触发点击事件
+ const startButton = document.querySelector('[name="button_start"]');
+ if (startButton) {
+ startButton.click();
+ }
+ }
+ }
+ }
+ } catch (error) {
+ console.error('查询工单时出错:', error);
+ }
+ }
+ }
+
+ // 返回模板名称
+ static template = 'sf_manufacturing.QRCodeWidgetTemplate';
+}
+
+// 将自定义字段注册到字段注册表
+registry.category('fields').add('qrcode_widget', QRCodeWidget);
diff --git a/sf_manufacturing/static/src/xml/qr.xml b/sf_manufacturing/static/src/xml/qr.xml
new file mode 100644
index 00000000..415c0cd8
--- /dev/null
+++ b/sf_manufacturing/static/src/xml/qr.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml
index f3aa70cc..708a9779 100644
--- a/sf_manufacturing/views/mrp_workorder_view.xml
+++ b/sf_manufacturing/views/mrp_workorder_view.xml
@@ -125,9 +125,9 @@
mrp.workorder
-
-
-
+
+
+
@@ -225,6 +225,7 @@
+
@@ -246,8 +247,8 @@
-
+