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 00000000..823bb997 Binary files /dev/null and b/pos_customer_required/static/description/frontend_pos_error_message.png differ diff --git a/pos_customer_required/static/description/icon.png b/pos_customer_required/static/description/icon.png new file mode 100644 index 00000000..637d357b Binary files /dev/null and b/pos_customer_required/static/description/icon.png differ 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 @@ + + + + + +