diff --git a/pos_odoo_driver_device_list/README.rst b/pos_odoo_driver_device_list/README.rst new file mode 100644 index 0000000..e69de29 diff --git a/pos_odoo_driver_device_list/__init__.py b/pos_odoo_driver_device_list/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/pos_odoo_driver_device_list/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/pos_odoo_driver_device_list/__manifest__.py b/pos_odoo_driver_device_list/__manifest__.py new file mode 100644 index 0000000..efded3e --- /dev/null +++ b/pos_odoo_driver_device_list/__manifest__.py @@ -0,0 +1,25 @@ +# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Point of Sale - Devices List (odoo-pos-driver)", + "version": "16.0.1.0.0", + "category": "Point Of Sale", + "summary": "Get devices information from odoo-pos-driver library", + "author": "GRAP", + "website": "https://github.com/grap/odoo-addons-pos", + "license": "AGPL-3", + "depends": ["point_of_sale"], + "assets": { + "point_of_sale.assets": [ + "pos_odoo_driver_device_list/static/src/js/devices.esm.js", + ], + }, + "data": [ + "security/ir.model.access.csv", + "security/ir_rule.xml", + "views/view_pos_device.xml", + ], + "installable": True, +} diff --git a/pos_odoo_driver_device_list/i18n/fr.po b/pos_odoo_driver_device_list/i18n/fr.po new file mode 100644 index 0000000..6180a5a --- /dev/null +++ b/pos_odoo_driver_device_list/i18n/fr.po @@ -0,0 +1,141 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_odoo_driver_device_list +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-09-14 13:15+0000\n" +"PO-Revision-Date: 2024-09-14 13:15+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__company_id +msgid "Company" +msgstr "Société" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__config_id +msgid "Config" +msgstr "Point de vente" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__create_date +msgid "Created on" +msgstr "Créé le" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields.selection,name:pos_odoo_driver_device_list.selection__pos_device__device_type__display +msgid "Customer Display" +msgstr "Afficheur client" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_config__device_ids +msgid "Device" +msgstr "Périphérique" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__device_type +msgid "Device Type" +msgstr "Type de périphérique" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__display_name +msgid "Display Name" +msgstr "Nom complet" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__id +msgid "ID" +msgstr "" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__last_connexion_date +msgid "Last Connexion Date" +msgstr "Date de dernière connexion" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device____last_update +msgid "Last Modified on" +msgstr "Dernière mise à jour le" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__write_uid +msgid "Last Updated by" +msgstr "Dernière mise à jour par" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__write_date +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__manufacturer +msgid "Manufacturer" +msgstr "" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__name +msgid "Name" +msgstr "" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields.selection,name:pos_odoo_driver_device_list.selection__pos_device__device_type__payment +msgid "Payment Terminal" +msgstr "" + +#. module: pos_odoo_driver_device_list +#: model:ir.ui.menu,name:pos_odoo_driver_device_list.menu_pos_device +msgid "PoS Devices" +msgstr "" + +#. module: pos_odoo_driver_device_list +#: model:ir.model,name:pos_odoo_driver_device_list.model_pos_config +msgid "Point of Sale Configuration" +msgstr "Configuration du point de vente" + +#. module: pos_odoo_driver_device_list +#: model:ir.model,name:pos_odoo_driver_device_list.model_pos_device +msgid "Point of Sale Devices" +msgstr "" + +#. module: pos_odoo_driver_device_list +#: model:ir.actions.act_window,name:pos_odoo_driver_device_list.action_pos_device +msgid "Pos Devices" +msgstr "" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields.selection,name:pos_odoo_driver_device_list.selection__pos_device__device_type__printer +msgid "Printer" +msgstr "" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__product_name +msgid "Product Name" +msgstr "" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields.selection,name:pos_odoo_driver_device_list.selection__pos_device__device_type__scale +msgid "Scale" +msgstr "" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__serial_number +msgid "Serial Number" +msgstr "" + +#. module: pos_odoo_driver_device_list +#: model:ir.model.fields,field_description:pos_odoo_driver_device_list.field_pos_device__vendor_product_code +msgid "Vendor Product Code" +msgstr "" diff --git a/pos_odoo_driver_device_list/models/__init__.py b/pos_odoo_driver_device_list/models/__init__.py new file mode 100644 index 0000000..9044dab --- /dev/null +++ b/pos_odoo_driver_device_list/models/__init__.py @@ -0,0 +1,2 @@ +from . import pos_config +from . import pos_device diff --git a/pos_odoo_driver_device_list/models/pos_config.py b/pos_odoo_driver_device_list/models/pos_config.py new file mode 100644 index 0000000..e115bd0 --- /dev/null +++ b/pos_odoo_driver_device_list/models/pos_config.py @@ -0,0 +1,53 @@ +# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from datetime import datetime + +from odoo import api, fields, models + + +class PosConfig(models.Model): + _inherit = "pos.config" + + device_ids = fields.One2many(comodel_name="pos.device", inverse_name="config_id") + + @api.model + def update_pos_device(self, config_id, changes): + PosDevice = self.env["pos.device"] + for device_type, device_info in changes.items(): + existing_device = PosDevice.search( + [ + ("config_id", "=", config_id), + ("device_type", "=", device_type), + ("name", "=", device_info.get("device_name", False)), + ("product_name", "=", device_info.get("product_name", False)), + ("manufacturer", "=", device_info.get("manufacturer", False)), + ("serial_number", "=", device_info.get("serial_number", False)), + ( + "vendor_product_code", + "=", + device_info.get("vendor_product_code", False), + ), + ], + limit=1, + order="last_connexion_date desc", + ) + if existing_device: + existing_device.write({"last_connexion_date": datetime.now()}) + else: + PosDevice.create( + { + "config_id": config_id, + "device_type": device_type, + "name": device_info.get("device_name", False), + "product_name": device_info.get("product_name", False), + "manufacturer": device_info.get("manufacturer", False), + "serial_number": device_info.get("serial_number", False), + "vendor_product_code": device_info.get( + "vendor_product_code", False + ), + "last_connexion_date": datetime.now(), + } + ) + return True diff --git a/pos_odoo_driver_device_list/models/pos_device.py b/pos_odoo_driver_device_list/models/pos_device.py new file mode 100644 index 0000000..43b0243 --- /dev/null +++ b/pos_odoo_driver_device_list/models/pos_device.py @@ -0,0 +1,39 @@ +# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class PosDevice(models.Model): + _name = "pos.device" + _description = "Point of Sale Devices" + _order = "last_connexion_date desc, name" + + device_type = fields.Selection( + selection=[ + ("display", "Customer Display"), + ("payment", "Payment Terminal"), + ("scale", "Scale"), + ("printer", "Printer"), + ] + ) + + config_id = fields.Many2one(comodel_name="pos.config") + + company_id = fields.Many2one(related="config_id.company_id") + + name = fields.Char(readonly=True) + + product_name = fields.Char(readonly=True) + + vendor_product_code = fields.Char(readonly=True) + + serial_number = fields.Char(readonly=True) + + manufacturer = fields.Char(readonly=True) + + last_connexion_date = fields.Datetime(readonly=True) + + def _default_company_id(self): + return self.env.company diff --git a/pos_odoo_driver_device_list/readme/CONTRIBUTORS.rst b/pos_odoo_driver_device_list/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..ae6f43a --- /dev/null +++ b/pos_odoo_driver_device_list/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Sylvain LE GAL (https://twitter.com/legalsylvain) diff --git a/pos_odoo_driver_device_list/readme/DESCRIPTION.rst b/pos_odoo_driver_device_list/readme/DESCRIPTION.rst new file mode 100644 index 0000000..bc4d21a --- /dev/null +++ b/pos_odoo_driver_device_list/readme/DESCRIPTION.rst @@ -0,0 +1,4 @@ +This module extends the Point of Sale odoo module, to add compatibility +with the ``odoo-pos-driver`` python library. + +It will store connected devices information in Odoo for analysis. diff --git a/pos_odoo_driver_device_list/readme/USAGE.rst b/pos_odoo_driver_device_list/readme/USAGE.rst new file mode 100644 index 0000000..2104a27 --- /dev/null +++ b/pos_odoo_driver_device_list/readme/USAGE.rst @@ -0,0 +1,9 @@ +* Open the Point of sale, with usb devices connected. + +* Close the point of sale. + +* Go to " / Devices". + +you can see the devices information, with last usage date. + +.. figure:: ../static/img/pos_device_tree.png diff --git a/pos_odoo_driver_device_list/security/ir.model.access.csv b/pos_odoo_driver_device_list/security/ir.model.access.csv new file mode 100644 index 0000000..bc7e685 --- /dev/null +++ b/pos_odoo_driver_device_list/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_pos_device_user,access_pos_device_user,pos_odoo_driver_device_list.model_pos_device,point_of_sale.group_pos_user,1,1,1,0 +access_pos_device_manager,access_pos_device_manager,pos_odoo_driver_device_list.model_pos_device,base.group_system,1,1,1,1 diff --git a/pos_odoo_driver_device_list/security/ir_rule.xml b/pos_odoo_driver_device_list/security/ir_rule.xml new file mode 100644 index 0000000..b0a4acc --- /dev/null +++ b/pos_odoo_driver_device_list/security/ir_rule.xml @@ -0,0 +1,19 @@ + + + + + + PoS Device Rule + + + [('company_id', 'in', company_ids + [False])] + + + diff --git a/pos_odoo_driver_device_list/static/description/pos_device_tree.png b/pos_odoo_driver_device_list/static/description/pos_device_tree.png new file mode 100644 index 0000000..2ee31ce Binary files /dev/null and b/pos_odoo_driver_device_list/static/description/pos_device_tree.png differ diff --git a/pos_odoo_driver_device_list/static/src/js/devices.esm.js b/pos_odoo_driver_device_list/static/src/js/devices.esm.js new file mode 100644 index 0000000..b603c3b --- /dev/null +++ b/pos_odoo_driver_device_list/static/src/js/devices.esm.js @@ -0,0 +1,41 @@ +// Copyright (C) 2024 - Today: GRAP (http://www.grap.coop) +// @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +odoo.define("pos_odoo_driver_device_list.devices", function (require) { + + var ProxyDevice = require("point_of_sale.devices").ProxyDevice; + + var set_connection_status_super = ProxyDevice.prototype.set_connection_status; + + ProxyDevice.prototype.set_connection_status = function (status, drivers, msg='') { + if (status === 'connected' && drivers !== undefined) { + var old_drivers = this.get('status').drivers; + var changes = {}; + Object.entries(drivers).forEach(([driver_name, driver_value]) => { + if (driver_value.status === "connected") { + if (JSON.stringify(driver_value) !== JSON.stringify(old_drivers[driver_name])) { + changes[driver_name] = driver_value; + } + } + }) + if (Object.keys(changes).length !== 0) { + this.env.services.rpc({ + model: 'pos.config', + method: 'update_pos_device', + args: [this.env.pos.config.id, changes], + kwargs: {context: this.env.session.user_context}, + }, {}) + .then(function (result) { + console.log("THEN: ", result) + }).catch(function (error){ + console.warn('catch: ', error); + }); + + console.log("CHANGES: ", changes) + } + } + set_connection_status_super.call(this, status, drivers, msg); + }; + +}); diff --git a/pos_odoo_driver_device_list/views/view_pos_device.xml b/pos_odoo_driver_device_list/views/view_pos_device.xml new file mode 100644 index 0000000..84e73b7 --- /dev/null +++ b/pos_odoo_driver_device_list/views/view_pos_device.xml @@ -0,0 +1,39 @@ + + + + + + pos.device + + + + + + + + + + + + + + + + + Pos Devices + pos.device + tree + + + + PoS Devices + + + + + + diff --git a/setup/.setuptools-odoo-make-default-ignore b/setup/.setuptools-odoo-make-default-ignore new file mode 100644 index 0000000..207e615 --- /dev/null +++ b/setup/.setuptools-odoo-make-default-ignore @@ -0,0 +1,2 @@ +# addons listed in this file are ignored by +# setuptools-odoo-make-default (one addon per line) diff --git a/setup/README b/setup/README new file mode 100644 index 0000000..a63d633 --- /dev/null +++ b/setup/README @@ -0,0 +1,2 @@ +To learn more about this directory, please visit +https://pypi.python.org/pypi/setuptools-odoo diff --git a/setup/pos_odoo_driver_device_list/odoo/addons/pos_odoo_driver_device_list b/setup/pos_odoo_driver_device_list/odoo/addons/pos_odoo_driver_device_list new file mode 120000 index 0000000..0ddc385 --- /dev/null +++ b/setup/pos_odoo_driver_device_list/odoo/addons/pos_odoo_driver_device_list @@ -0,0 +1 @@ +../../../../pos_odoo_driver_device_list \ No newline at end of file diff --git a/setup/pos_odoo_driver_device_list/setup.py b/setup/pos_odoo_driver_device_list/setup.py new file mode 100644 index 0000000..28c57bb --- /dev/null +++ b/setup/pos_odoo_driver_device_list/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)