Browse Source

[9.0] [PORT + IMP] pos_require_customer (#74)

pull/132/head
Sylvain LE GAL 8 years ago
committed by Pedro M. Baeza
parent
commit
b594fd9c97
  1. 2
      .travis.yml
  2. 92
      pos_customer_required/README.rst
  3. 2
      pos_customer_required/__init__.py
  4. 27
      pos_customer_required/__openerp__.py
  5. 7
      pos_customer_required/demo/pos_config.yml
  6. 71
      pos_customer_required/i18n/fr.po
  7. 72
      pos_customer_required/i18n/nl_NL.po
  8. 19
      pos_customer_required/migrations/9.0.1.0.0/post-migration.py
  9. 18
      pos_customer_required/migrations/9.0.1.0.0/pre-migration.py
  10. 4
      pos_customer_required/models/__init__.py
  11. 26
      pos_customer_required/models/pos_config.py
  12. 27
      pos_customer_required/models/pos_make_payment.py
  13. 33
      pos_customer_required/models/pos_order.py
  14. BIN
      pos_customer_required/static/description/frontend_pos_error_message.png
  15. BIN
      pos_customer_required/static/description/icon.png
  16. 58
      pos_customer_required/static/src/js/pos_customer_required.js
  17. 20
      pos_customer_required/static/src/xml/templates.xml
  18. 2
      pos_customer_required/tests/__init__.py
  19. 38
      pos_customer_required/tests/test_pos.py
  20. 24
      pos_customer_required/views/pos_config_view.xml
  21. 27
      pos_customer_required/views/pos_order_view.xml

2
.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

92
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
<https://github.com/OCA/pos/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 <Jos.DeGraeve@apertoso.be>
* Sylvain LE GAL <https://twitter.com/legalsylvain>
* Pedro M. Baeza <pedro.baeza@gmail.com> ( 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.

2
pos_customer_required/__init__.py

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import models

27
pos_customer_required/__openerp__.py

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2004-Today Apertoso NV (<http://www.apertoso.be>)
# Copyright (C) 2016-Today: La Louve (<http://www.lalouve.net/>)
# @author: Jos DE GRAEVE (<Jos.DeGraeve@apertoso.be>)
# @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,
}

7
pos_customer_required/demo/pos_config.yml

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2016-Today: La Louve (<http://www.lalouve.net/>)
# @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

71
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"

72
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."

19
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 (<http://www.lalouve.net/>)
# @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')

18
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 (<http://www.lalouve.net/>)
# @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)

4
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

26
pos_customer_required/models/pos_config.py

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2004-Today Apertoso NV (<http://www.apertoso.be>)
# Copyright (C) 2016-Today: La Louve (<http://www.lalouve.net/>)
# @author: Jos DE GRAEVE (<Jos.DeGraeve@apertoso.be>)
# @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';")

27
pos_customer_required/models/pos_make_payment.py

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2016-Today: La Louve (<http://www.lalouve.net/>)
# @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()

33
pos_customer_required/models/pos_order.py

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2004-Today Apertoso NV (<http://www.apertoso.be>)
# Copyright (C) 2016-Today: La Louve (<http://www.lalouve.net/>)
# @author: Jos DE GRAEVE (<Jos.DeGraeve@apertoso.be>)
# @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.'))

BIN
pos_customer_required/static/description/frontend_pos_error_message.png

After

Width: 400  |  Height: 183  |  Size: 6.8 KiB

BIN
pos_customer_required/static/description/icon.png

After

Width: 96  |  Height: 96  |  Size: 4.5 KiB

58
pos_customer_required/static/src/js/pos_customer_required.js

@ -0,0 +1,58 @@
/*
Copyright (C) 2004-Today Apertoso NV (<http://www.apertoso.be>)
Copyright (C) 2016-Today La Louve (<http://www.lalouve.net/>)
@author: Jos DE GRAEVE (<Jos.DeGraeve@apertoso.be>)
@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);
};
});

20
pos_customer_required/static/src/xml/templates.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2004-Today Apertoso NV (<http://www.apertoso.be>)
Copyright (C) 2016-Today La Louve (<http://www.lalouve.net/>)
@author: Jos DE GRAEVE (<Jos.DeGraeve@apertoso.be>)
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<template id="assets_frontend" inherit_id="point_of_sale.assets">
<xpath expr="." position="inside">
<script type="text/javascript" src="/pos_customer_required/static/src/js/pos_customer_required.js"/>
</xpath>
</template>
</data>
</openerp>

2
pos_customer_required/tests/__init__.py

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import test_pos

38
pos_customer_required/tests/test_pos.py

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
import openerp.tests.common as common
from openerp import exceptions
class TestPosRequireCustomer(common.TransactionCase):
def setUp(self):
super(TestPosRequireCustomer, self).setUp()
def test_customer_not_required(self):
posconfig = self.env.ref('point_of_sale.pos_config_main')
posconfig.require_customer = 'no'
# Now Create new session and create a
# pos order in this session
pos_session = self.env['pos.session'].create(
{'config_id': posconfig.id})
# should not raise any exception
self.env['pos.order'].create({
'session_id': pos_session.id,
'partner_id': False,
})
def test_customer_is_required(self):
posconfig = self.env.ref('point_of_sale.pos_config_main')
posconfig.require_customer = 'order'
# Now Create new session and create a
# pos order in this session
pos_session = self.env['pos.session'].create(
{'config_id': posconfig.id})
# should raise exceptions.ValidationError
with self.assertRaises(exceptions.ValidationError):
self.env['pos.order'].create({
'session_id': pos_session.id,
'partner_id': False,
})

24
pos_customer_required/views/pos_config_view.xml

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<!--
Copyright (C) 2004-Today Apertoso NV (<http://www.apertoso.be>)
Copyright (C) 2016-Today La Louve (<http://www.lalouve.net/>)
@author: Jos DE GRAEVE (<Jos.DeGraeve@apertoso.be>)
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
The licence is in the file __openerp__.py
-->
<odoo>
<record model="ir.ui.view" id="view_pos_config_form">
<field name="model">pos.config</field>
<field name="inherit_id" ref="point_of_sale.view_pos_config_form" />
<field name="arch" type="xml">
<field name="iface_tax_included" position="after">
<field name="require_customer" />
</field>
</field>
</record>
</odoo>

27
pos_customer_required/views/pos_order_view.xml

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<!--
Copyright (C) 2004-Today Apertoso NV (<http://www.apertoso.be>)
Copyright (C) 2016-Today La Louve (<http://www.lalouve.net/>)
@author: Jos DE GRAEVE (<Jos.DeGraeve@apertoso.be>)
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
The licence is in the file __openerp__.py
-->
<odoo>
<record model="ir.ui.view" id="view_pos_order_form">
<field name="model">pos.order</field>
<field name="inherit_id" ref="point_of_sale.view_pos_pos_form"/>
<field name="arch" type="xml">
<xpath expr="//sheet" position="inside">
<field name="require_customer" invisible="1"/>
</xpath>
<xpath expr="//field[@name='partner_id']" position="attributes">
<attribute name="attrs">{'readonly': [('state','=','invoiced')], 'required': [('require_customer','=',True)]}</attribute>
</xpath>
</field>
</record>
</odoo>
Loading…
Cancel
Save