From b594fd9c97a329f74732eb1f5f4aaf8575f73298 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Wed, 2 Nov 2016 17:47:34 +0100 Subject: [PATCH] [9.0] [PORT + IMP] pos_require_customer (#74) --- .travis.yml | 2 +- pos_customer_required/README.rst | 92 ++++++++++++++++++ pos_customer_required/__init__.py | 2 + pos_customer_required/__openerp__.py | 27 +++++ pos_customer_required/demo/pos_config.yml | 7 ++ pos_customer_required/i18n/fr.po | 71 ++++++++++++++ pos_customer_required/i18n/nl_NL.po | 72 ++++++++++++++ .../migrations/9.0.1.0.0/post-migration.py | 19 ++++ .../migrations/9.0.1.0.0/pre-migration.py | 18 ++++ pos_customer_required/models/__init__.py | 4 + pos_customer_required/models/pos_config.py | 26 +++++ .../models/pos_make_payment.py | 27 +++++ pos_customer_required/models/pos_order.py | 33 +++++++ .../frontend_pos_error_message.png | Bin 0 -> 6994 bytes .../static/description/icon.png | Bin 0 -> 4602 bytes .../static/src/js/pos_customer_required.js | 58 +++++++++++ .../static/src/xml/templates.xml | 20 ++++ pos_customer_required/tests/__init__.py | 2 + pos_customer_required/tests/test_pos.py | 38 ++++++++ .../views/pos_config_view.xml | 24 +++++ .../views/pos_order_view.xml | 27 +++++ 21 files changed, 568 insertions(+), 1 deletion(-) create mode 100644 pos_customer_required/README.rst create mode 100644 pos_customer_required/__init__.py create mode 100644 pos_customer_required/__openerp__.py create mode 100644 pos_customer_required/demo/pos_config.yml create mode 100644 pos_customer_required/i18n/fr.po create mode 100644 pos_customer_required/i18n/nl_NL.po create mode 100644 pos_customer_required/migrations/9.0.1.0.0/post-migration.py create mode 100644 pos_customer_required/migrations/9.0.1.0.0/pre-migration.py create mode 100644 pos_customer_required/models/__init__.py create mode 100644 pos_customer_required/models/pos_config.py create mode 100644 pos_customer_required/models/pos_make_payment.py create mode 100644 pos_customer_required/models/pos_order.py create mode 100644 pos_customer_required/static/description/frontend_pos_error_message.png create mode 100644 pos_customer_required/static/description/icon.png create mode 100644 pos_customer_required/static/src/js/pos_customer_required.js create mode 100644 pos_customer_required/static/src/xml/templates.xml create mode 100644 pos_customer_required/tests/__init__.py create mode 100644 pos_customer_required/tests/test_pos.py create mode 100644 pos_customer_required/views/pos_config_view.xml create mode 100644 pos_customer_required/views/pos_order_view.xml diff --git a/.travis.yml b/.travis.yml index bc7ac93b..76226d14 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ install: - export PATH=${HOME}/maintainer-quality-tools/travis:${PATH} - travis_install_nightly - printf '[options]\n\nrunning_env = dev' > ${HOME}/.openerp_serverrc - - pip install unidecode pyserial pycountry + - pip install unidecode pyserial pycountry openupgradelib script: - travis_run_tests diff --git a/pos_customer_required/README.rst b/pos_customer_required/README.rst new file mode 100644 index 00000000..f25be82c --- /dev/null +++ b/pos_customer_required/README.rst @@ -0,0 +1,92 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + + +================================= +Point Of Sale - Customer Required +================================= + +This module was written to extend the functionality of odoo pos +and allows you to require a customer for each pos order. In the +pos session configuration, you can choose to require the customer for pos +orders. + +If a customer is not selected, the pos ui will display an error message. +In the backend the customer field is required when needed. + +Two new options are available: + +* Customer 'Required before starting the order'; +* Customer 'Required before paying'; + +'Required before starting the order' Option +------------------------------------------- +In the frontend PoS, the default screen is the screen to select customers. + +* Users are not allowed to start selling before having selected a customer; +* Users can not 'deselect a customer', only select an other one; + +'Required before paying' Option +------------------------------- +In the frontend PoS, the user can start selling, but if the user tries to +make payment and if a customer is not selected, the pos ui will display an +error message. + + +.. image:: /pos_customer_required/static/description/frontend_pos_error_message.png + +Configuration +============= + +To configure this module, you need to: + +* go to point of sale -> configuration -> point of sales +* select the point of sales you want configure +* search for the "Require Customer" and choose between the following values: + * 'Optional'; (this module has no effect on this PoS config) + * 'Required before paying'; + * 'Required before starting the order'; + +Usage +===== + + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/184/9.0 + +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. + + +Credits +======= + +Contributors +------------ + +* Jos De Graeve +* Sylvain LE GAL +* Pedro M. Baeza ( reviews & feedback ) + + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +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. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/pos_customer_required/__init__.py b/pos_customer_required/__init__.py new file mode 100644 index 00000000..a0fdc10f --- /dev/null +++ b/pos_customer_required/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import models diff --git a/pos_customer_required/__openerp__.py b/pos_customer_required/__openerp__.py new file mode 100644 index 00000000..08a4140c --- /dev/null +++ b/pos_customer_required/__openerp__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2004-Today Apertoso NV () +# Copyright (C) 2016-Today: La Louve () +# @author: Jos DE GRAEVE () +# @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 Require Customer', + 'version': '9.0.1.0.0', + 'category': 'Point Of Sale', + 'summary': 'Point of Sale Require Customer', + 'author': 'Apertoso NV, La Louve, Odoo Community Association (OCA)', + 'website': 'http://www.apertoso.be', + 'depends': [ + 'point_of_sale', + ], + 'data': [ + 'static/src/xml/templates.xml', + 'views/pos_config_view.xml', + 'views/pos_order_view.xml', + ], + 'demo': [ + 'demo/pos_config.yml', + ], + 'installable': True, +} diff --git a/pos_customer_required/demo/pos_config.yml b/pos_customer_required/demo/pos_config.yml new file mode 100644 index 00000000..370b5b57 --- /dev/null +++ b/pos_customer_required/demo/pos_config.yml @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2016-Today: La Louve () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +- !record {model: pos.config, id: point_of_sale.pos_config_main}: + require_customer: order diff --git a/pos_customer_required/i18n/fr.po b/pos_customer_required/i18n/fr.po new file mode 100644 index 00000000..ae397b17 --- /dev/null +++ b/pos_customer_required/i18n/fr.po @@ -0,0 +1,71 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_customer_required +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-04-03 23:56+0000\n" +"PO-Revision-Date: 2016-04-03 23:56+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_customer_required +#: selection:pos.config,require_customer:0 +msgid "Optional" +msgstr "Facultatif" + +#. module: pos_customer_required +#: model:ir.model,name:pos_customer_required.model_pos_order +msgid "Point of Sale" +msgstr "Point de vente" + +#. module: pos_customer_required +#: model:ir.model,name:pos_customer_required.model_pos_make_payment +msgid "Point of Sale Payment" +msgstr "Paiement du ticket" + +#. module: pos_customer_required +#: model:ir.model.fields,field_description:pos_customer_required.field_pos_config_require_customer +msgid "Require Customer" +msgstr "Client requis" + +#. module: pos_customer_required +#: model:ir.model.fields,field_description:pos_customer_required.field_pos_order_require_customer +msgid "Require customer" +msgstr "Client requis" + +#. module: pos_customer_required +#: model:ir.model.fields,help:pos_customer_required.field_pos_config_require_customer +msgid "Require customer for orders in this point of sale:\n" +"* 'Optional' (customer is optional);* 'Required before paying';* 'Required before starting the order';" +msgstr "Client requis pour vendre dans le point de vente:\n" +"* 'Optional' (le client est facultatif);\n* 'Requis avant de payer';\n* 'Requis avant de commencer la vente';" + +#. module: pos_customer_required +#: selection:pos.config,require_customer:0 +msgid "Required before paying" +msgstr "Requis avant de payer" + +#. module: pos_customer_required +#: selection:pos.config,require_customer:0 +msgid "Required before starting the order" +msgstr "Requis avant de commencer la vente" + +#. module: pos_customer_required +#: model:ir.model.fields,help:pos_customer_required.field_pos_order_require_customer +msgid "True if a customer is required to begin the order.\n" +"See the PoS Config to change this setting" +msgstr "Vrai si un client est requis pour commencer une vente.\n" +"Voir la configuration du point de vente pour changer ce paramètre." + +#. module: pos_customer_required +#: model:ir.model,name:pos_customer_required.model_pos_config +msgid "pos.config" +msgstr "pos.config" + diff --git a/pos_customer_required/i18n/nl_NL.po b/pos_customer_required/i18n/nl_NL.po new file mode 100644 index 00000000..01acb513 --- /dev/null +++ b/pos_customer_required/i18n/nl_NL.po @@ -0,0 +1,72 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_customer_required +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-06-02 15:04+0100\n" +"PO-Revision-Date: 2015-06-02 15:04+0100\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"Language: nl_NL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.8\n" + +#. module: pos_customer_required +#. openerp-web +#: code:addons/pos_customer_required/static/src/js/pos_customer_required.js:16 +#, python-format +msgid "An anonymous order cannot be confirmed" +msgstr "Een anoniem kassa order kan niet worden bevestigd" + +#. module: pos_customer_required +#: view:pos.config:pos_customer_required.view_pos_config_form +msgid "Customer" +msgstr "Klant" + +#. module: pos_customer_required +#: code:addons/pos_customer_required/pos.py:45 +#, python-format +msgid "Customer is required for this order and is missing" +msgstr "Klant is vereist voor deze order en ontbreekt" + +#. module: pos_customer_required +#. openerp-web +#: code:addons/pos_customer_required/static/src/js/pos_customer_required.js:17 +#, python-format +msgid "" +"Please select a client for this order. This can be done by clicking the " +"order tab" +msgstr "" +"Selecteer een klant voor dit order. Dit kan gedaan worden door te klikken op " +"de tab bestelling" + +#. module: pos_customer_required +#: model:ir.model,name:pos_customer_required.model_pos_order +msgid "Point of Sale" +msgstr "Kassa" + +#. module: pos_customer_required +#: field:pos.config,require_customer:0 +msgid "Require customer" +msgstr "Klant verplichten" + +#. module: pos_customer_required +#: help:pos.config,require_customer:0 +msgid "Require customer for orders in this point of sale" +msgstr "Klant verplichten voor kassa orders in deze kassa." + +#. module: pos_customer_required +#: view:pos.order:pos_customer_required.view_pos_pos_form_inherit +msgid "" +"{'readonly': [('state','=','invoiced')], 'required': " +"[('require_customer','=',True)]}" +msgstr "" + +#~ msgid "Require customer for pos orders in the frontend" +#~ msgstr "Klant verplichten voor kassa orders in deze kassa." diff --git a/pos_customer_required/migrations/9.0.1.0.0/post-migration.py b/pos_customer_required/migrations/9.0.1.0.0/post-migration.py new file mode 100644 index 00000000..76208613 --- /dev/null +++ b/pos_customer_required/migrations/9.0.1.0.0/post-migration.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2016-Today: La Louve () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openupgradelib import openupgrade + + +BOOLEAN_TO_SELECTION = [ + ('false', 'no'), + ('true', 'order'), +] + + +@openupgrade.migrate() +def migrate(cr, installed_version): + openupgrade.map_values( + cr, openupgrade.get_legacy_name('require_customer'), + 'require_customer', BOOLEAN_TO_SELECTION, table='pos_config') diff --git a/pos_customer_required/migrations/9.0.1.0.0/pre-migration.py b/pos_customer_required/migrations/9.0.1.0.0/pre-migration.py new file mode 100644 index 00000000..7932ef97 --- /dev/null +++ b/pos_customer_required/migrations/9.0.1.0.0/pre-migration.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2016-Today: La Louve () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openupgradelib import openupgrade + + +column_renames = { + 'pos_config': [ + ('require_customer', None), + ] +} + + +@openupgrade.migrate() +def migrate(cr, version): + openupgrade.rename_columns(cr, column_renames) diff --git a/pos_customer_required/models/__init__.py b/pos_customer_required/models/__init__.py new file mode 100644 index 00000000..8dd7b1a7 --- /dev/null +++ b/pos_customer_required/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +from . import pos_config +from . import pos_order +from . import pos_make_payment diff --git a/pos_customer_required/models/pos_config.py b/pos_customer_required/models/pos_config.py new file mode 100644 index 00000000..38d6d30c --- /dev/null +++ b/pos_customer_required/models/pos_config.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2004-Today Apertoso NV () +# Copyright (C) 2016-Today: La Louve () +# @author: Jos DE GRAEVE () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp import fields, models + + +class PosConfig(models.Model): + _inherit = 'pos.config' + + _REQUIRE_CUSTOMER_KEYS = [ + ('no', 'Optional'), + ('payment', 'Required before paying'), + ('order', 'Required before starting the order'), + ] + + require_customer = fields.Selection( + selection=_REQUIRE_CUSTOMER_KEYS, + string='Require Customer', + help="Require customer for orders in this point of sale:\n" + "* 'Optional' (customer is optional);\n" + "* 'Required before paying';\n" + "* 'Required before starting the order';") diff --git a/pos_customer_required/models/pos_make_payment.py b/pos_customer_required/models/pos_make_payment.py new file mode 100644 index 00000000..358b21d5 --- /dev/null +++ b/pos_customer_required/models/pos_make_payment.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2016-Today: La Louve () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +from openerp import models, api, _ +from openerp.exceptions import UserError + + +class PosMakePayment(models.TransientModel): + _inherit = 'pos.make.payment' + + @api.multi + def check(self): + # Load current order + order_obj = self.env['pos.order'] + order = order_obj.browse(self.env.context.get('active_id', False)) + + # Check if control is required + if not order.partner_id\ + and order.session_id.config_id.require_customer != 'no': + raise UserError(_( + "An anonymous order cannot be confirmed.\n" + "Please select a customer for this order.")) + + return super(PosMakePayment, self).check() diff --git a/pos_customer_required/models/pos_order.py b/pos_customer_required/models/pos_order.py new file mode 100644 index 00000000..d61f2efe --- /dev/null +++ b/pos_customer_required/models/pos_order.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2004-Today Apertoso NV () +# Copyright (C) 2016-Today: La Louve () +# @author: Jos DE GRAEVE () +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp import fields, models, exceptions, api +from openerp.tools.translate import _ + + +class PosOrder(models.Model): + _inherit = 'pos.order' + + @api.multi + @api.depends('session_id.config_id.require_customer') + def compute_require_customer(self): + for order in self: + order.require_customer = ( + order.session_id.config_id.require_customer == 'order') + + require_customer = fields.Boolean( + compute='compute_require_customer', string='Require customer', + help="True if a customer is required to begin the order.\n" + "See the PoS Config to change this setting") + + @api.one + @api.constrains('partner_id', 'require_customer') + def _check_partner(self): + if (self.session_id.config_id.require_customer == 'order' and + not self.partner_id): + raise exceptions.ValidationError( + _('Customer is required for this order and is missing.')) diff --git a/pos_customer_required/static/description/frontend_pos_error_message.png b/pos_customer_required/static/description/frontend_pos_error_message.png new file mode 100644 index 0000000000000000000000000000000000000000..823bb997e3f34a3c706e0524ce35975503247f56 GIT binary patch literal 6994 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 V4Qb`yOZ^L=`_xdg`ib4U{{>yqjrsrp literal 0 HcmV?d00001 diff --git a/pos_customer_required/static/description/icon.png b/pos_customer_required/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..637d357b57b6bafdafc8798535a088a8371a35e1 GIT binary patch literal 4602 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 literal 0 HcmV?d00001 diff --git a/pos_customer_required/static/src/js/pos_customer_required.js b/pos_customer_required/static/src/js/pos_customer_required.js new file mode 100644 index 00000000..d873dec8 --- /dev/null +++ b/pos_customer_required/static/src/js/pos_customer_required.js @@ -0,0 +1,58 @@ +/* + Copyright (C) 2004-Today Apertoso NV () + Copyright (C) 2016-Today La Louve () + + @author: Jos DE GRAEVE () + @author: Sylvain LE GAL (https://twitter.com/legalsylvain) + + The licence is in the file __openerp__.py +*/ + + +odoo.define('pos_customer_required.pos_customer_required', function (require) { + "use strict"; + + var screens = require('point_of_sale.screens'); + var gui = require('point_of_sale.gui'); + var core = require('web.core'); + var _t = core._t; + + screens.PaymentScreenWidget.include({ + validate_order: function(options) { + if(this.pos.config.require_customer != 'no' + && !this.pos.get('selectedOrder').get_client()){ + this.gui.show_popup('error',{ + 'title': _t('An anonymous order cannot be confirmed'), + 'body': _t('Please select a customer for this order.'), + }); + return; + } + return this._super(options); + } + }); + + /* + Because of clientlist screen behaviour, it is not possible to simply + use: set_default_screen('clientlist') + remove cancel button on + customer screen. + + Instead of, + - we overload the function : show_screen(screen_name,params,refresh), + - and we replace the required screen by the 'clientlist' screen if the + current PoS Order has no Customer. + */ + + var _show_screen_ = gui.Gui.prototype.show_screen; + gui.Gui.prototype.show_screen = function(screen_name, params, refresh){ + if(this.pos.config.require_customer == 'order' + && !this.pos.get('selectedOrder').get_client() + && screen_name != 'clientlist'){ + // We call first the original screen, to avoid to break the + // 'previous screen' mecanism + _show_screen_.call(this, screen_name, params, refresh); + screen_name = 'clientlist'; + } + _show_screen_.call(this, screen_name, params, refresh); + }; + +}); diff --git a/pos_customer_required/static/src/xml/templates.xml b/pos_customer_required/static/src/xml/templates.xml new file mode 100644 index 00000000..ef1769f6 --- /dev/null +++ b/pos_customer_required/static/src/xml/templates.xml @@ -0,0 +1,20 @@ + + + + + +