@ -0,0 +1,50 @@ |
|||
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg |
|||
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html |
|||
:alt: License: AGPL-3 |
|||
|
|||
Scan Product Barcode for Sale & Purchase |
|||
======================================== |
|||
This module captures barcode of products through system camera and add product |
|||
to order line. |
|||
|
|||
Configuration |
|||
============= |
|||
* No additional configurations are required |
|||
|
|||
Company |
|||
======= |
|||
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
|||
|
|||
License |
|||
======= |
|||
GNU LESSER GENERAL PUBLIC LICENSE, Version 3 (AGPLv3) |
|||
(https://www.gnu.org/licenses/agpl-3.0-standalone.html) |
|||
|
|||
Credits |
|||
======= |
|||
* Developers: (V18) Manasa T P, |
|||
(V17) Subina , |
|||
(V16) RAHUL C K, |
|||
Contact: odoo@cybrosys.com |
|||
|
|||
Contacts |
|||
======== |
|||
* Mail Contact : odoo@cybrosys.com |
|||
* Website : https://cybrosys.com |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
|||
|
|||
Maintainer |
|||
========== |
|||
.. image:: https://cybrosys.com/images/logo.png |
|||
:target: https://cybrosys.com |
|||
|
|||
This module is maintained by Cybrosys Technologies. |
|||
|
|||
For support and more information, please visit https://www.cybrosys.com. |
|||
|
|||
Further information |
|||
=================== |
|||
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,22 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################ |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
|||
# Author: Manasa T P (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################ |
|||
from . import models |
@ -0,0 +1,58 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################ |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
|||
# Author: Manasa T P (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################ |
|||
{ |
|||
'name': "Scan Product Barcode for Sale & Purchase", |
|||
'version': '18.0.1.0.0', |
|||
'category': 'Extra Tools', |
|||
'summary': """Scan Barcode from Camera in sale and purchase orders.""", |
|||
'description': """Products can be added to sale or purchase orders by |
|||
scanning barcode of products through system camera. Products will be |
|||
automatically added to order line once the barcode is identified.""", |
|||
'author': "Cybrosys Techno Solutions", |
|||
'company': "Cybrosys Techno Solutions", |
|||
'maintainer': "Cybrosys Techno Solutions", |
|||
'website': "https://www.cybrosys.com", |
|||
'depends': ['sale_management', 'purchase'], |
|||
'data': [ |
|||
'views/sale_order_views.xml', |
|||
'views/purchase_order_views.xml' |
|||
], |
|||
'assets': { |
|||
'web.assets_backend': [ |
|||
'https://cdn.jsdelivr.net/npm/quagga@0.12.1/dist/quagga.min.js', |
|||
'barcode_capturing_sale_purchase/static/src/js/registry_barcode_sale.js', |
|||
'barcode_capturing_sale_purchase/static/src/js/registry_barcode_purchase.js', |
|||
'barcode_capturing_sale_purchase/static/src/js/sale_barcode.js', |
|||
'barcode_capturing_sale_purchase/static/src/js/purchase_barcode.js', |
|||
'barcode_capturing_sale_purchase/static/src/js/barcode_dialog.js', |
|||
'barcode_capturing_sale_purchase/static/src/css/styles.css', |
|||
'barcode_capturing_sale_purchase/static/src/xml/purchase_web_form_templates.xml', |
|||
'barcode_capturing_sale_purchase/static/src/xml/sale_web_form_templates.xml', |
|||
'barcode_capturing_sale_purchase/static/src/xml/barcode_dialog_templates.xml', |
|||
], |
|||
}, |
|||
'images': ['static/description/banner.jpg'], |
|||
'license': 'AGPL-3', |
|||
'installable': True, |
|||
'auto_install': False, |
|||
'application': False, |
|||
} |
@ -0,0 +1,7 @@ |
|||
## Module <barcode_capturing_sale_purchase> |
|||
|
|||
#### 09.04.2025 |
|||
#### Version 18.0.1.0.0 |
|||
#### ADD |
|||
|
|||
- Initial commit for Scan Product Barcode for Sale & Purchase |
@ -0,0 +1,23 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################ |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
|||
# Author: Manasa T P (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################ |
|||
from . import purchase_order |
|||
from . import sale_order |
@ -0,0 +1,57 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################ |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
|||
# Author: Manasa T P (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################ |
|||
from odoo import api, models |
|||
|
|||
|
|||
class PurchaseOrder(models.Model): |
|||
"""Module is inherited and function is created to create a purchase |
|||
order line with the scanned barcode of product""" |
|||
_inherit = 'purchase.order' |
|||
|
|||
@api.model |
|||
def barcode_search(self, last_code, order_id): |
|||
"""Purchase Order line is created and product is added by checking |
|||
the barcode. args contains the barcode of product and purchase order |
|||
id""" |
|||
product = self.env['product.product'].search([('barcode', '=', |
|||
last_code)]) |
|||
if not product: |
|||
return True |
|||
else: |
|||
purchase_order = self.browse(order_id) |
|||
if purchase_order.order_line: |
|||
for rec in purchase_order.order_line: |
|||
if rec.product_id == product: |
|||
rec.product_qty += 1 |
|||
return { |
|||
'type': 'ir.actions.client', |
|||
'tag': 'reload', |
|||
} |
|||
purchase_order.order_line.create({ |
|||
'order_id': purchase_order.id, |
|||
'product_id': product.id, |
|||
'product_uom_qty': 1 |
|||
}) |
|||
return { |
|||
'type': 'ir.actions.client', |
|||
'tag': 'reload', |
|||
} |
@ -0,0 +1,49 @@ |
|||
# -*- coding: utf-8 -*- |
|||
################################################################################ |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
|||
# Author: Manasa T P (odoo@cybrosys.com) |
|||
# |
|||
# You can modify it under the terms of the GNU AFFERO |
|||
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
|||
# |
|||
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
# (AGPL v3) along with this program. |
|||
# If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
################################################################################ |
|||
from odoo import api, models |
|||
|
|||
|
|||
class SaleOrder(models.Model): |
|||
"""Module is inherited and function is created to create a sale |
|||
order line with the scanned barcode of product""" |
|||
_inherit = 'sale.order' |
|||
|
|||
@api.model |
|||
def barcode_search(self, last_code, order_id): |
|||
"""Sale Order line is created and product is added by checking |
|||
the barcode. args contains the barcode of product and sale order id.""" |
|||
product = self.env['product.product'].search([('barcode', '=', |
|||
last_code)]) |
|||
if not product: |
|||
return True |
|||
else: |
|||
sale_order = self.browse(order_id) |
|||
if sale_order.order_line: |
|||
for rec in sale_order.order_line: |
|||
if rec.product_id == product: |
|||
rec.product_uom_qty += 1 |
|||
return |
|||
sale_order.order_line.create({ |
|||
'order_id': sale_order.id, |
|||
'product_id': product.id, |
|||
'product_uom_qty': 1 |
|||
}) |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 628 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 210 KiB |
After Width: | Height: | Size: 209 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 495 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 624 B |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 156 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 462 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 800 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 189 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 875 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 912 KiB |
After Width: | Height: | Size: 767 KiB |
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 138 KiB |
After Width: | Height: | Size: 760 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 697 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 331 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 880 KiB |
After Width: | Height: | Size: 144 KiB |
After Width: | Height: | Size: 8.5 KiB |
@ -0,0 +1,3 @@ |
|||
.btn-close{ |
|||
display:none; |
|||
} |
@ -0,0 +1,181 @@ |
|||
/** @odoo-module */ |
|||
import { browser } from "@web/core/browser/browser"; |
|||
import { Dialog } from "@web/core/dialog/dialog"; |
|||
import { _t } from "@web/core/l10n/translation"; |
|||
import { useChildRef, useService } from "@web/core/utils/hooks"; |
|||
import { Component, useRef, onWillUnmount } from "@odoo/owl"; |
|||
var beep = new Audio('/barcode_capturing_sale_purchase/static/src/audio/beep_scan.mp3'); |
|||
|
|||
//BarcodeDialog is a component that captures barcode input through the device's camera,
|
|||
// processes the scanned barcode, and interacts with the Odoo backend to perform
|
|||
// actions based on the scanned data.
|
|||
export class BarcodeDialog extends Component { |
|||
async setup() { |
|||
super.setup(); |
|||
this.env.dialogData.dismiss = () => this._cancel(); |
|||
this.orm = useService('orm'); |
|||
this.notificationService = useService("notification"); |
|||
this.modalRef = useChildRef(); |
|||
this.videoPreviewRef = useRef("videoPreview"); |
|||
this.isMounted = true; |
|||
|
|||
// Cleanup function to stop video stream when component unmounts
|
|||
onWillUnmount(() => { |
|||
this.isMounted = false; |
|||
this._stopVideoStream(); |
|||
}); |
|||
|
|||
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { |
|||
this.stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false }); |
|||
} else { |
|||
// Handle case where camera access is not available
|
|||
this.notificationService.add(_t("Camera access is not available"), { |
|||
title: _t("Error"), |
|||
type: "danger", |
|||
}); |
|||
this.props.close(); |
|||
return; |
|||
} |
|||
this.videoPreviewRef.el.srcObject = this.stream; |
|||
this.videoPreviewRef.el.play(); |
|||
Quagga.init({ |
|||
inputStream: { |
|||
name: "Live", |
|||
type: "LiveStream", |
|||
target: this.videoPreviewRef.el, |
|||
constraints: { |
|||
width: 640, |
|||
height: 480, |
|||
facingMode: "environment" // Use the rear camera
|
|||
} |
|||
}, |
|||
decoder: { |
|||
readers: [ |
|||
"code_128_reader", |
|||
"ean_reader", |
|||
"ean_8_reader", |
|||
"upc_reader", |
|||
"upc_e_reader" |
|||
] |
|||
} |
|||
}, (err) => { |
|||
if (err) { |
|||
return; |
|||
} |
|||
Quagga.start(); |
|||
}); |
|||
Quagga.onDetected((result) => { |
|||
if (!this.isMounted) return; |
|||
var barcode = result.codeResult.code; |
|||
Quagga.offDetected(); |
|||
Quagga.stop(); |
|||
this.scan_product(barcode); |
|||
}); |
|||
} |
|||
// Handles the cancellation of the dialog.
|
|||
async _cancel() { |
|||
return this.execButton(this.props.cancel); |
|||
} |
|||
// Handles the confirmation of the dialog.
|
|||
async _dialogConfirm() { |
|||
return this.execButton(this.props.confirm); |
|||
} |
|||
// Processes the scanned product by barcode.
|
|||
async scan_product(barcode) { |
|||
if (!this.isMounted) return; |
|||
var last_code = barcode; |
|||
var last_result = []; |
|||
last_result.push(last_code); |
|||
last_result = []; |
|||
beep.play(); |
|||
Quagga.stop(); |
|||
var order_id = this.props.order_id; |
|||
var method = this.props.model === "sale.order" ? "sale.order" : "purchase.order"; |
|||
try { |
|||
const data = await this.orm.call(method, "barcode_search", [last_code, order_id]); |
|||
if (!this.isMounted) return; |
|||
|
|||
if (data === true) { |
|||
this.notificationService.add(_t("Product with the scanned Barcode Not Found in the system"), { |
|||
title: _t("Product Not Found!"), |
|||
type: "danger", |
|||
}); |
|||
} else { |
|||
location.reload(); // Ensure the page reloads after adding a product
|
|||
} |
|||
} catch (error) { |
|||
if (this.isMounted) { |
|||
console.error("Error scanning product: ", error); |
|||
} |
|||
} |
|||
|
|||
this._stopVideoStream(); |
|||
this.props.close(); |
|||
} |
|||
// Stops the video stream if it is active.
|
|||
_stopVideoStream() { |
|||
if (this.videoPreviewRef.el && this.videoPreviewRef.el.srcObject) { |
|||
const tracks = this.videoPreviewRef.el.srcObject.getTracks(); |
|||
tracks.forEach((track) => track.stop()); |
|||
} |
|||
} |
|||
// sets button disabled
|
|||
setButtonsDisabled(disabled) { |
|||
this.isProcess = disabled; |
|||
if (!this.modalRef.el) { |
|||
return; |
|||
} |
|||
for (const button of [...this.modalRef.el.querySelectorAll(".modal-footer button")]) { |
|||
button.disabled = disabled; |
|||
} |
|||
} |
|||
|
|||
async execButton(callback) { |
|||
if (this.isProcess) { |
|||
return; |
|||
} |
|||
this.setButtonsDisabled(true); |
|||
if (callback) { |
|||
let shouldClose; |
|||
try { |
|||
shouldClose = await callback(); |
|||
} catch (e) { |
|||
this.props.close(); |
|||
throw e; |
|||
} |
|||
if (shouldClose === false) { |
|||
this.setButtonsDisabled(false); |
|||
return; |
|||
} |
|||
} |
|||
this.props.close(); |
|||
} |
|||
} |
|||
|
|||
BarcodeDialog.template = "BarcodeDialog"; |
|||
BarcodeDialog.components = { Dialog }; |
|||
BarcodeDialog.props = { |
|||
close: Function, |
|||
order_id: Number, |
|||
model: String, |
|||
title: { |
|||
validate: (m) => { |
|||
return ( |
|||
typeof m === "string" || (typeof m === "object" && typeof m.toString === "function") |
|||
); |
|||
}, |
|||
optional: true, |
|||
}, |
|||
body: String, |
|||
confirm: { type: Function, optional: true }, |
|||
confirmLabel: { type: String, optional: true }, |
|||
confirmClass: { type: String, optional: true }, |
|||
cancel: { type: Function, optional: true }, |
|||
cancelLabel: { type: String, optional: true }, |
|||
}; |
|||
BarcodeDialog.defaultProps = { |
|||
confirmLabel: _t("Ok"), |
|||
cancelLabel: _t("Cancel"), |
|||
confirmClass: "btn-primary", |
|||
title: _t("Confirmation"), |
|||
}; |
@ -0,0 +1,64 @@ |
|||
/** @odoo-module **/ |
|||
import { FormController } from "@web/views/form/form_controller"; |
|||
import { Dialog } from "@web/core/dialog/dialog"; |
|||
import { BarcodeDialog } from "./barcode_dialog.js"; |
|||
import { useChildRef, useService } from "@web/core/utils/hooks"; |
|||
import { Component, onWillUnmount, EventBus } from "@odoo/owl"; |
|||
import { _t } from "@web/core/l10n/translation"; |
|||
|
|||
var beep = new Audio('/barcode_capturing_sale_purchase/static/src/audio/beep_scan.mp3'); |
|||
// Extends FormController for rendering the purchase order form with barcode scanning functionality.
|
|||
export class ComPurchaseOrderRender extends FormController { |
|||
setup() { |
|||
this.bus = new EventBus(); |
|||
this.modalRef = useChildRef(); |
|||
this.isProcess = false; |
|||
this.dialog = useService("dialog"); |
|||
this.notificationService = useService("notification"); |
|||
onWillUnmount(() => { |
|||
if (this.stream) { |
|||
this.stream.getTracks().forEach((track) => track.stop()); |
|||
this.stream = null; |
|||
} |
|||
}); |
|||
super.setup(); |
|||
} |
|||
// Opens a dialog for barcode scanning.
|
|||
async PurchaseBarcodeDialog() { |
|||
var self = this; |
|||
var load_params = self.model.config; |
|||
var model = this.props.resModel |
|||
if(load_params.resId){ |
|||
var order_id = load_params.resId; |
|||
} |
|||
else{ |
|||
if(load_params.resIds[0]){ |
|||
var order_id = load_params.resIds[0]; |
|||
} |
|||
else{ |
|||
this.notificationService.add(_t("Create or Save Purchase Order to start barcode scan"), { |
|||
title: _t("Create/save Order"), |
|||
type: "danger", |
|||
}); |
|||
return |
|||
} |
|||
} |
|||
// Opens a Dialog box for scanning barcode
|
|||
const constraints = { |
|||
video: { facingMode: this.props.facingMode }, |
|||
audio: false, |
|||
}; |
|||
try { |
|||
this.dialog.add(BarcodeDialog, { |
|||
title: _t("Barcode Scanner"), |
|||
body: _t("An administrator needs to configure Google Synchronization before you can use it!"), |
|||
close: true, |
|||
order_id: order_id, |
|||
model: model, |
|||
}); |
|||
} catch (err) { |
|||
window.alert('Failed to detect webcam.Please ensure that your browser has the required permissions to access your webcam.') |
|||
} |
|||
} |
|||
} |
|||
ComPurchaseOrderRender.template = "barcode_capturing_sale_purchase.purchase_scanner"; |
@ -0,0 +1,11 @@ |
|||
/** @odoo-module **/ |
|||
import { formView } from '@web/views/form/form_view'; |
|||
import { FormController } from '@web/views/form/form_controller'; |
|||
import { registry } from "@web/core/registry"; |
|||
import { ComPurchaseOrderRender } from '@barcode_capturing_sale_purchase/js/purchase_barcode'; |
|||
//JsClassBarcodePurchase constant is added to views registry
|
|||
export const JsClassBarcodePurchase = { |
|||
...formView, |
|||
Controller: ComPurchaseOrderRender, |
|||
}; |
|||
registry.category("views").add("purchase_order_barcode", JsClassBarcodePurchase); |