Browse Source

Merge pull request #14 from houssine78/9.0

add pos_access_right module from la louve
pull/15/head
Houssine BAKKALI 8 years ago
committed by GitHub
parent
commit
f7a8d406f2
  1. 106
      pos_access_right/README.rst
  2. 2
      pos_access_right/__init__.py
  3. BIN
      pos_access_right/__init__.pyc
  4. 25
      pos_access_right/__openerp__.py
  5. 26
      pos_access_right/demo/res_groups.yml
  6. 135
      pos_access_right/i18n/fr.po
  7. 2
      pos_access_right/models/__init__.py
  8. BIN
      pos_access_right/models/__init__.pyc
  9. 75
      pos_access_right/models/pos_config.py
  10. BIN
      pos_access_right/models/pos_config.pyc
  11. 25
      pos_access_right/security/res_groups.yml
  12. BIN
      pos_access_right/static/description/admin_numpad.png
  13. BIN
      pos_access_right/static/description/demo_error.png
  14. BIN
      pos_access_right/static/description/demo_numpad.png
  15. BIN
      pos_access_right/static/description/icon.png
  16. BIN
      pos_access_right/static/description/new_groups.png
  17. 13
      pos_access_right/static/src/css/pos_access_right.css
  18. 140
      pos_access_right/static/src/js/pos_access_right.js
  19. 17
      pos_access_right/static/src/xml/templates.xml

106
pos_access_right/README.rst

@ -0,0 +1,106 @@
.. 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 - Extra Access Right for Certain Actions
======================================================
This module extends Odoo Point Of Sale features, restricting possibility
to cashier to make some actions in the Point of Sale (set discount, change
unit prices, etc...)
this module can be usefull to limit errors and / or fraud.
This module will add the following groups to Odoo:
* PoS - Negative Quantity: The cashier can sell negative quantity in Point Of
Sale (ie, can return products);
* PoS - Discount: The cashier can set Discount in Point Of Sale;
* PoS - Change Unit Price: The cashier can change the unit price of a product
in Point Of Sale;
* PoS - Many Orders: The cashier can many orders at the same time;
* PoS - Delete Order: The cashier can not delete a full order;
.. image:: /pos_access_right/static/description/new_groups.png
If a user doesn't belong to a group, he can not use the according feature.
For example, here is the default numpad for the demo data user :
.. image:: /pos_access_right/static/description/demo_numpad.png
If the user try to use a forbidden feature, here is the warning displayed.
.. image:: /pos_access_right/static/description/demo_error.png
If the cashier changed, the new right are applied :
.. image:: /pos_access_right/static/description/admin_numpad.png
Installation
============
Normal installation.
Configuration
=============
Once installed, you have to give correct access right to your cashiers.
Limits / Roadmap
================
The feature are only blocked on the Point of sale Frond End UI. it could be
interesting do the same in the back-end office for some of this blockages.
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/{project_repo}/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
<https://github.com/OCA/
pos/issues/new?body=module:%20
pos_access_right%0Aversion:%20
9.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Images
------
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
Contributors
------------
* Sylvain LE GAL <https://twitter.com/legalsylvain>
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 https://odoo-community.org.

2
pos_access_right/__init__.py

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

BIN
pos_access_right/__init__.pyc

25
pos_access_right/__openerp__.py

@ -0,0 +1,25 @@
# -*- 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).
{
'name': 'Point of Sale - Extra Access Right',
'version': '9.0.1.0.0',
'category': 'Point Of Sale',
'summary': 'Point of Sale - Extra Access Right for certain actions',
'author': 'La Louve, GRAP, Odoo Community Association (OCA)',
'website': 'http://www.lalouve.net/',
'license': 'AGPL-3',
'depends': [
'point_of_sale',
],
'data': [
'security/res_groups.yml',
'static/src/xml/templates.xml',
],
'demo': [
'demo/res_groups.yml',
],
'installable': True,
}

26
pos_access_right/demo/res_groups.yml

@ -0,0 +1,26 @@
# -*- 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: res.groups, id: group_negative_qty}:
users:
- base.user_root
- !record {model: res.groups, id: group_discount}:
users:
- base.user_root
- base.user_demo
- !record {model: res.groups, id: group_change_unit_price}:
users:
- base.user_root
- !record {model: res.groups, id: group_multi_order}:
users:
- base.user_root
- !record {model: res.groups, id: group_delete_order}:
users:
- base.user_root

135
pos_access_right/i18n/fr.po

@ -0,0 +1,135 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_access_right
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-11-02 11:49+0000\n"
"PO-Revision-Date: 2016-11-02 11:49+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_access_right
#. openerp-web
#: code:addons/pos_access_right/static/src/js/pos_access_right.js:131
#, python-format
msgid "Change Unit Price - Unauthorized function"
msgstr "Changer le prix unitaire - Fonctionnalité non autorisée"
#. module: pos_access_right
#. openerp-web
#: code:addons/pos_access_right/static/src/js/pos_access_right.js:83
#, python-format
msgid "Delete Order - Unauthorized function"
msgstr "Supprimer une commande de vente - Fonctionnalité non autorisée"
#. module: pos_access_right
#. openerp-web
#: code:addons/pos_access_right/static/src/js/pos_access_right.js:124
#, python-format
msgid "Discount - Unauthorized function"
msgstr "Remise - Fonctionnalité non autorisée"
#. module: pos_access_right
#. openerp-web
#: code:addons/pos_access_right/static/src/js/pos_access_right.js:72
#, python-format
msgid "Many Orders - Unauthorized function"
msgstr "Plusieurs Commandes simultanées - Fonctionnalité non autorisée"
#. module: pos_access_right
#. openerp-web
#: code:addons/pos_access_right/static/src/js/pos_access_right.js:110
#, python-format
msgid "Negative Quantity - Unauthorized function"
msgstr "Quantité négative - Fonctionnalité non autorisée"
#. module: pos_access_right
#. openerp-web
#: code:addons/pos_access_right/static/src/js/pos_access_right.js:73
#: code:addons/pos_access_right/static/src/js/pos_access_right.js:84
#: code:addons/pos_access_right/static/src/js/pos_access_right.js:111
#: code:addons/pos_access_right/static/src/js/pos_access_right.js:125
#: code:addons/pos_access_right/static/src/js/pos_access_right.js:132
#, python-format
msgid "Please ask your manager to do it."
msgstr "Veuillez vous rapprocher d'un responsable"
#. module: pos_access_right
#: model:ir.model.fields,field_description:pos_access_right.field_pos_config_group_discount_id
msgid "Point of Sale - Allow Discount"
msgstr "Point de vente - Autoriser les remises"
#. module: pos_access_right
#: model:ir.model.fields,field_description:pos_access_right.field_pos_config_group_negative_qty_id
msgid "Point of Sale - Allow Negative Quantity"
msgstr "Point de vente - Autoriser les quantités négatives"
#. module: pos_access_right
#: model:ir.model.fields,field_description:pos_access_right.field_pos_config_group_change_unit_price_id
msgid "Point of Sale - Allow Unit Price Change"
msgstr "Point de vente - Autoriser le changement de prix unitaire"
#. module: pos_access_right
#: model:ir.model.fields,field_description:pos_access_right.field_pos_config_group_delete_order_id
#: model:res.groups,name:pos_access_right.group_delete_order
msgid "Point of Sale - Delete Order"
msgstr "Point de Vente - Supprimer une commande"
#. module: pos_access_right
#: model:res.groups,name:pos_access_right.group_discount
msgid "Point of Sale - Discount"
msgstr "Point de Vente - Remise"
#. module: pos_access_right
#: model:ir.model.fields,field_description:pos_access_right.field_pos_config_group_multi_order_id
#: model:res.groups,name:pos_access_right.group_multi_order
msgid "Point of Sale - Many Orders"
msgstr "Point de Vente - Plusieurs commandes simultanées"
#. module: pos_access_right
#: model:res.groups,name:pos_access_right.group_negative_qty
msgid "Point of Sale - Negative Quantity"
msgstr "Point de Vente - Quantité négative"
#. module: pos_access_right
#: model:res.groups,name:pos_access_right.group_change_unit_price
msgid "Point of Sale - Unit Price Change"
msgstr "Point de Vente - Changer de prix"
#. module: pos_access_right
#: model:ir.model.fields,help:pos_access_right.field_pos_config_group_discount_id
msgid "This field is there to pass the id of the 'PoS - Allow Discount' Group to the Point of Sale Frontend."
msgstr "Ce champs existe pour passer l'ID du groupe 'PdV - Autoriser les remises' au sein du point de vente tactile."
#. module: pos_access_right
#: model:ir.model.fields,help:pos_access_right.field_pos_config_group_negative_qty_id
msgid "This field is there to pass the id of the 'PoS - Allow Negative Quantity' Group to the Point of Sale Frontend."
msgstr "Ce champs existe pour passer l'ID du groupe 'PdV - Autoriser les quantités négatives' au sein du point de vente tactile."
#. module: pos_access_right
#: model:ir.model.fields,help:pos_access_right.field_pos_config_group_change_unit_price_id
msgid "This field is there to pass the id of the 'PoS - Allow Unit Price Change' Group to the Point of Sale Frontend."
msgstr "Ce champs existe pour passer l'ID du groupe 'PdV - Autoriser les changements de prix unitaires' au sein du point de vente tactile."
#. module: pos_access_right
#: model:ir.model.fields,help:pos_access_right.field_pos_config_group_delete_order_id
msgid "This field is there to pass the id of the 'PoS - Delete Order' Group to the Point of Sale Frontend."
msgstr "Ce champs existe pour passer l'ID du groupe 'PdV - Supprimer une commande' au sein du point de vente tactile."
#. module: pos_access_right
#: model:ir.model.fields,help:pos_access_right.field_pos_config_group_multi_order_id
msgid "This field is there to pass the id of the 'PoS - Many Orders Group to the Point of Sale Frontend."
msgstr "Ce champs existe pour passer l'ID du groupe 'PdV - Plusieurs commandes' au sein du point de vente tactile."
#. module: pos_access_right
#: model:ir.model,name:pos_access_right.model_pos_config
msgid "pos.config"
msgstr "pos.config"

2
pos_access_right/models/__init__.py

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

BIN
pos_access_right/models/__init__.pyc

75
pos_access_right/models/pos_config.py

@ -0,0 +1,75 @@
# -*- 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 fields, models, api
class PosConfig(models.Model):
_inherit = 'pos.config'
group_negative_qty_id = fields.Many2one(
comodel_name='res.groups',
compute='_compute_group_negative_qty_id',
string='Point of Sale - Allow Negative Quantity',
help="This field is there to pass the id of the 'PoS - Allow Negative"
" Quantity' Group to the Point of Sale Frontend.")
group_discount_id = fields.Many2one(
comodel_name='res.groups',
compute='_compute_group_discount_id',
string='Point of Sale - Allow Discount',
help="This field is there to pass the id of the 'PoS - Allow Discount'"
" Group to the Point of Sale Frontend.")
group_change_unit_price_id = fields.Many2one(
comodel_name='res.groups',
compute='_compute_group_change_unit_price_id',
string='Point of Sale - Allow Unit Price Change',
help="This field is there to pass the id of the 'PoS - Allow Unit"
" Price Change' Group to the Point of Sale Frontend.")
group_multi_order_id = fields.Many2one(
comodel_name='res.groups',
compute='_compute_group_multi_order_id',
string='Point of Sale - Many Orders',
help="This field is there to pass the id of the 'PoS - Many Orders"
" Group to the Point of Sale Frontend.")
group_delete_order_id = fields.Many2one(
comodel_name='res.groups',
compute='_compute_group_delete_order_id',
string='Point of Sale - Delete Order',
help="This field is there to pass the id of the 'PoS - Delete Order'"
" Group to the Point of Sale Frontend.")
@api.multi
def _compute_group_negative_qty_id(self):
for config in self:
self.group_negative_qty_id = \
self.env.ref('pos_access_right.group_negative_qty')
@api.multi
def _compute_group_discount_id(self):
for config in self:
self.group_discount_id = \
self.env.ref('pos_access_right.group_discount')
@api.multi
def _compute_group_change_unit_price_id(self):
for config in self:
self.group_change_unit_price_id = \
self.env.ref('pos_access_right.group_change_unit_price')
@api.multi
def _compute_group_multi_order_id(self):
for config in self:
self.group_multi_order_id = \
self.env.ref('pos_access_right.group_multi_order')
@api.multi
def _compute_group_delete_order_id(self):
for config in self:
self.group_delete_order_id = \
self.env.ref('pos_access_right.group_delete_order')

BIN
pos_access_right/models/pos_config.pyc

25
pos_access_right/security/res_groups.yml

@ -0,0 +1,25 @@
# -*- 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: res.groups, id: group_negative_qty}:
name: Point of Sale - Negative Quantity
category_id: base.module_category_usability
- !record {model: res.groups, id: group_discount}:
name: Point of Sale - Discount
category_id: base.module_category_usability
- !record {model: res.groups, id: group_change_unit_price}:
name: Point of Sale - Unit Price Change
category_id: base.module_category_usability
- !record {model: res.groups, id: group_multi_order}:
name: Point of Sale - Many Orders
category_id: base.module_category_usability
- !record {model: res.groups, id: group_delete_order}:
name: Point of Sale - Delete Order
category_id: base.module_category_usability

BIN
pos_access_right/static/description/admin_numpad.png

After

Width: 243  |  Height: 240  |  Size: 9.3 KiB

BIN
pos_access_right/static/description/demo_error.png

After

Width: 552  |  Height: 442  |  Size: 12 KiB

BIN
pos_access_right/static/description/demo_numpad.png

After

Width: 244  |  Height: 245  |  Size: 9.1 KiB

BIN
pos_access_right/static/description/icon.png

After

Width: 64  |  Height: 64  |  Size: 4.3 KiB

BIN
pos_access_right/static/description/new_groups.png

After

Width: 678  |  Height: 141  |  Size: 15 KiB

13
pos_access_right/static/src/css/pos_access_right.css

@ -0,0 +1,13 @@
/*
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).
*/
.pos-disabled-mode {
color: #bbb !important;
background-color: #d3d3d3 !important;
}
.pos-disabled-mode:hover {
background: #e2e2e2 !important;
}

140
pos_access_right/static/src/js/pos_access_right.js

@ -0,0 +1,140 @@
/*
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).
*/
odoo.define('pos_access_right.pos_access_right', function (require) {
"use strict";
var screens = require('point_of_sale.screens');
var chrome = require('point_of_sale.chrome');
var models = require('point_of_sale.models');
var gui = require('point_of_sale.gui');
var core = require('web.core');
var _t = core._t;
/* ********************************************************
point_of_sale.gui
******************************************************** */
// New function 'display_access_right' to display disabled functions
gui.Gui.prototype.display_access_right = function(user){
if (user.groups_id.indexOf(this.pos.config.group_negative_qty_id[0]) != -1){
$('.numpad-minus').removeClass('pos-disabled-mode');
}
else{
$('.numpad-minus').addClass('pos-disabled-mode');
}
if (user.groups_id.indexOf(this.pos.config.group_discount_id[0]) != -1){
$(".mode-button[data-mode='discount']").removeClass('pos-disabled-mode');
}
else{
$(".mode-button[data-mode='discount']").addClass('pos-disabled-mode');
}
if (user.groups_id.indexOf(this.pos.config.group_change_unit_price_id[0]) != -1){
$(".mode-button[data-mode='price']").removeClass('pos-disabled-mode');
}
else{
$(".mode-button[data-mode='price']").addClass('pos-disabled-mode');
}
};
/* ********************************************************
point_of_sale.models
******************************************************** */
// load extra data from 'pos_config' (ids of new groups)
models.load_fields("pos.config", "group_negative_qty_id");
models.load_fields("pos.config", "group_discount_id");
models.load_fields("pos.config", "group_change_unit_price_id");
models.load_fields("pos.config", "group_multi_order_id");
models.load_fields("pos.config", "group_delete_order_id");
// Overload 'set_cashier' function to display correctly
// unauthorized function after cashier changed
var _set_cashier_ = models.PosModel.prototype.set_cashier;
models.PosModel.prototype.set_cashier = function(user){
this.gui.display_access_right(user);
_set_cashier_.call(this, user);
};
/* ********************************************************
chrome.OrderSelectorWidget
******************************************************** */
chrome.OrderSelectorWidget.include({
neworder_click_handler: function(event, $el) {
if (this.pos.get_cashier().groups_id.indexOf(this.pos.config.group_multi_order_id[0]) == -1) {
this.gui.show_popup('error',{
'title': _t('Many Orders - Unauthorized function'),
'body': _t('Please ask your manager to do it.'),
});
}
else {
return this._super();
}
},
deleteorder_click_handler: function(event, $el) {
if (this.pos.get_cashier().groups_id.indexOf(this.pos.config.group_delete_order_id[0]) == -1) {
this.gui.show_popup('error',{
'title': _t('Delete Order - Unauthorized function'),
'body': _t('Please ask your manager to do it.'),
});
}
else {
return this._super();
}
},
});
/* ********************************************************
screens.NumpadWidget
******************************************************** */
screens.NumpadWidget.include({
// Overload 'start' function to display correctly unauthorized function
// at the beginning of the session, based on current user
start: function() {
this._super();
this.gui.display_access_right(this.pos.get_cashier());
},
// block '+/-' button if user doesn't belong to the correct group
clickSwitchSign: function() {
if (this.pos.get_cashier().groups_id.indexOf(this.pos.config.group_negative_qty_id[0]) == -1) {
this.gui.show_popup('error',{
'title': _t('Negative Quantity - Unauthorized function'),
'body': _t('Please ask your manager to do it.'),
});
}
else {
return this._super();
}
},
// block 'discount' or 'price' button if user doesn't belong to the correct group
clickChangeMode: function(event) {
if (event.currentTarget.attributes['data-mode'].nodeValue == 'discount' &&
this.pos.get_cashier().groups_id.indexOf(this.pos.config.group_discount_id[0]) == -1) {
this.gui.show_popup('error',{
'title': _t('Discount - Unauthorized function'),
'body': _t('Please ask your manager to do it.'),
});
}
else if (event.currentTarget.attributes['data-mode'].nodeValue == 'price' &&
this.pos.get_cashier().groups_id.indexOf(this.pos.config.group_change_unit_price_id[0]) == -1) {
this.gui.show_popup('error',{
'title': _t('Change Unit Price - Unauthorized function'),
'body': _t('Please ask your manager to do it.'),
});
}
else {
return this._super(event);
}
},
});
});

17
pos_access_right/static/src/xml/templates.xml

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="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).
-->
<odoo>
<template id="assets_frontend" inherit_id="point_of_sale.assets">
<xpath expr="." position="inside">
<script type="text/javascript" src="/pos_access_right/static/src/js/pos_access_right.js"/>
</xpath>
<xpath expr="//link[@id='pos-stylesheet']" position="after">
<link rel="stylesheet" href="/pos_access_right/static/src/css/pos_access_right.css" />
</xpath>
</template>
</odoo>
Loading…
Cancel
Save