From 35244756a4c51b197d5ef87a521e9b0036a6b238 Mon Sep 17 00:00:00 2001 From: Jose Zambudio Date: Thu, 13 Apr 2023 11:44:55 +0200 Subject: [PATCH] [IMP] pos_order_mgmt: black, isort, prettier --- pos_order_mgmt/README.rst | 16 +- pos_order_mgmt/__manifest__.py | 36 +- pos_order_mgmt/models/pos_config.py | 26 +- pos_order_mgmt/models/pos_order.py | 117 +++--- pos_order_mgmt/static/src/css/pos.css | 4 +- pos_order_mgmt/static/src/js/models.js | 6 +- pos_order_mgmt/static/src/js/widgets.js | 344 +++++++++--------- pos_order_mgmt/static/src/xml/pos.xml | 73 ++-- pos_order_mgmt/tests/test_module.py | 150 ++++---- pos_order_mgmt/views/assets.xml | 14 +- pos_order_mgmt/views/view_pos_config.xml | 41 ++- pos_order_mgmt/views/view_pos_order.xml | 19 +- .../pos_order_mgmt/odoo/addons/pos_order_mgmt | 1 + setup/pos_order_mgmt/setup.py | 6 + 14 files changed, 479 insertions(+), 374 deletions(-) create mode 120000 setup/pos_order_mgmt/odoo/addons/pos_order_mgmt create mode 100644 setup/pos_order_mgmt/setup.py diff --git a/pos_order_mgmt/README.rst b/pos_order_mgmt/README.rst index 8525e844bf..e4104a6a3d 100644 --- a/pos_order_mgmt/README.rst +++ b/pos_order_mgmt/README.rst @@ -14,13 +14,13 @@ POS Frontend Orders Management :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github - :target: https://github.com/OCA/pos/tree/12.0/pos_order_mgmt + :target: https://github.com/OCA/pos/tree/14.0/pos_order_mgmt :alt: OCA/pos .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/pos-12-0/pos-12-0-pos_order_mgmt + :target: https://translation.odoo-community.org/projects/pos-14.0/pos-14.0-pos_order_mgmt :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/184/12.0 + :target: https://runbot.odoo-community.org/runbot/184/14.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -40,7 +40,7 @@ Configuration To configure this module, you need to go to *Point of Sale > Configuration > Point of Sale* and enable *Order Management* -.. image:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_order_mgmt/static/description/order-mgmt-config.png +.. image:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_order_mgmt/static/description/order-mgmt-config.png #. Change *Maximum orders to load* to your desired amount (10 by default). Please note that the more you load, the more it will take to load @@ -62,13 +62,13 @@ Usage Once the PoS is loaded, you'll find a shopping trolley icon (🛒) in the top bar that grants access to the order list screen. -.. image:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_order_mgmt/static/description/order-mgmt-icon.png +.. image:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_order_mgmt/static/description/order-mgmt-icon.png There you can find the number of past orders loaded according to your configuration (see Configuration) as well as the orders you checked out in the current session: -.. image:: https://raw.githubusercontent.com/OCA/pos/12.0/pos_order_mgmt/static/description/order-mgmt-list.png +.. image:: https://raw.githubusercontent.com/OCA/pos/14.0/pos_order_mgmt/static/description/order-mgmt-list.png #. You can see their totals as well as their custumers if registered. #. You can reprint their tickets clicking on the printer icon (⎙). @@ -93,7 +93,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -129,6 +129,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/pos `_ project on GitHub. +This module is part of the `OCA/pos `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_order_mgmt/__manifest__.py b/pos_order_mgmt/__manifest__.py index fce48872bb..89c12f61be 100644 --- a/pos_order_mgmt/__manifest__.py +++ b/pos_order_mgmt/__manifest__.py @@ -3,26 +3,22 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { - 'name': 'POS Frontend Orders Management', - 'summary': 'Manage old POS Orders from the frontend', - 'version': '12.0.1.1.4', - 'category': 'Point of Sale', - 'author': 'GRAP, ' - 'Tecnativa, ' - 'Odoo Community Association (OCA)', - 'website': 'https://github.com/OCA/pos', - 'license': 'AGPL-3', - 'depends': [ - 'point_of_sale', + "name": "POS Frontend Orders Management", + "summary": "Manage old POS Orders from the frontend", + "version": "14.0.1.0.0", + "category": "Point of Sale", + "author": "GRAP, " "Tecnativa, " "Odoo Community Association (OCA)", + "website": "https://github.com/OCA/pos", + "license": "AGPL-3", + "depends": [ + "point_of_sale", ], - 'data': [ - 'views/assets.xml', - 'views/view_pos_config.xml', - 'views/view_pos_order.xml', + "data": [ + "views/assets.xml", + "views/view_pos_config.xml", + "views/view_pos_order.xml", ], - 'qweb': [ - 'static/src/xml/pos.xml' - ], - 'application': False, - 'installable': True, + "qweb": ["static/src/xml/pos.xml"], + "application": False, + "installable": True, } diff --git a/pos_order_mgmt/models/pos_config.py b/pos_order_mgmt/models/pos_config.py index 8f53d4be0d..43df1f28b2 100644 --- a/pos_order_mgmt/models/pos_config.py +++ b/pos_order_mgmt/models/pos_config.py @@ -9,37 +9,37 @@ class PosConfig(models.Model): - _inherit = 'pos.config' + _inherit = "pos.config" iface_order_mgmt = fields.Boolean( - string='Order Management', - help='Allows to manage orders in the frontend', + string="Order Management", + help="Allows to manage orders in the frontend", default=True, ) iface_reprint_done_order = fields.Boolean( - string='Reprint Orders', + string="Reprint Orders", default=True, - help='Allows to reprint already done orders in the frontend', + help="Allows to reprint already done orders in the frontend", ) iface_return_done_order = fields.Boolean( - string='Return Orders', + string="Return Orders", default=True, - help='Allows to return already done orders in the frontend', + help="Allows to return already done orders in the frontend", ) iface_copy_done_order = fields.Boolean( - string='Duplicate Orders', + string="Duplicate Orders", default=True, - help='Allows to duplicate already done orders in the frontend', + help="Allows to duplicate already done orders in the frontend", ) iface_load_done_order_max_qty = fields.Integer( - string='Maximum Orders to load', + string="Maximum Orders to load", default=10, required=True, - help='Maximum number of orders to load on the PoS at its init. ' - 'Set it to 0 to load none (it\'s still possible to load them by ' - 'ticket code).', + help="Maximum number of orders to load on the PoS at its init. " + "Set it to 0 to load none (it's still possible to load them by " + "ticket code).", ) diff --git a/pos_order_mgmt/models/pos_order.py b/pos_order_mgmt/models/pos_order.py index 078bd58b1b..031d8eec64 100644 --- a/pos_order_mgmt/models/pos_order.py +++ b/pos_order_mgmt/models/pos_order.py @@ -2,36 +2,37 @@ # Copyright 2018 Tecnativa S.L. - David Vidal # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import api, models, fields +from odoo import api, fields, models class PosOrder(models.Model): - _inherit = 'pos.order' + _inherit = "pos.order" returned_order_id = fields.Many2one( - comodel_name='pos.order', - string='Returned Order', + comodel_name="pos.order", + string="Returned Order", readonly=True, ) returned_order_reference = fields.Char( - related='returned_order_id.pos_reference', - string='Reference of the returned Order') + related="returned_order_id.pos_reference", + string="Reference of the returned Order", + ) refund_order_ids = fields.One2many( - comodel_name='pos.order', - inverse_name='returned_order_id', - string='Refund Orders', + comodel_name="pos.order", + inverse_name="returned_order_id", + string="Refund Orders", readonly=True, ) refund_order_qty = fields.Integer( - compute='_compute_refund_order_qty', - string='Refund Orders Quantity', + compute="_compute_refund_order_qty", + string="Refund Orders Quantity", ) @api.multi - @api.depends('refund_order_ids') + @api.depends("refund_order_ids") def _compute_refund_order_qty(self): for order in self: order.refund_order_qty = len(order.refund_order_ids) @@ -40,14 +41,15 @@ def _compute_refund_order_qty(self): def action_view_refund_orders(self): self.ensure_one() - action = self.env.ref('point_of_sale.action_pos_pos_form').read()[0] + action = self.env.ref("point_of_sale.action_pos_pos_form").read()[0] if self.refund_order_qty == 1: - action['views'] = [ - (self.env.ref('point_of_sale.view_pos_pos_form').id, 'form')] - action['res_id'] = self.refund_order_ids.ids[0] + action["views"] = [ + (self.env.ref("point_of_sale.view_pos_pos_form").id, "form") + ] + action["res_id"] = self.refund_order_ids.ids[0] else: - action['domain'] = [('id', 'in', self.refund_order_ids.ids)] + action["domain"] = [("id", "in", self.refund_order_ids.ids)] return action @api.multi @@ -55,51 +57,55 @@ def refund(self): return super(PosOrder, self.with_context(refund=True)).refund() @api.multi - @api.returns('self', lambda value: value.id) + @api.returns("self", lambda value: value.id) def copy(self, default=None): self.ensure_one() order = super().copy(default=default) - if self.env.context.get('refund', False): + if self.env.context.get("refund", False): order.returned_order_id = self.id return order @api.model def _prepare_filter_for_pos(self, pos_session_id): return [ - ('state', 'in', ['paid', 'done', 'invoiced']), + ("state", "in", ["paid", "done", "invoiced"]), ] @api.model def _prepare_filter_query_for_pos(self, pos_session_id, query): return [ - '|', '|', - ('name', 'ilike', query), - ('pos_reference', 'ilike', query), - ('partner_id.display_name', 'ilike', query), + "|", + "|", + ("name", "ilike", query), + ("pos_reference", "ilike", query), + ("partner_id.display_name", "ilike", query), ] @api.model def _prepare_fields_for_pos_list(self): return [ - 'name', 'pos_reference', 'partner_id', 'date_order', - 'amount_total', + "name", + "pos_reference", + "partner_id", + "date_order", + "amount_total", ] @api.model def search_done_orders_for_pos(self, query, pos_session_id): - session_obj = self.env['pos.session'] + session_obj = self.env["pos.session"] config = session_obj.browse(pos_session_id).config_id condition = self._prepare_filter_for_pos(pos_session_id) if not query: # Search only this POS orders - condition += [('config_id', '=', config.id)] + condition += [("config_id", "=", config.id)] else: # Search globally by criteria - condition += self._prepare_filter_query_for_pos( - pos_session_id, query) + condition += self._prepare_filter_query_for_pos(pos_session_id, query) field_names = self._prepare_fields_for_pos_list() return self.search_read( - condition, field_names, limit=config.iface_load_done_order_max_qty) + condition, field_names, limit=config.iface_load_done_order_max_qty + ) @api.multi def _prepare_done_order_for_pos(self): @@ -110,22 +116,21 @@ def _prepare_done_order_for_pos(self): order_line = self._prepare_done_order_line_for_pos(order_line) order_lines.append(order_line) for payment_line in self.statement_ids: - payment_line = self._prepare_done_order_payment_for_pos( - payment_line) + payment_line = self._prepare_done_order_payment_for_pos(payment_line) payment_lines.append(payment_line) res = { - 'id': self.id, - 'date_order': self.date_order, - 'pos_reference': self.pos_reference, - 'name': self.name, - 'partner_id': self.partner_id.id, - 'fiscal_position': self.fiscal_position_id.id, - 'pricelist_id': self.pricelist_id.id, - 'line_ids': order_lines, - 'statement_ids': payment_lines, - 'to_invoice': bool(self.invoice_id), - 'returned_order_id': self.returned_order_id.id, - 'returned_order_reference': self.returned_order_reference, + "id": self.id, + "date_order": self.date_order, + "pos_reference": self.pos_reference, + "name": self.name, + "partner_id": self.partner_id.id, + "fiscal_position": self.fiscal_position_id.id, + "pricelist_id": self.pricelist_id.id, + "line_ids": order_lines, + "statement_ids": payment_lines, + "to_invoice": bool(self.invoice_id), + "returned_order_id": self.returned_order_id.id, + "returned_order_reference": self.returned_order_reference, } return res @@ -133,19 +138,19 @@ def _prepare_done_order_for_pos(self): def _prepare_done_order_line_for_pos(self, order_line): self.ensure_one() return { - 'product_id': order_line.product_id.id, - 'qty': order_line.qty, - 'price_unit': order_line.price_unit, - 'discount': order_line.discount, - 'pack_lot_names': order_line.pack_lot_ids.mapped('lot_name'), + "product_id": order_line.product_id.id, + "qty": order_line.qty, + "price_unit": order_line.price_unit, + "discount": order_line.discount, + "pack_lot_names": order_line.pack_lot_ids.mapped("lot_name"), } @api.multi def _prepare_done_order_payment_for_pos(self, payment_line): self.ensure_one() return { - 'journal_id': payment_line.journal_id.id, - 'amount': payment_line.amount, + "journal_id": payment_line.journal_id.id, + "amount": payment_line.amount, } @api.multi @@ -156,7 +161,9 @@ def load_done_order_for_pos(self): @api.model def _order_fields(self, ui_order): res = super()._order_fields(ui_order) - res.update({ - 'returned_order_id': ui_order.get('returned_order_id', False), - }) + res.update( + { + "returned_order_id": ui_order.get("returned_order_id", False), + } + ) return res diff --git a/pos_order_mgmt/static/src/css/pos.css b/pos_order_mgmt/static/src/css/pos.css index b667a4511a..fb53ab19d0 100644 --- a/pos_order_mgmt/static/src/css/pos.css +++ b/pos_order_mgmt/static/src/css/pos.css @@ -26,11 +26,11 @@ color: white; } -.orderlist-screen table td[name='td_ol_amount_total'] { +.orderlist-screen table td[name="td_ol_amount_total"] { text-align: right; } /* Keep the table from breaking when the customer name is too long */ -.orderlist-screen table td:not([name='td_ol_customer']) { +.orderlist-screen table td:not([name="td_ol_customer"]) { white-space: nowrap; } diff --git a/pos_order_mgmt/static/src/js/models.js b/pos_order_mgmt/static/src/js/models.js index d57e845622..6e820d3c07 100644 --- a/pos_order_mgmt/static/src/js/models.js +++ b/pos_order_mgmt/static/src/js/models.js @@ -1,10 +1,10 @@ /* Copyright 2018 Tecnativa - David Vidal License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). */ -odoo.define('pos_order_mgmt.models', function (require) { - 'use strict'; +odoo.define("pos_order_mgmt.models", function (require) { + "use strict"; - var models = require('point_of_sale.models'); + var models = require("point_of_sale.models"); var order_super = models.Order.prototype; diff --git a/pos_order_mgmt/static/src/js/widgets.js b/pos_order_mgmt/static/src/js/widgets.js index 82637d5448..4b758ea1aa 100644 --- a/pos_order_mgmt/static/src/js/widgets.js +++ b/pos_order_mgmt/static/src/js/widgets.js @@ -3,16 +3,16 @@ Copyright 2019 Druidoo - Ivan Todorovich License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). */ -odoo.define('pos_order_mgmt.widgets', function (require) { +odoo.define("pos_order_mgmt.widgets", function (require) { "use strict"; - var core = require('web.core'); + var core = require("web.core"); var _t = core._t; - var PosBaseWidget = require('point_of_sale.BaseWidget'); - var screens = require('point_of_sale.screens'); - var gui = require('point_of_sale.gui'); - var chrome = require('point_of_sale.chrome'); - var models = require('point_of_sale.models'); + var PosBaseWidget = require("point_of_sale.BaseWidget"); + var screens = require("point_of_sale.screens"); + var gui = require("point_of_sale.gui"); + var chrome = require("point_of_sale.chrome"); + var models = require("point_of_sale.models"); var QWeb = core.qweb; var ScreenWidget = screens.ScreenWidget; @@ -24,14 +24,16 @@ odoo.define('pos_order_mgmt.widgets', function (require) { return this._super(); } var order = this.pos.reloaded_order; - this.$('.pos-receipt-container').html(QWeb.render('PosTicket', { - widget: this, - pos: this.pos, - order: order, - receipt: order.export_for_printing(), - orderlines: order.get_orderlines(), - paymentlines: order.get_paymentlines(), - })); + this.$(".pos-receipt-container").html( + QWeb.render("PosTicket", { + widget: this, + pos: this.pos, + order: order, + receipt: order.export_for_printing(), + orderlines: order.get_orderlines(), + paymentlines: order.get_paymentlines(), + }) + ); this.pos.from_loaded_order = true; }, click_next: function () { @@ -51,7 +53,7 @@ odoo.define('pos_order_mgmt.widgets', function (require) { }); var OrderListScreenWidget = ScreenWidget.extend({ - template: 'OrderListScreenWidget', + template: "OrderListScreenWidget", init: function (parent, options) { this._super(parent, options); @@ -68,28 +70,27 @@ odoo.define('pos_order_mgmt.widgets', function (require) { var self = this; var previous_screen = false; if (this.pos.get_order()) { - previous_screen = this.pos.get_order().get_screen_data( - 'previous-screen'); + previous_screen = this.pos + .get_order() + .get_screen_data("previous-screen"); } - if (previous_screen === 'receipt') { + if (previous_screen === "receipt") { this.gui.screen_instances.receipt.click_next(); - this.gui.show_screen('orderlist'); + this.gui.show_screen("orderlist"); } this._super(); this.renderElement(); this.old_order = this.pos.get_order(); - this.$('.back').click(function () { + this.$(".back").click(function () { return self.gui.show_screen(self.gui.startup_screen); }); - if (this.pos.config.iface_vkeyboard && - this.chrome.widget.keyboard) { - this.chrome.widget.keyboard.connect( - this.$('.searchbox input')); + if (this.pos.config.iface_vkeyboard && this.chrome.widget.keyboard) { + this.chrome.widget.keyboard.connect(this.$(".searchbox input")); } var search_timeout = null; - this.$('.searchbox input').on('keyup', function () { + this.$(".searchbox input").on("keyup", function () { self.search_query = this.value; clearTimeout(search_timeout); search_timeout = setTimeout(function () { @@ -97,7 +98,7 @@ odoo.define('pos_order_mgmt.widgets', function (require) { }, 70); }); - this.$('.searchbox .search-clear').click(function () { + this.$(".searchbox .search-clear").click(function () { self.clear_search(); }); @@ -107,55 +108,52 @@ odoo.define('pos_order_mgmt.widgets', function (require) { render_list: function () { var self = this; var orders = this.orders; - var contents = this.$el[0].querySelector('.order-list-contents'); + var contents = this.$el[0].querySelector(".order-list-contents"); contents.innerHTML = ""; - for ( - var i = 0, len = Math.min(orders.length, 1000); i < len; i++ - ) { + for (var i = 0, len = Math.min(orders.length, 1000); i < len; i++) { var order = orders[i]; - var orderline = this.order_cache.get_node( - order.id || order.uid); + var orderline = this.order_cache.get_node(order.id || order.uid); if (!orderline) { - var orderline_html = QWeb.render('OrderLine', { + var orderline_html = QWeb.render("OrderLine", { widget: this, order: order, }); - orderline = document.createElement('tbody'); + orderline = document.createElement("tbody"); orderline.innerHTML = orderline_html; orderline = orderline.childNodes[1]; - this.order_cache.cache_node( - order.id || order.uid, orderline); + this.order_cache.cache_node(order.id || order.uid, orderline); } if (order === this.old_order) { - orderline.classList.add('highlight'); + orderline.classList.add("highlight"); } else { - orderline.classList.remove('highlight'); + orderline.classList.remove("highlight"); } contents.appendChild(orderline); } // FIXME: Everytime the list is rendered we need to reassing the // button events. - this.$('.order-list-return').off('click'); - this.$('.order-list-reprint').off('click'); - this.$('.order-list-copy').off('click'); - this.$('.order-list-reprint').click(function (event) { - self.order_list_actions(event, 'print'); + this.$(".order-list-return").off("click"); + this.$(".order-list-reprint").off("click"); + this.$(".order-list-copy").off("click"); + this.$(".order-list-reprint").click(function (event) { + self.order_list_actions(event, "print"); }); - this.$('.order-list-copy').click(function (event) { - self.order_list_actions(event, 'copy'); + this.$(".order-list-copy").click(function (event) { + self.order_list_actions(event, "copy"); }); - this.$('.order-list-return').click(function (event) { - self.order_list_actions(event, 'return'); + this.$(".order-list-return").click(function (event) { + self.order_list_actions(event, "return"); }); }, order_list_actions: function (event, action) { var self = this; var dataset = event.target.parentNode.dataset; - self.load_order_data(parseInt(dataset.orderId, 10)) - .then(function (order_data) { - self.order_action(order_data, action); - }); + self.load_order_data(parseInt(dataset.orderId, 10)).then(function ( + order_data + ) { + self.order_action(order_data, action); + }); }, order_action: function (order_data, action) { @@ -168,7 +166,7 @@ odoo.define('pos_order_mgmt.widgets', function (require) { // We cancel the action return; } - this['action_' + action](order_data, order); + this["action_" + action](order_data, order); }, action_print: function (order_data, order) { @@ -182,16 +180,16 @@ odoo.define('pos_order_mgmt.widgets', function (require) { var skip_screen_state = this.pos.config.iface_print_skip_screen; // Disable temporarily skip screen if set this.pos.config.iface_print_skip_screen = false; - this.gui.show_screen('receipt'); + this.gui.show_screen("receipt"); this.pos.reloaded_order = false; // Set skip screen to whatever previous state this.pos.config.iface_print_skip_screen = skip_screen_state; // If it's invoiced, we also print the invoice if (order_data.to_invoice) { - this.pos.chrome.do_action('point_of_sale.pos_invoice_report', { - additional_context: { active_ids: [order_data.id] } - }) + this.pos.chrome.do_action("point_of_sale.pos_invoice_report", { + additional_context: {active_ids: [order_data.id]}, + }); } // Destroy the order so it's removed from localStorage @@ -200,36 +198,38 @@ odoo.define('pos_order_mgmt.widgets', function (require) { }, action_copy: function (order_data, order) { - order.trigger('change'); - this.pos.get('orders').add(order); - this.pos.set('selectedOrder', order); + order.trigger("change"); + this.pos.get("orders").add(order); + this.pos.set("selectedOrder", order); return order; }, action_return: function (order_data, order) { - order.trigger('change'); - this.pos.get('orders').add(order); - this.pos.set('selectedOrder', order); + order.trigger("change"); + this.pos.get("orders").add(order); + this.pos.set("selectedOrder", order); return order; }, _prepare_order_from_order_data: function (order_data, action) { var self = this; - var order = new models.Order({}, { - pos: this.pos, - }); + var order = new models.Order( + {}, + { + pos: this.pos, + } + ); // Get Customer if (order_data.partner_id) { - order.set_client( - this.pos.db.get_partner_by_id(order_data.partner_id)); + order.set_client(this.pos.db.get_partner_by_id(order_data.partner_id)); } // Get pricelist, if it is available in the current Point of Sale order.set_pricelist( - _.findWhere( - this.pos.pricelists, {'id': order_data.pricelist_id} - ) || this.pos.default_pricelist); + _.findWhere(this.pos.pricelists, {id: order_data.pricelist_id}) || + this.pos.default_pricelist + ); // Get fiscal position if (order_data.fiscal_position && this.pos.fiscal_positions) { @@ -237,45 +237,44 @@ odoo.define('pos_order_mgmt.widgets', function (require) { order.fiscal_position = fiscal_positions.filter(function (p) { return p.id === order_data.fiscal_position; })[0]; - order.trigger('change'); + order.trigger("change"); } // Get order lines - self._prepare_orderlines_from_order_data( - order, order_data, action); + self._prepare_orderlines_from_order_data(order, order_data, action); // Get Name - if (['print'].indexOf(action) !== -1) { + if (["print"].indexOf(action) !== -1) { order.name = order_data.pos_reference; - } else if (['return'].indexOf(action) !== -1) { + } else if (["return"].indexOf(action) !== -1) { order.name = _t("Refund ") + order.uid; } // Get to invoice - if (['return', 'copy'].indexOf(action) !== -1) { + if (["return", "copy"].indexOf(action) !== -1) { // If previous order was invoiced, we need a refund too order.set_to_invoice(order_data.to_invoice); } // Get returned Order - if (['print'].indexOf(action) !== -1) { + if (["print"].indexOf(action) !== -1) { // Get the same value as the original order.returned_order_id = order_data.returned_order_id; - order.returned_order_reference = - order_data.returned_order_reference; - } else if (['return'].indexOf(action) !== -1) { + order.returned_order_reference = order_data.returned_order_reference; + } else if (["return"].indexOf(action) !== -1) { order.returned_order_id = order_data.id; order.returned_order_reference = order_data.pos_reference; } // Get Date - if (['print'].indexOf(action) !== -1) { - order.formatted_validation_date = - moment(order_data.date_order).format('YYYY-MM-DD HH:mm:ss'); + if (["print"].indexOf(action) !== -1) { + order.formatted_validation_date = moment(order_data.date_order).format( + "YYYY-MM-DD HH:mm:ss" + ); } // Get Payment lines - if (['print'].indexOf(action) !== -1) { + if (["print"].indexOf(action) !== -1) { var paymentLines = order_data.statement_ids || []; _.each(paymentLines, function (paymentLine) { var line = paymentLine; @@ -288,8 +287,7 @@ odoo.define('pos_order_mgmt.widgets', function (require) { if (line.amount > 0) { // If it is not change order.add_paymentline(cashregister); - order.selected_paymentline.set_amount( - line.amount); + order.selected_paymentline.set_amount(line.amount); } } }); @@ -298,8 +296,7 @@ odoo.define('pos_order_mgmt.widgets', function (require) { return order; }, - _prepare_orderlines_from_order_data: function ( - order, order_data, action) { + _prepare_orderlines_from_order_data: function (order, order_data, action) { var orderLines = order_data.line_ids || order_data.lines || []; var self = this; @@ -315,30 +312,38 @@ odoo.define('pos_order_mgmt.widgets', function (require) { self.unknown_products.push(String(line.product_id)); } else { // Create a new order line - order.add_product(product, + order.add_product( + product, self._prepare_product_options_from_orderline_data( - order, line, action)); + order, + line, + action + ) + ); // Restore lot information. - if (['return'].indexOf(action) !== -1) { - var orderline = order.get_selected_orderline() + if (["return"].indexOf(action) !== -1) { + var orderline = order.get_selected_orderline(); if (orderline.pack_lot_lines) { - _.each(orderline.return_pack_lot_names, function(lot_name) { - orderline.pack_lot_lines.add(new models.Packlotline( - {'lot_name': lot_name}, {'order_line': orderline} - )); - }) - orderline.trigger('change', orderline); + _.each(orderline.return_pack_lot_names, function ( + lot_name + ) { + orderline.pack_lot_lines.add( + new models.Packlotline( + {lot_name: lot_name}, + {order_line: orderline} + ) + ); + }); + orderline.trigger("change", orderline); } } } }); }, - _prepare_product_options_from_orderline_data: function ( - order, line, action) { - + _prepare_product_options_from_orderline_data: function (order, line, action) { var qty = line.qty; - if (['return'].indexOf(action) !== -1) { + if (["return"].indexOf(action) !== -1) { // Invert line quantities qty *= -1; } @@ -350,30 +355,29 @@ odoo.define('pos_order_mgmt.widgets', function (require) { extras: { return_pack_lot_names: line.pack_lot_names, }, - } - + }; }, load_order_data: function (order_id) { var self = this; return this._rpc({ - model: 'pos.order', - method: 'load_done_order_for_pos', + model: "pos.order", + method: "load_done_order_for_pos", args: [order_id], }).fail(function (error) { if (parseInt(error.code, 10) === 200) { // Business Logic Error, not a connection problem - self.gui.show_popup( - 'error-traceback', { - 'title': error.data.message, - 'body': error.data.debug, - }); + self.gui.show_popup("error-traceback", { + title: error.data.message, + body: error.data.debug, + }); } else { - self.gui.show_popup('error', { - 'title': _t('Connection error'), - 'body': _t( - 'Can not execute this action because the POS' + - ' is currently offline'), + self.gui.show_popup("error", { + title: _t("Connection error"), + body: _t( + "Can not execute this action because the POS" + + " is currently offline" + ), }); } }); @@ -382,16 +386,17 @@ odoo.define('pos_order_mgmt.widgets', function (require) { load_order_from_data: function (order_data, action) { var self = this; this.unknown_products = []; - var order = self._prepare_order_from_order_data( - order_data, action); + var order = self._prepare_order_from_order_data(order_data, action); // Forbid POS Order loading if some products are unknown if (self.unknown_products.length > 0) { - self.gui.show_popup('error-traceback', { - 'title': _t('Unknown Products'), - 'body': _t('Unable to load some order lines because the ' + - 'products are not available in the POS cache.\n\n' + - 'Please check that lines :\n\n * ') + - self.unknown_products.join("; \n *"), + self.gui.show_popup("error-traceback", { + title: _t("Unknown Products"), + body: + _t( + "Unable to load some order lines because the " + + "products are not available in the POS cache.\n\n" + + "Please check that lines :\n\n * " + ) + self.unknown_products.join("; \n *"), }); return false; } @@ -402,63 +407,65 @@ odoo.define('pos_order_mgmt.widgets', function (require) { search_done_orders: function (query) { var self = this; return this._rpc({ - model: 'pos.order', - method: 'search_done_orders_for_pos', - args: [query || '', this.pos.pos_session.id], - }).then(function (result) { - self.orders = result; - // Get the date in local time - _.each(self.orders, function (order) { - if (order.date_order) { - order.date_order = moment.utc(order.date_order) - .local().format('YYYY-MM-DD HH:mm:ss'); - } - }); - }).fail(function (error, event) { - if (parseInt(error.code, 10) === 200) { - // Business Logic Error, not a connection problem - self.gui.show_popup( - 'error-traceback', { - 'title': error.data.message, - 'body': error.data.debug, + model: "pos.order", + method: "search_done_orders_for_pos", + args: [query || "", this.pos.pos_session.id], + }) + .then(function (result) { + self.orders = result; + // Get the date in local time + _.each(self.orders, function (order) { + if (order.date_order) { + order.date_order = moment + .utc(order.date_order) + .local() + .format("YYYY-MM-DD HH:mm:ss"); } - ); - } else { - self.gui.show_popup('error', { - 'title': _t('Connection error'), - 'body': _t( - 'Can not execute this action because the POS' + - ' is currently offline'), }); - } - event.preventDefault(); - }); + }) + .fail(function (error, event) { + if (parseInt(error.code, 10) === 200) { + // Business Logic Error, not a connection problem + self.gui.show_popup("error-traceback", { + title: error.data.message, + body: error.data.debug, + }); + } else { + self.gui.show_popup("error", { + title: _t("Connection error"), + body: _t( + "Can not execute this action because the POS" + + " is currently offline" + ), + }); + } + event.preventDefault(); + }); }, perform_search: function () { var self = this; - return this.search_done_orders(self.search_query) - .done(function () { - self.render_list(); - }); + return this.search_done_orders(self.search_query).done(function () { + self.render_list(); + }); }, clear_search: function () { var self = this; - self.$('.searchbox input')[0].value = ''; - self.$('.searchbox input').focus(); + self.$(".searchbox input")[0].value = ""; + self.$(".searchbox input").focus(); self.search_query = false; self.perform_search(); }, }); gui.define_screen({ - name: 'orderlist', + name: "orderlist", widget: OrderListScreenWidget, }); var ListOrderButtonWidget = PosBaseWidget.extend({ - template: 'ListOrderButtonWidget', + template: "ListOrderButtonWidget", init: function (parent, options) { var opts = options || {}; this._super(parent, opts); @@ -467,7 +474,7 @@ odoo.define('pos_order_mgmt.widgets', function (require) { }, button_click: function () { - this.gui.show_screen('orderlist'); + this.gui.show_screen("orderlist"); }, renderElement: function () { @@ -481,11 +488,11 @@ odoo.define('pos_order_mgmt.widgets', function (require) { var widgets = chrome.Chrome.prototype.widgets; widgets.push({ - 'name': 'list_orders', - 'widget': ListOrderButtonWidget, - 'prepend': '.pos-rightheader', - 'args': { - 'label': 'All Orders', + name: "list_orders", + widget: ListOrderButtonWidget, + prepend: ".pos-rightheader", + args: { + label: "All Orders", }, }); @@ -493,5 +500,4 @@ odoo.define('pos_order_mgmt.widgets', function (require) { ListOrderButtonWidget: ListOrderButtonWidget, OrderListScreenWidget: OrderListScreenWidget, }; - }); diff --git a/pos_order_mgmt/static/src/xml/pos.xml b/pos_order_mgmt/static/src/xml/pos.xml index a497513065..b278e7fc9d 100644 --- a/pos_order_mgmt/static/src/xml/pos.xml +++ b/pos_order_mgmt/static/src/xml/pos.xml @@ -1,10 +1,10 @@ - +
- +
@@ -14,27 +14,29 @@
- + Back - + - +
-
+
- @@ -53,16 +55,40 @@ - - + @@ -73,7 +99,10 @@
- Returned order: + Returned order:
@@ -83,15 +112,17 @@ -
- Rectifies: +
+ Rectifies:
-
+
DUPLICATE
-
+
@@ -100,7 +131,7 @@
DUPLICATE
-
+
diff --git a/pos_order_mgmt/tests/test_module.py b/pos_order_mgmt/tests/test_module.py index aeeea58059..58a1555482 100644 --- a/pos_order_mgmt/tests/test_module.py +++ b/pos_order_mgmt/tests/test_module.py @@ -7,89 +7,117 @@ class TestModule(TransactionCase): - def setUp(self): super(TestModule, self).setUp() # Get Registry - self.PosOrder = self.env['pos.order'] - self.AccountPayment = self.env['account.payment'] + self.PosOrder = self.env["pos.order"] + self.AccountPayment = self.env["account.payment"] # Get Object - self.pos_product = self.env["product.product"].create({ - "name": "Test POS Product", - }) - self.pricelist = self.env["product.pricelist"].create({ - "name": "Test pricelist", - "currency_id": self.env.user.company_id.currency_id.id, - "item_ids": [(0, 0, { - "applied_on": "3_global", - "compute_price": "formula", - "base": "list_price", - })] - }) - self.partner = self.env["res.partner"].create({ - "name": "Mr. Odoo", - "property_product_pricelist": self.pricelist.id, - }) + self.pos_product = self.env["product.product"].create( + { + "name": "Test POS Product", + } + ) + self.pricelist = self.env["product.pricelist"].create( + { + "name": "Test pricelist", + "currency_id": self.env.user.company_id.currency_id.id, + "item_ids": [ + ( + 0, + 0, + { + "applied_on": "3_global", + "compute_price": "formula", + "base": "list_price", + }, + ) + ], + } + ) + self.partner = self.env["res.partner"].create( + { + "name": "Mr. Odoo", + "property_product_pricelist": self.pricelist.id, + } + ) # Create a new pos config and open it - self.pos_config = self.env.ref('point_of_sale.pos_config_main').copy({ - 'available_pricelist_ids': [(6, 0, self.pricelist.ids)], - 'pricelist_id': self.pricelist.id, - }) + self.pos_config = self.env.ref("point_of_sale.pos_config_main").copy( + { + "available_pricelist_ids": [(6, 0, self.pricelist.ids)], + "pricelist_id": self.pricelist.id, + } + ) self.pos_config.open_session_cb() # Test Section def test_load_order(self): order = self._create_order() orders_data = self.PosOrder.search_done_orders_for_pos( - [], self.pos_config.current_session_id.id) + [], self.pos_config.current_session_id.id + ) self.assertEqual(len(orders_data), 1) - self.assertEqual( - orders_data[0]['id'], order.id) + self.assertEqual(orders_data[0]["id"], order.id) detail_data = order.load_done_order_for_pos() self.assertEqual( - len(detail_data.get('line_ids', [])), 1, - "Loading order detail failed") + len(detail_data.get("line_ids", [])), 1, "Loading order detail failed" + ) def _create_order(self): # Create order order_data = { - 'id': u'0006-001-0010', - 'to_invoice': True, - 'data': { - 'pricelist_id': self.pricelist.id, - 'user_id': 1, - 'name': 'Order 0006-001-0010', - 'partner_id': self.partner.id, - 'amount_paid': 0.9, - 'pos_session_id': self.pos_config.current_session_id.id, - 'lines': [[0, 0, { - 'product_id': self.pos_product.id, - 'price_unit': 0.9, - 'qty': 1, - 'price_subtotal': 0.9, - 'price_subtotal_incl': 0.9, - }]], - 'statement_ids': [[0, 0, { - 'journal_id': self.pos_config.journal_ids[0].id, - 'amount': 0.9, - 'name': fields.Datetime.now(), - 'account_id': - self.env.user.partner_id.property_account_receivable_id.id, - 'statement_id': - self.pos_config.current_session_id.statement_ids[0].id, - }]], - 'creation_date': u'2018-09-27 15:51:03', - 'amount_tax': 0, - 'fiscal_position_id': False, - 'uid': u'00001-001-0001', - 'amount_return': 0, - 'sequence_number': 1, - 'amount_total': 0.9, - }} + "id": "0006-001-0010", + "to_invoice": True, + "data": { + "pricelist_id": self.pricelist.id, + "user_id": 1, + "name": "Order 0006-001-0010", + "partner_id": self.partner.id, + "amount_paid": 0.9, + "pos_session_id": self.pos_config.current_session_id.id, + "lines": [ + [ + 0, + 0, + { + "product_id": self.pos_product.id, + "price_unit": 0.9, + "qty": 1, + "price_subtotal": 0.9, + "price_subtotal_incl": 0.9, + }, + ] + ], + "statement_ids": [ + [ + 0, + 0, + { + "journal_id": self.pos_config.journal_ids[0].id, + "amount": 0.9, + "name": fields.Datetime.now(), + "account_id": ( + self.env.user.partner_id.property_account_receivable_id.id + ), + "statement_id": self.pos_config.current_session_id.statement_ids[ + 0 + ].id, + }, + ] + ], + "creation_date": "2018-09-27 15:51:03", + "amount_tax": 0, + "fiscal_position_id": False, + "uid": "00001-001-0001", + "amount_return": 0, + "sequence_number": 1, + "amount_total": 0.9, + }, + } result = self.PosOrder.create_from_ui([order_data]) order = self.PosOrder.browse(result[0]) diff --git a/pos_order_mgmt/views/assets.xml b/pos_order_mgmt/views/assets.xml index 126e81c3b4..d8c9089b22 100644 --- a/pos_order_mgmt/views/assets.xml +++ b/pos_order_mgmt/views/assets.xml @@ -1,11 +1,17 @@ - +
Ref. Customer Date Amount +
- - + + + - - + + - - + +