Browse Source
[MIG] pos_pricelist: Migrate to v10 by backporting from v11 (#247)
[MIG] pos_pricelist: Migrate to v10 by backporting from v11 (#247)
This module included previously support for taxes and pricelists. Taxes are now included in upstream Odoo v10, so that feature is removed. The pricelist feature, however, is supported in upstream Odoo v11. Thus, to ease the migration path, that functionality has been scalpel-backported from there. This also means a great diff between previous OCA-only code and current Odoo-backport-only code, but with the advantage that the end user gets exactly the behavior that he would have when updating to v11. Since most of the code has been copied from Odoo, the addon now has to become LGPL, and Odoo has been added as an author.pull/251/head
Jairo Llopis
7 years ago
committed by
Pedro M. Baeza
31 changed files with 836 additions and 2311 deletions
-
109pos_pricelist/README.rst
-
37pos_pricelist/__init__.py
-
47pos_pricelist/__manifest__.py
-
95pos_pricelist/demo/pos_pricelist_demo.yml
-
17pos_pricelist/hooks.py
-
200pos_pricelist/i18n/es.po
-
141pos_pricelist/i18n/pos_pricelist.pot
-
30pos_pricelist/migrations/8.0.1.1.0/post-migration.py
-
24pos_pricelist/models/__init__.py
-
160pos_pricelist/models/point_of_sale.py
-
123pos_pricelist/models/pos_config.py
-
15pos_pricelist/models/pos_order.py
-
28pos_pricelist/models/pos_pricelist.py
-
20pos_pricelist/models/res_partner.py
-
36pos_pricelist/report/report_receipt.xml
-
4pos_pricelist/security/ir.model.access.csv
-
150pos_pricelist/static/src/css/style.css
-
195pos_pricelist/static/src/js/db.js
-
24pos_pricelist/static/src/js/main.js
-
998pos_pricelist/static/src/js/models.js
-
191pos_pricelist/static/src/js/screens.js
-
184pos_pricelist/static/src/js/tests.js
-
87pos_pricelist/static/src/js/widgets.js
-
74pos_pricelist/static/src/xml/pos.xml
-
16pos_pricelist/templates/assets.xml
-
28pos_pricelist/test/test.py
-
28pos_pricelist/views/point_of_sale_view.xml
-
41pos_pricelist/views/pos_config_view.xml
-
29pos_pricelist/views/pos_pricelist_template.xml
-
15pos_pricelist/views/pos_pricelist_views.xml
-
1requirements.txt
@ -1,34 +1,5 @@ |
|||
# -#- coding: utf-8 -#- |
|||
############################################################################## |
|||
# Point Of Sale - Pricelist for POS Odoo |
|||
# Copyright (C) 2014 Taktik (http://www.taktik.be) |
|||
# @author Adil Houmadi <ah@taktik.be> |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
from . import models |
|||
from openerp import SUPERUSER_ID |
|||
|
|||
# -*- coding: utf-8 -*- |
|||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). |
|||
|
|||
def set_pos_line_taxes(cr, registry): |
|||
"""Copy the product taxes to the pos.line""" |
|||
cr.execute("""insert into pline_tax_rel |
|||
select l.id, t.id |
|||
from pos_order_line l |
|||
join pos_order o on l.order_id = o.id |
|||
join product_product p on l.product_id = p.id |
|||
join product_template pt on pt.id = p.product_tmpl_id |
|||
join product_taxes_rel rel on rel.prod_id = pt.id |
|||
join account_tax t on rel.tax_id = t.id |
|||
where t.company_id = o.company_id""") |
|||
registry['pos.order']._install_tax_detail(cr, SUPERUSER_ID) |
|||
from .hooks import post_init_hook |
|||
from . import models |
@ -1,46 +1,31 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# Point Of Sale - Pricelist for POS Odoo |
|||
# Copyright (C) 2014 Taktik (http://www.taktik.be) |
|||
# @author Adil Houmadi <ah@taktik.be> |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
# Copyright 2018 Tecnativa - Jairo Llopis |
|||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). |
|||
|
|||
{ |
|||
'name': 'POS Pricelist', |
|||
'version': '8.0.1.2.0', |
|||
'version': '10.0.1.0.0', |
|||
'category': 'Point Of Sale', |
|||
'sequence': 1, |
|||
'author': "Adil Houmadi @Taktik,Odoo Community Association (OCA)", |
|||
'author': "Tecnativa, " |
|||
"Odoo SA, " |
|||
"Odoo Community Association (OCA)", |
|||
'summary': 'Pricelist for Point of sale', |
|||
'license': 'LGPL-3', |
|||
'post_init_hook': 'post_init_hook', |
|||
'depends': [ |
|||
"point_of_sale", |
|||
], |
|||
"external_dependencies": { |
|||
"python": [ |
|||
"oca.decorators", |
|||
], |
|||
}, |
|||
'data': [ |
|||
"views/pos_pricelist_template.xml", |
|||
"views/pos_pricelist_views.xml", |
|||
"views/point_of_sale_view.xml", |
|||
"report/report_receipt.xml", |
|||
"security/ir.model.access.csv", |
|||
], |
|||
'demo': [ |
|||
'demo/pos_pricelist_demo.yml', |
|||
"templates/assets.xml", |
|||
"views/pos_config_view.xml", |
|||
], |
|||
'qweb': [ |
|||
'static/src/xml/pos.xml' |
|||
], |
|||
'post_init_hook': "set_pos_line_taxes", |
|||
'installable': False, |
|||
'application': False, |
|||
'auto_install': False, |
|||
} |
@ -1,95 +0,0 @@ |
|||
- |
|||
This product will have two rule (min_qty:3 => 10%, min_qty:5 => 30%) |
|||
- |
|||
!record {model: product.product, id: pos_product_product_1}: |
|||
default_code: ABC123 |
|||
name: POS Product 1 |
|||
type: product |
|||
categ_id: product.product_category_1 |
|||
list_price: 100.0 |
|||
standard_price: 50.0 |
|||
uom_id: product.product_uom_unit |
|||
uom_po_id: product.product_uom_unit |
|||
available_in_pos: True |
|||
|
|||
- |
|||
This product will have one rule (min_qty:2 => 10%) |
|||
- |
|||
!record {model: product.product, id: pos_product_product_2}: |
|||
default_code: ABC124 |
|||
name: POS Product 2 |
|||
type: product |
|||
categ_id: product.product_category_1 |
|||
list_price: 100.0 |
|||
standard_price: 100.0 |
|||
uom_id: product.product_uom_unit |
|||
uom_po_id: product.product_uom_unit |
|||
available_in_pos: True |
|||
|
|||
- |
|||
This product will have a rule that (based on supplier discount) |
|||
- |
|||
!record {model: product.product, id: pos_product_product_3}: |
|||
default_code: ABC125 |
|||
name: POS Product 3 |
|||
type: product |
|||
categ_id: product.product_category_1 |
|||
list_price: 100.0 |
|||
standard_price: 50.0 |
|||
uom_id: product.product_uom_unit |
|||
uom_po_id: product.product_uom_unit |
|||
available_in_pos: True |
|||
seller_ids: |
|||
- delay: 1 |
|||
name: base.res_partner_3 |
|||
pricelist_ids: |
|||
- min_quantity : 2.0 |
|||
price : 80 |
|||
|
|||
- |
|||
This product belgon to computer category (5% dicount) |
|||
- |
|||
!record {model: product.product, id: pos_product_product_4}: |
|||
default_code: ABC125 |
|||
name: POS Product 4 |
|||
type: product |
|||
categ_id: product.product_category_4 |
|||
list_price: 100.0 |
|||
standard_price: 50.0 |
|||
uom_id: product.product_uom_unit |
|||
uom_po_id: product.product_uom_unit |
|||
available_in_pos: True |
|||
- |
|||
Prepare pricelist items |
|||
- |
|||
!record {model: product.pricelist.version, id: product.ver0}: |
|||
items_id: |
|||
- name: 10% Discount on POS Product 1 (Qty 3) |
|||
sequence: 2 |
|||
product_id: pos_product_product_1 |
|||
base: 1 |
|||
price_discount: -0.10 |
|||
min_quantity: 3 |
|||
- name: 30% Discount on POS Product 1 (Qty 5) |
|||
sequence: 1 |
|||
product_id: pos_product_product_1 |
|||
min_quantity: 5 |
|||
base: 1 |
|||
price_discount: -0.30 |
|||
- name: 10% Discount (POS Product 2) |
|||
sequence: 1 |
|||
product_id: pos_product_product_2 |
|||
base: 2 |
|||
price_discount: -0.10 |
|||
min_quantity: 2 |
|||
- name: 20% Discount given by supplier |
|||
sequence: 1 |
|||
min_quantity: 2 |
|||
product_id: pos_product_product_3 |
|||
base: -2 |
|||
- name: 5% Discount on all Computer related products (Qty 2) |
|||
sequence: 1 |
|||
min_quantity: 2 |
|||
base: 1 |
|||
categ_id: product.product_category_4 |
|||
price_discount: -0.05 |
@ -0,0 +1,17 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2018 Tecnativa - Jairo Llopis |
|||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). |
|||
|
|||
from odoo import api, SUPERUSER_ID |
|||
|
|||
|
|||
def post_init_hook(cr, registry): |
|||
"""Set default pricelists for existing POS configurations""" |
|||
with api.Environment.manage(): |
|||
env = api.Environment(cr, SUPERUSER_ID, {}) |
|||
nopricelist = env["pos.config"].search([ |
|||
("available_pricelist_ids", "=", False), |
|||
]) |
|||
for one in nopricelist: |
|||
one.available_pricelist_ids = (one.pricelist_id or |
|||
one._default_pricelist()) |
@ -1,141 +1,141 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * pos_pricelist |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 8.0\n" |
|||
# * point_of_sale |
|||
"Project-Id-Version: Odoo Server 11.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2015-07-24 14:44+0000\n" |
|||
"PO-Revision-Date: 2015-07-24 14:44+0000\n" |
|||
"Last-Translator: <>\n" |
|||
"Language-Team: \n" |
|||
"POT-Creation-Date: 2018-02-15 09:10+0000\n" |
|||
"PO-Revision-Date: 2018-02-15 09:18+0000\n" |
|||
"Last-Translator: Jairo Llopis <yajo.sk8@gmail.com>\n" |
|||
"Language-Team: Spanish (https://www.transifex.com/odoo/teams/41243/es/)\n" |
|||
"Language: es\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: \n" |
|||
"Content-Transfer-Encoding: 8bit\n" |
|||
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
|||
"X-Generator: Poedit 2.0.3\n" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,amount:0 |
|||
#: view:website:point_of_sale.report_receipt |
|||
msgid "Amount" |
|||
msgstr "Cuota" |
|||
|
|||
#. module: pos_pricelist |
|||
#. openerp-web |
|||
#: code:addons/pos_pricelist/static/src/js/models.js:386 |
|||
#: code:addons/pos_pricelist/models/pos_config.py:57 |
|||
#, python-format |
|||
msgid "At least one pricelist has no active version ! Please create or activate one." |
|||
msgstr "¡Al menos una lista de precios no tiene ua versión activa! Por favor, cree o active una." |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,base:0 |
|||
#: view:website:point_of_sale.report_receipt |
|||
msgid "Base" |
|||
msgstr "Base imponible" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,create_uid:0 |
|||
msgid "Created by" |
|||
msgstr "Creado por" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,create_date:0 |
|||
msgid "Created on" |
|||
msgstr "Creado en" |
|||
|
|||
#. module: pos_pricelist |
|||
#: help:pos.config,display_price_with_taxes:0 |
|||
msgid "Display Prices with taxes on POS" |
|||
msgstr "Mostrar los precios con impuestos incluidos en el TPV" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,id:0 |
|||
msgid "ID" |
|||
msgstr "ID" |
|||
msgid "" |
|||
"All available pricelists must be in the same currency as the company or as " |
|||
"the Sales Journal set on this point of sale if you use the Accounting " |
|||
"application." |
|||
msgstr "" |
|||
"Todas las tarifas deben estar en la misma moneda que la compañía o el diario " |
|||
"de ventas escogido para este punto de venta si usted está usando la " |
|||
"aplicación de contabilidad." |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,write_uid:0 |
|||
msgid "Last Updated by" |
|||
msgstr "Última actualización por" |
|||
#: code:addons/pos_pricelist/models/pos_config.py:69 |
|||
#, python-format |
|||
msgid "" |
|||
"All payment methods must be in the same currency as the Sales Journal or the " |
|||
"company currency if that is not set." |
|||
msgstr "" |
|||
"Todos los métodos de pago deben estar en la misma moneda que el diario de " |
|||
"ventas o, si no lo hay, de la compañía." |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,write_date:0 |
|||
msgid "Last Updated on" |
|||
msgstr "Última actualización en" |
|||
#: model:ir.model.fields,help:pos_pricelist.field_pos_config_group_sale_pricelist |
|||
msgid "" |
|||
"Allows to manage different prices based on rules per category of customers. " |
|||
"Example: 10% for retailers, promotion of 5 EUR on this product, etc." |
|||
msgstr "" |
|||
"Permite gestionar diferentes precios basándose en reglas por categoría de " |
|||
"clientes. Por ejemplo: 10% para minoristas, promoción de 5€ en este " |
|||
"producto, etc." |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:ir.model,name:pos_pricelist.model_pos_order_line |
|||
msgid "Lines of Point of Sale" |
|||
msgstr "Líneas del Terminal Punto de Venta" |
|||
#: model:ir.model.fields,field_description:pos_pricelist.field_pos_config_available_pricelist_ids |
|||
msgid "Available Pricelists" |
|||
msgstr "Listas de Precio Disponibles" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,pos_order:0 |
|||
msgid "POS Order" |
|||
msgstr "Pedido" |
|||
#: model:ir.model.fields,help:pos_pricelist.field_pos_config_available_pricelist_ids |
|||
msgid "" |
|||
"Make several pricelists available in the Point of Sale. You can also apply a " |
|||
"pricelist to specific customers from their contact form (in Sales tab). To " |
|||
"be valid, this pricelist must be listed here as an available pricelist. " |
|||
"Otherwise the default pricelist will apply." |
|||
msgstr "" |
|||
"Hacer disponibles varias tarifas en este punto de venta. También puede " |
|||
"aplicar una tarifa a clientes específicos desde su formulario de contacto " |
|||
"(en la pestaña de ventas). Para que sea válida, esa tarifa debe estar " |
|||
"disponible aquí. En caso contrario, se le aplicará la tarifa por defecto." |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:product.template,name:pos_pricelist.pos_product_product_1_product_template |
|||
msgid "POS Product 1" |
|||
msgstr "TPV Producto 1" |
|||
#. openerp-web |
|||
#: code:addons/pos_pricelist/static/src/xml/pos.xml:36 |
|||
#, python-format |
|||
msgid "N/A" |
|||
msgstr "N/A" |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:product.template,name:pos_pricelist.pos_product_product_2_product_template |
|||
msgid "POS Product 2" |
|||
msgstr "TPV Producto 2" |
|||
#: model:ir.model,name:pos_pricelist.model_pos_order |
|||
msgid "Point of Sale Orders" |
|||
msgstr "Pedidos del TPV" |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:product.template,name:pos_pricelist.pos_product_product_3_product_template |
|||
msgid "POS Product 3" |
|||
msgstr "TPV Producto 3" |
|||
#. openerp-web |
|||
#: code:addons/pos_pricelist/static/src/js/screens.js:186 |
|||
#: code:addons/pos_pricelist/static/src/xml/pos.xml:15 |
|||
#: code:addons/pos_pricelist/static/src/xml/pos.xml:31 |
|||
#, python-format |
|||
msgid "Pricelist" |
|||
msgstr "Tarifa" |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:product.template,name:pos_pricelist.pos_product_product_4_product_template |
|||
msgid "POS Product 4" |
|||
msgstr "TPV Producto 4" |
|||
#: model:ir.ui.view,arch_db:pos_pricelist.view_pos_config_form |
|||
msgid "Pricelists" |
|||
msgstr "Tarifas" |
|||
|
|||
#. module: pos_pricelist |
|||
#: view:pos.order:pos_pricelist.view_pos_pos_form |
|||
msgid "Payments" |
|||
msgstr "Pagos" |
|||
#. openerp-web |
|||
#: code:addons/pos_pricelist/static/src/js/screens.js:173 |
|||
#, python-format |
|||
msgid "Select pricelist" |
|||
msgstr "Seleccionar tarifa" |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:ir.model,name:pos_pricelist.model_pos_order |
|||
msgid "Point of Sale" |
|||
msgstr "Terminal Punto de Venta" |
|||
#: model:ir.model.fields,help:pos_pricelist.field_pos_config_use_pricelist |
|||
msgid "Set shop-specific prices, seasonal discounts, etc." |
|||
msgstr "" |
|||
"Establecer precios específicos por tienda, descuentos por campaña especial, " |
|||
"etc." |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.config,display_price_with_taxes:0 |
|||
msgid "Price With Taxes" |
|||
msgstr "Precios con impuestos incluidos" |
|||
#: model:ir.model.fields,field_description:pos_pricelist.field_pos_config_group_pricelist_item |
|||
msgid "Show pricelists to customers" |
|||
msgstr "Mostrar tarifas a los clientes" |
|||
|
|||
#. module: pos_pricelist |
|||
#. openerp-web |
|||
#: code:addons/pos_pricelist/static/src/js/models.js:385 |
|||
#: code:addons/pos_pricelist/models/pos_config.py:52 |
|||
#, python-format |
|||
msgid "Pricelist Error" |
|||
msgstr "Error en lista de precios" |
|||
msgid "The default pricelist must be included in the available pricelists." |
|||
msgstr "La tarifa por defecto debe estar incluida entre las disponibles." |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,tax:0 |
|||
#: view:website:point_of_sale.report_receipt |
|||
msgid "Tax" |
|||
msgstr "Impuesto" |
|||
#: code:addons/pos_pricelist/models/pos_config.py:63 |
|||
#, python-format |
|||
msgid "" |
|||
"The invoice journal must be in the same currency as the Sales Journal or the " |
|||
"company currency if that is not set." |
|||
msgstr "" |
|||
"El diario de facturación debe estar en la misma moneda que el de ventas o, " |
|||
"si no lo hay, que la compañía." |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,name:0 |
|||
msgid "Tax Description" |
|||
msgstr "Descripción del impuesto" |
|||
#: model:ir.model.fields,field_description:pos_pricelist.field_pos_config_use_pricelist |
|||
msgid "Use pricelists" |
|||
msgstr "Usar tarifas" |
|||
|
|||
#. module: pos_pricelist |
|||
#: view:pos.order:pos_pricelist.view_pos_pos_form |
|||
#: field:pos.order,taxes:0 |
|||
#: field:pos.order.line,tax_ids:0 |
|||
msgid "Taxes" |
|||
msgstr "Impuestos" |
|||
#: model:ir.model.fields,field_description:pos_pricelist.field_pos_config_group_sale_pricelist |
|||
msgid "Use pricelists to adapt your price per customers" |
|||
msgstr "Usar tarifas para adaptar los precios a cada cliente" |
|||
|
|||
#. module: pos_pricelist |
|||
#: view:pos.order:pos_pricelist.view_pos_pos_form |
|||
msgid "Taxes detail" |
|||
msgstr "Detalle de impuestos" |
|||
|
|||
#: model:ir.model,name:pos_pricelist.model_pos_config |
|||
msgid "pos.config" |
|||
msgstr "pos.config" |
@ -1,141 +0,0 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * pos_pricelist |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 8.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2015-07-24 14:44+0000\n" |
|||
"PO-Revision-Date: 2015-07-24 14:44+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_pricelist |
|||
#: field:pos.order.tax,amount:0 |
|||
#: view:website:point_of_sale.report_receipt |
|||
msgid "Amount" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#. openerp-web |
|||
#: code:addons/pos_pricelist/static/src/js/models.js:386 |
|||
#, python-format |
|||
msgid "At least one pricelist has no active version ! Please create or activate one." |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,base:0 |
|||
#: view:website:point_of_sale.report_receipt |
|||
msgid "Base" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,create_uid:0 |
|||
msgid "Created by" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,create_date:0 |
|||
msgid "Created on" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: help:pos.config,display_price_with_taxes:0 |
|||
msgid "Display Prices with taxes on POS" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,id:0 |
|||
msgid "ID" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,write_uid:0 |
|||
msgid "Last Updated by" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,write_date:0 |
|||
msgid "Last Updated on" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:ir.model,name:pos_pricelist.model_pos_order_line |
|||
msgid "Lines of Point of Sale" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,pos_order:0 |
|||
msgid "POS Order" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:product.template,name:pos_pricelist.pos_product_product_1_product_template |
|||
msgid "POS Product 1" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:product.template,name:pos_pricelist.pos_product_product_2_product_template |
|||
msgid "POS Product 2" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:product.template,name:pos_pricelist.pos_product_product_3_product_template |
|||
msgid "POS Product 3" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:product.template,name:pos_pricelist.pos_product_product_4_product_template |
|||
msgid "POS Product 4" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: view:pos.order:pos_pricelist.view_pos_pos_form |
|||
msgid "Payments" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: model:ir.model,name:pos_pricelist.model_pos_order |
|||
msgid "Point of Sale" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.config,display_price_with_taxes:0 |
|||
msgid "Price With Taxes" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#. openerp-web |
|||
#: code:addons/pos_pricelist/static/src/js/models.js:385 |
|||
#, python-format |
|||
msgid "Pricelist Error" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,tax:0 |
|||
#: view:website:point_of_sale.report_receipt |
|||
msgid "Tax" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: field:pos.order.tax,name:0 |
|||
msgid "Tax Description" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: view:pos.order:pos_pricelist.view_pos_pos_form |
|||
#: field:pos.order,taxes:0 |
|||
#: field:pos.order.line,tax_ids:0 |
|||
msgid "Taxes" |
|||
msgstr "" |
|||
|
|||
#. module: pos_pricelist |
|||
#: view:pos.order:pos_pricelist.view_pos_pos_form |
|||
msgid "Taxes detail" |
|||
msgstr "" |
|||
|
@ -1,30 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2015 Aserti Global Solutions (http://www.aserti.es/). |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as published |
|||
# by the Free Software Foundation, either version 3 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
__name__ = "Copy the product taxes to the pos.line" |
|||
|
|||
|
|||
def migrate(cr, version): |
|||
cr.execute("""insert into pline_tax_rel |
|||
select l.id, t.id |
|||
from pos_order_line l |
|||
join pos_order o on l.order_id = o.id |
|||
join product_taxes_rel rel on rel.prod_id = l.product_id |
|||
join account_tax t on rel.tax_id = t.id |
|||
where t.company_id = o.company_id""") |
@ -1,20 +1,6 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# Point Of Sale - Pricelist for POS Odoo |
|||
# Copyright (C) 2015 Taktik (http://www.taktik.be) |
|||
# @author Adil Houmadi <ah@taktik.be> |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
from . import pos_pricelist |
|||
from . import point_of_sale |
|||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). |
|||
|
|||
from . import pos_config |
|||
from . import pos_order |
|||
from . import res_partner |
@ -1,160 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Copyright (C) 2015 Aserti Global Solutions (http://www.aserti.es/). |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as published |
|||
# by the Free Software Foundation, either version 3 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
|
|||
from openerp import models, fields, api |
|||
from openerp.addons import decimal_precision as dp |
|||
import logging |
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
|
|||
class PosOrderTax(models.Model): |
|||
_name = 'pos.order.tax' |
|||
|
|||
pos_order = fields.Many2one('pos.order', string='POS Order', |
|||
ondelete='cascade', index=True) |
|||
tax = fields.Many2one('account.tax', string='Tax') |
|||
name = fields.Char(string='Tax Description', required=True) |
|||
base = fields.Float(string='Base', digits=dp.get_precision('Account')) |
|||
amount = fields.Float(string='Amount', digits=dp.get_precision('Account')) |
|||
|
|||
|
|||
class PosOrderLine(models.Model): |
|||
_inherit = "pos.order.line" |
|||
|
|||
@api.multi |
|||
def _compute_taxes(self): |
|||
res = { |
|||
'total': 0, |
|||
'total_included': 0, |
|||
'taxes': [], |
|||
} |
|||
for line in self: |
|||
price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) |
|||
taxes = line.tax_ids.compute_all( |
|||
price, line.qty, product=line.product_id, |
|||
partner=line.order_id.partner_id) |
|||
res['total'] += taxes['total'] |
|||
res['total_included'] += taxes['total_included'] |
|||
res['taxes'] += taxes['taxes'] |
|||
return res |
|||
|
|||
@api.one |
|||
@api.depends('tax_ids', 'qty', 'price_unit', |
|||
'product_id', 'discount', 'order_id.partner_id') |
|||
def _amount_line_all(self): |
|||
taxes = self._compute_taxes() |
|||
self.price_subtotal = taxes['total'] |
|||
self.price_subtotal_incl = taxes['total_included'] |
|||
|
|||
tax_ids = fields.Many2many( |
|||
'account.tax', 'pline_tax_rel', 'pos_line_id', 'tax_id', |
|||
"Taxes", domain=[('type_tax_use', '=', 'sale')]) |
|||
price_subtotal = fields.Float(compute="_amount_line_all", store=True) |
|||
price_subtotal_incl = fields.Float(compute="_amount_line_all", store=True) |
|||
|
|||
|
|||
class PosOrder(models.Model): |
|||
_inherit = "pos.order" |
|||
|
|||
taxes = fields.One2many(comodel_name='pos.order.tax', |
|||
inverse_name='pos_order', readonly=True) |
|||
|
|||
@api.model |
|||
def _amount_line_tax(self, line): |
|||
price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) |
|||
taxes = line.tax_ids.compute_all( |
|||
price, line.qty, product=line.product_id, |
|||
partner=line.order_id.partner_id)['taxes'] |
|||
val = 0.0 |
|||
for c in taxes: |
|||
val += c.get('amount', 0.0) |
|||
return val |
|||
|
|||
@api.multi |
|||
def _tax_list_get(self): |
|||
agg_taxes = {} |
|||
tax_lines = [] |
|||
for order in self: |
|||
for line in order.lines: |
|||
tax_lines.append({ |
|||
'base': line.price_subtotal, |
|||
'taxes': line._compute_taxes()['taxes'] |
|||
}) |
|||
|
|||
for tax_line in tax_lines: |
|||
base = tax_line['base'] |
|||
for tax in tax_line['taxes']: |
|||
tax_id = str(tax['id']) |
|||
if tax_id in agg_taxes: |
|||
agg_taxes[tax_id]['base'] += base |
|||
agg_taxes[tax_id]['amount'] += tax['amount'] |
|||
else: |
|||
agg_taxes[tax_id] = { |
|||
'tax_id': tax_id, |
|||
'name': tax['name'], |
|||
'base': base, |
|||
'amount': tax['amount'], |
|||
} |
|||
return agg_taxes |
|||
|
|||
@api.multi |
|||
def compute_tax_detail(self): |
|||
taxes_to_delete = False |
|||
for order in self: |
|||
taxes_to_delete = self.env['pos.order.tax'].search( |
|||
[('pos_order', '=', order.id)]) |
|||
# Update order taxes list |
|||
for key, tax in order._tax_list_get().iteritems(): |
|||
current = taxes_to_delete.filtered( |
|||
lambda r: r.tax.id == tax['tax_id']) |
|||
if current: |
|||
current.write({ |
|||
'base': tax['base'], |
|||
'amount': tax['amount'], |
|||
}) |
|||
taxes_to_delete -= current |
|||
else: |
|||
self.env['pos.order.tax'].create({ |
|||
'pos_order': order.id, |
|||
'tax': tax['tax_id'], |
|||
'name': tax['name'], |
|||
'base': tax['base'], |
|||
'amount': tax['amount'], |
|||
}) |
|||
if taxes_to_delete: |
|||
taxes_to_delete.unlink() |
|||
|
|||
@api.multi |
|||
def action_paid(self): |
|||
result = super(PosOrder, self).action_paid() |
|||
self.compute_tax_detail() |
|||
return result |
|||
|
|||
@api.model |
|||
def _install_tax_detail(self): |
|||
"""Create tax details to pos.order's already paid, done or invoiced. |
|||
""" |
|||
# Find orders with state : paid, done or invoiced |
|||
orders = self.search([('state', 'in', ('paid', 'done', 'invoiced')), |
|||
('taxes', '=', False)]) |
|||
# Compute tax detail |
|||
orders.compute_tax_detail() |
|||
_logger.info("%d orders computed installing module.", len(orders)) |
@ -0,0 +1,123 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2018 Tecnativa - Jairo Llopis |
|||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). |
|||
|
|||
from odoo import _, api, fields, models |
|||
from odoo.exceptions import ValidationError |
|||
import logging |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
try: |
|||
from oca.decorators import foreach |
|||
except ImportError: # pragma: no-cover |
|||
_logger.warn("Missing dependency", exc_info=True) |
|||
|
|||
|
|||
class PosConfig(models.Model): |
|||
_inherit = 'pos.config' |
|||
|
|||
# Redefine preexisting field |
|||
pricelist_id = fields.Many2one( |
|||
string="Default Pricelist", |
|||
help="The pricelist used if no customer is selected or if the " |
|||
"customer has no Sale Pricelist configured.", |
|||
) |
|||
# New fields |
|||
available_pricelist_ids = fields.Many2many( |
|||
'product.pricelist', |
|||
string='Available Pricelists', |
|||
default=lambda self: self._default_pricelist(), |
|||
help="Make several pricelists available in the Point of Sale. " |
|||
"You can also apply a pricelist to specific customers from " |
|||
"their contact form (in Sales tab). To be valid, this pricelist " |
|||
"must be listed here as an available pricelist. Otherwise the " |
|||
"default pricelist will apply.", |
|||
) |
|||
use_pricelist = fields.Boolean( |
|||
"Use pricelists", |
|||
help="Set shop-specific prices, seasonal discounts, etc.", |
|||
) |
|||
group_sale_pricelist = fields.Boolean( |
|||
"Use pricelists to adapt your price per customers", |
|||
implied_group='product.group_sale_pricelist', |
|||
help="Allows to manage different prices based on rules per " |
|||
"category of customers. Example: 10% for retailers, promotion " |
|||
"of 5 EUR on this product, etc.", |
|||
) |
|||
group_pricelist_item = fields.Boolean( |
|||
"Show pricelists to customers", |
|||
implied_group='product.group_pricelist_item', |
|||
) |
|||
|
|||
@api.constrains('pricelist_id', 'available_pricelist_ids', 'journal_id', |
|||
'invoice_journal_id', 'journal_ids') |
|||
@foreach() |
|||
def _check_currencies(self): |
|||
if self.pricelist_id not in self.available_pricelist_ids: |
|||
raise ValidationError(_( |
|||
"The default pricelist must be included in " |
|||
"the available pricelists.")) |
|||
if self.available_pricelist_ids.filtered( |
|||
lambda pricelist: pricelist.currency_id != self.currency_id): |
|||
raise ValidationError(_( |
|||
"All available pricelists must be in the same currency " |
|||
"as the company or as the Sales Journal set on this " |
|||
"point of sale if you use the Accounting application.")) |
|||
if (self.invoice_journal_id.currency_id and |
|||
self.invoice_journal_id.currency_id != self.currency_id): |
|||
raise ValidationError(_( |
|||
"The invoice journal must be in the same currency as the " |
|||
"Sales Journal or the company currency if that is not set.")) |
|||
if self.journal_ids.filtered( |
|||
lambda journal: (journal.currency_id and |
|||
journal.currency_id != self.currency_id)): |
|||
raise ValidationError(_( |
|||
"All payment methods must be in the same currency as the " |
|||
"Sales Journal or the company currency if that is not set.")) |
|||
|
|||
@api.onchange('use_pricelist') |
|||
def _onchange_use_pricelist(self): |
|||
"""If the 'pricelist' box is unchecked, reset the pricelist_id |
|||
|
|||
This makes the posbox to stop using a pricelist. |
|||
""" |
|||
if not self.use_pricelist: |
|||
self.pricelist_id = self.available_pricelist_ids = \ |
|||
self._default_pricelist() |
|||
else: |
|||
self.update({ |
|||
'group_sale_pricelist': True, |
|||
'group_pricelist_item': True, |
|||
}) |
|||
|
|||
@api.onchange('available_pricelist_ids') |
|||
def _onchange_available_pricelist_ids(self): |
|||
if self.pricelist_id not in self.available_pricelist_ids: |
|||
self.pricelist_id = False |
|||
|
|||
@foreach() |
|||
def _check_groups_implied(self): |
|||
for field_name in (f for f in self.fields_get_keys() |
|||
if f.startswith('group_')): |
|||
field = self._fields[field_name] |
|||
if (field.type in {'boolean', 'selection'} and |
|||
hasattr(field, 'implied_group')): |
|||
field_group_xmlids = getattr( |
|||
field, 'group', 'base.group_user').split(',') |
|||
field_groups = self.env['res.groups'].concat( |
|||
*(self.env.ref(it) for it in field_group_xmlids)) |
|||
field_groups.write({ |
|||
'implied_ids': [(4, self.env.ref(field.implied_group).id)], |
|||
}) |
|||
|
|||
@api.model |
|||
def create(self, vals): |
|||
result = super(PosConfig, self).create(vals) |
|||
result.sudo()._check_groups_implied() |
|||
return result |
|||
|
|||
def write(self, vals): |
|||
result = super(PosConfig, self).write(vals) |
|||
self.sudo()._check_groups_implied() |
|||
return result |
@ -0,0 +1,15 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2018 Tecnativa - Jairo Llopis |
|||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). |
|||
|
|||
from odoo import api, models |
|||
|
|||
|
|||
class PosOrder(models.Model): |
|||
_inherit = "pos.order" |
|||
|
|||
@api.model |
|||
def _order_fields(self, ui_order): |
|||
result = super(PosOrder, self)._order_fields(ui_order) |
|||
result.setdefault('pricelist_id', ui_order['pricelist_id']) |
|||
return result |
@ -1,28 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# Point Of Sale - Pricelist for POS Odoo |
|||
# Copyright (C) 2015 Taktik (http://www.taktik.be) |
|||
# @author Adil Houmadi <ah@taktik.be> |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
from openerp import models, fields |
|||
|
|||
|
|||
class PosPriceListConfig(models.Model): |
|||
_inherit = 'pos.config' |
|||
|
|||
display_price_with_taxes = fields.Boolean( |
|||
string='Price With Taxes', |
|||
help="Display Prices with taxes on POS" |
|||
) |
@ -0,0 +1,20 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2018 Tecnativa - Jairo Llopis |
|||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). |
|||
|
|||
from odoo import api, models |
|||
|
|||
|
|||
class ResPartner(models.Model): |
|||
_inherit = "res.partner" |
|||
|
|||
@api.model |
|||
def create_from_ui(self, partner): |
|||
try: |
|||
# If there's an incoming pricelist, it must be an int |
|||
partner["property_product_pricelist"] = \ |
|||
int(partner["property_product_pricelist"]) |
|||
except KeyError: |
|||
# There's no incoming pricelist, no problem |
|||
pass |
|||
return super(ResPartner, self).create_from_ui(partner) |
@ -1,36 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
|
|||
<template id="report_receipt" |
|||
inherit_id="point_of_sale.report_receipt" |
|||
name="Add taxes detail"> |
|||
<xpath expr="//div[@class='page']" position="inside"> |
|||
<table class="table table-condensed"> |
|||
<thead> |
|||
<tr> |
|||
<th>Tax</th> |
|||
<th class="text-right">Base</th> |
|||
<th class="text-right">Amount</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
<tr t-foreach="o.taxes" t-as="tax"> |
|||
<td> |
|||
<span t-esc="tax.name"/> |
|||
</td> |
|||
<td class="text-right"> |
|||
<span t-esc="formatLang(tax.base, currency_obj=res_company.currency_id)"/> |
|||
</td> |
|||
<td class="text-right"> |
|||
<span t-esc="formatLang(tax.amount, currency_obj=res_company.currency_id)"/> |
|||
</td> |
|||
</tr> |
|||
</tbody> |
|||
</table> |
|||
</xpath> |
|||
</template> |
|||
|
|||
|
|||
</data> |
|||
</openerp> |
@ -1,3 +1,3 @@ |
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
|||
access_pos_order_tax,pos.order.tax,model_pos_order_tax,point_of_sale.group_pos_user,1,0,0,0 |
|||
access_pos_order_tax_manager,pos.order.tax manager,model_pos_order_tax,point_of_sale.group_pos_manager,1,1,1,1 |
|||
access_product_pricelist_manager,product.pricelist manager,product.model_product_pricelist,point_of_sale.group_pos_manager,1,1,1,1 |
|||
access_product_pricelist_user,product.pricelist user,product.model_product_pricelist,point_of_sale.group_pos_user,1,0,0,0 |
@ -1,150 +0,0 @@ |
|||
/****************************************************************************** |
|||
* Point Of Sale - Pricelist for POS Odoo |
|||
* Copyright (C) 2014 Taktik (http://www.taktik.be) |
|||
* @author Adil Houmadi <ah@taktik.be> |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License as |
|||
* published by the Free Software Foundation, either version 3 of the |
|||
* License, or (at your option) any later version. |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* You should have received a copy of the GNU Affero General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
******************************************************************************/ |
|||
.popover { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
z-index: 1060; |
|||
display: none; |
|||
max-width: 276px; |
|||
padding: 1px; |
|||
text-align: left; |
|||
white-space: normal; |
|||
background-color: #fff; |
|||
-webkit-background-clip: padding-box; |
|||
background-clip: padding-box; |
|||
border: 1px solid #ccc; |
|||
border: 1px solid rgba(0, 0, 0, .2); |
|||
border-radius: 6px; |
|||
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); |
|||
box-shadow: 0 5px 10px rgba(0, 0, 0, .2); |
|||
} |
|||
.popover-title { |
|||
padding: 8px 14px; |
|||
margin: 0; |
|||
font-size: 14px; |
|||
font-weight: normal; |
|||
line-height: 18px; |
|||
background-color: #f7f7f7; |
|||
border-bottom: 1px solid #ebebeb; |
|||
border-radius: 5px 5px 0 0; |
|||
} |
|||
|
|||
/* ToolTip */ |
|||
.tooltip { |
|||
position: absolute; |
|||
z-index: 1070; |
|||
display: block; |
|||
font-size: 12px; |
|||
line-height: 1.4; |
|||
visibility: visible; |
|||
filter: alpha(opacity=0); |
|||
opacity: 0; |
|||
} |
|||
.tooltip.in { |
|||
filter: alpha(opacity=90); |
|||
opacity: .9; |
|||
} |
|||
.tooltip.top { |
|||
padding: 5px 0; |
|||
margin-top: -3px; |
|||
} |
|||
.tooltip.right { |
|||
padding: 0 5px; |
|||
margin-left: 3px; |
|||
} |
|||
.tooltip.bottom { |
|||
padding: 5px 0; |
|||
margin-top: 3px; |
|||
} |
|||
.tooltip.left { |
|||
padding: 0 5px; |
|||
margin-left: -3px; |
|||
} |
|||
.tooltip-inner { |
|||
max-width: 200px; |
|||
padding: 3px 8px; |
|||
color: #fff; |
|||
text-align: center; |
|||
text-decoration: none; |
|||
background-color: #000; |
|||
border-radius: 4px; |
|||
} |
|||
.tooltip-arrow { |
|||
position: absolute; |
|||
width: 0; |
|||
height: 0; |
|||
border-color: transparent; |
|||
border-style: solid; |
|||
} |
|||
.tooltip.top .tooltip-arrow { |
|||
bottom: 0; |
|||
left: 50%; |
|||
margin-left: -5px; |
|||
border-width: 5px 5px 0; |
|||
border-top-color: #000; |
|||
} |
|||
.tooltip.top-left .tooltip-arrow { |
|||
bottom: 0; |
|||
left: 5px; |
|||
border-width: 5px 5px 0; |
|||
border-top-color: #000; |
|||
} |
|||
.tooltip.top-right .tooltip-arrow { |
|||
right: 5px; |
|||
bottom: 0; |
|||
border-width: 5px 5px 0; |
|||
border-top-color: #000; |
|||
} |
|||
.tooltip.right .tooltip-arrow { |
|||
top: 50%; |
|||
left: 0; |
|||
margin-top: -5px; |
|||
border-width: 5px 5px 5px 0; |
|||
border-right-color: #000; |
|||
} |
|||
.tooltip.left .tooltip-arrow { |
|||
top: 50%; |
|||
right: 0; |
|||
margin-top: -5px; |
|||
border-width: 5px 0 5px 5px; |
|||
border-left-color: #000; |
|||
} |
|||
.tooltip.bottom .tooltip-arrow { |
|||
top: 0; |
|||
left: 50%; |
|||
margin-left: -5px; |
|||
border-width: 0 5px 5px; |
|||
border-bottom-color: #000; |
|||
} |
|||
.tooltip.bottom-left .tooltip-arrow { |
|||
top: 0; |
|||
left: 5px; |
|||
border-width: 0 5px 5px; |
|||
border-bottom-color: #000; |
|||
} |
|||
.tooltip.bottom-right .tooltip-arrow { |
|||
top: 0; |
|||
right: 5px; |
|||
border-width: 0 5px 5px; |
|||
border-bottom-color: #000; |
|||
} |
|||
.pos .pos-right-align { |
|||
text-align: right; |
|||
vertical-align: top; |
|||
} |
@ -1,195 +0,0 @@ |
|||
/****************************************************************************** |
|||
* Point Of Sale - Pricelist for POS Odoo |
|||
* Copyright (C) 2014 Taktik (http://www.taktik.be)
|
|||
* @author Adil Houmadi <ah@taktik.be> |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License as |
|||
* published by the Free Software Foundation, either version 3 of the |
|||
* License, or (at your option) any later version. |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* You should have received a copy of the GNU Affero General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
* |
|||
******************************************************************************/ |
|||
function pos_pricelist_db(instance, module) { |
|||
|
|||
module.PosDB = module.PosDB.extend({ |
|||
init: function (options) { |
|||
options = options || {}; |
|||
this._super(options); |
|||
this.pricelist_by_id = {}; |
|||
this.pricelist_version_by_id = {}; |
|||
this.pricelist_item_by_id = {}; |
|||
this.pricelist_item_sorted = []; |
|||
this.product_category_by_id = {}; |
|||
this.product_category_children = {}; |
|||
this.product_category_ancestors = {}; |
|||
this.product_price_type_by_id = {}; |
|||
this.supplierinfo_by_id = {}; |
|||
this.pricelist_partnerinfo_by_id = {}; |
|||
this.fiscal_position_tax_by_id = {}; |
|||
}, |
|||
add_fiscal_position_taxes: function (fiscal_position_taxes) { |
|||
if (!(fiscal_position_taxes instanceof Array)) { |
|||
fiscal_position_taxes = [fiscal_position_taxes]; |
|||
} |
|||
var fiscal_position_tax; |
|||
while (fiscal_position_tax = fiscal_position_taxes.pop()) { |
|||
this.fiscal_position_tax_by_id[fiscal_position_tax.id] |
|||
= fiscal_position_tax; |
|||
} |
|||
}, |
|||
add_pricelist_partnerinfo: function (pricelist_partnerinfos) { |
|||
if (!(pricelist_partnerinfos instanceof Array)) { |
|||
pricelist_partnerinfos = [pricelist_partnerinfos]; |
|||
} |
|||
var partner_info; |
|||
while (partner_info = pricelist_partnerinfos.pop()) { |
|||
this.pricelist_partnerinfo_by_id[partner_info.id] |
|||
= partner_info; |
|||
} |
|||
}, |
|||
add_supplierinfo: function (supplierinfos) { |
|||
if (!(supplierinfos instanceof Array)) { |
|||
supplierinfos = [supplierinfos]; |
|||
} |
|||
var supplier_info; |
|||
while (supplier_info = supplierinfos.pop()) { |
|||
this.supplierinfo_by_id[supplier_info.id] = supplier_info; |
|||
} |
|||
}, |
|||
add_pricelists: function (pricelists) { |
|||
if (!(pricelists instanceof Array)) { |
|||
pricelists = [pricelists]; |
|||
} |
|||
var pricelist; |
|||
while (pricelist = pricelists.pop()) { |
|||
this.pricelist_by_id[pricelist.id] = pricelist; |
|||
} |
|||
}, |
|||
add_pricelist_versions: function (versions) { |
|||
if (!(versions instanceof Array)) { |
|||
versions = [versions]; |
|||
} |
|||
var version; |
|||
while (version = versions.pop()) { |
|||
this.pricelist_version_by_id[version.id] = version; |
|||
} |
|||
}, |
|||
add_pricelist_items: function (items) { |
|||
if (!(items instanceof Array)) { |
|||
items = [items]; |
|||
} |
|||
var item; |
|||
while (item = items.pop()) { |
|||
this.pricelist_item_by_id[item.id] = item; |
|||
} |
|||
this.pricelist_item_sorted = this._items_sorted(); |
|||
}, |
|||
add_price_types: function (price_types) { |
|||
if (!(price_types instanceof Array)) { |
|||
price_types = [price_types]; |
|||
} |
|||
var ptype; |
|||
while (ptype = price_types.pop()) { |
|||
this.product_price_type_by_id[ptype.id] = ptype; |
|||
} |
|||
}, |
|||
add_product_categories: function (categories) { |
|||
if (!(categories instanceof Array)) { |
|||
categories = [categories]; |
|||
} |
|||
var category; |
|||
while (category = categories.pop()) { |
|||
this.product_category_by_id[category.id] = category; |
|||
this.product_category_children[category.id] = |
|||
category.child_id; |
|||
} |
|||
this._make_ancestors(); |
|||
}, |
|||
_make_ancestors: function () { |
|||
var category, ancestors; |
|||
for (var id in this.product_category_by_id) { |
|||
category = this.product_category_by_id[id]; |
|||
ancestors = []; |
|||
while (category.parent_id) { |
|||
ancestors.push(category.parent_id[0]); |
|||
category = category.parent_id ? |
|||
this.product_category_by_id[category.parent_id[0]] : |
|||
false; |
|||
} |
|||
this.product_category_ancestors[parseInt(id)] = ancestors; |
|||
} |
|||
}, |
|||
_items_sorted: function () { |
|||
var items = this.pricelist_item_by_id; |
|||
var list = []; |
|||
for (var key in items) { |
|||
list.push(items[key]); |
|||
} |
|||
list.sort(function (a, b) { |
|||
if (a.sequence < b.sequence) return -1; |
|||
if (a.sequence > b.sequence) return 1; |
|||
if (a.min_quantity > b.min_quantity) return -1; |
|||
if (a.min_quantity < b.min_quantity) return 1; |
|||
return 0; |
|||
}); |
|||
return list; |
|||
}, |
|||
map_tax: function (fiscal_position_id, taxes_ids) { |
|||
var taxes = []; |
|||
var found_taxes = {}; |
|||
for (var id in this.fiscal_position_tax_by_id) { |
|||
var fp_line = this.fiscal_position_tax_by_id[id]; |
|||
if (fp_line && fp_line.position_id && |
|||
fp_line.position_id[0] == fiscal_position_id && |
|||
taxes_ids.indexOf(fp_line.tax_src_id[0]) > -1) { |
|||
taxes.push(fp_line.tax_dest_id[0]); |
|||
found_taxes[fp_line.tax_src_id[0]] = true; |
|||
} |
|||
} |
|||
for (var i = 0, len = taxes_ids.length; i < len; i++) { |
|||
var tax_id = taxes_ids[i]; |
|||
if (!(tax_id in found_taxes)) { |
|||
taxes.push(tax_id); |
|||
} |
|||
} |
|||
return taxes; |
|||
}, |
|||
add_products: function (products) { |
|||
this._super(products); |
|||
var pos = posmodel.pos_widget.pos; |
|||
for (var id in this.product_by_id) { |
|||
if (this.product_by_id.hasOwnProperty(id)) { |
|||
var product = this.product_by_id[id]; |
|||
var orderline = new openerp.point_of_sale.Orderline({}, { |
|||
pos: pos, |
|||
order: null, |
|||
product: product, |
|||
price: product.price |
|||
}); |
|||
var prices = orderline.get_all_prices(); |
|||
this.product_by_id[id].price_with_taxes |
|||
= prices['priceWithTax'] |
|||
} |
|||
} |
|||
}, |
|||
find_product_rules: function (product) { |
|||
var len = this.pricelist_item_sorted.length; |
|||
var rules = []; |
|||
for (var i = 0; i < len; i++) { |
|||
var rule = this.pricelist_item_sorted[i]; |
|||
if ((rule.product_id && rule.product_id[0] == product.id) || |
|||
(rule.categ_id && product.categ_id |
|||
&& rule.categ_id[0] == product.categ_id[0])) { |
|||
rules.push(rule); |
|||
} |
|||
} |
|||
return rules; |
|||
} |
|||
}) |
|||
} |
@ -1,24 +0,0 @@ |
|||
/****************************************************************************** |
|||
* Point Of Sale - Pricelist for POS Odoo |
|||
* Copyright (C) 2014 Taktik (http://www.taktik.be)
|
|||
* @author Adil Houmadi <ah@taktik.be> |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License as |
|||
* published by the Free Software Foundation, either version 3 of the |
|||
* License, or (at your option) any later version. |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* You should have received a copy of the GNU Affero General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
* |
|||
******************************************************************************/ |
|||
openerp.pos_pricelist = function (instance) { |
|||
var module = instance.point_of_sale; |
|||
pos_pricelist_db(instance, module); |
|||
pos_pricelist_models(instance, module); |
|||
pos_pricelist_screens(instance, module); |
|||
pos_pricelist_widgets(instance, module); |
|||
}; |
998
pos_pricelist/static/src/js/models.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,32 +1,167 @@ |
|||
/****************************************************************************** |
|||
* Point Of Sale - Pricelist for POS Odoo |
|||
* Copyright (C) 2014 Taktik (http://www.taktik.be)
|
|||
* @author Adil Houmadi <ah@taktik.be> |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License as |
|||
* published by the Free Software Foundation, either version 3 of the |
|||
* License, or (at your option) any later version. |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* You should have received a copy of the GNU Affero General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
* |
|||
******************************************************************************/ |
|||
function pos_pricelist_screens(instance, module) { |
|||
|
|||
module.ClientListScreenWidget = module.ClientListScreenWidget.extend({ |
|||
/* Copyright 2018 Tecnativa - Jairo Llopis |
|||
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). */
|
|||
|
|||
odoo.define("pos_pricelist.screens", function (require) { |
|||
"use strict"; |
|||
|
|||
var core = require("web.core"); |
|||
var screens = require("point_of_sale.screens"); |
|||
var _t = core._t; |
|||
var exports = {}; |
|||
|
|||
screens.ScaleScreenWidget.include({ |
|||
_get_active_pricelist: function() { |
|||
var current_order = this.pos.get_order(); |
|||
var current_pricelist = this.pos.default_pricelist; |
|||
if (current_order) { |
|||
current_pricelist = current_order.pricelist; |
|||
} |
|||
return current_pricelist; |
|||
}, |
|||
|
|||
get_product_price: function () { |
|||
var result = this._super.apply(this, arguments); |
|||
var product = this.get_product(); |
|||
if (product) { |
|||
var pricelist = this._get_active_pricelist(); |
|||
result = product.get_price(pricelist, this.weight) || result; |
|||
} |
|||
return result; |
|||
}, |
|||
}); |
|||
|
|||
screens.DomCache.include({ |
|||
init: function () { |
|||
this._super.apply(this, arguments); |
|||
this.key_wrapper = function (key) { |
|||
return key; |
|||
}; |
|||
}, |
|||
|
|||
cache_node: function () { |
|||
arguments[0] = this.key_wrapper(arguments[0]); |
|||
return this._super.apply(this, arguments); |
|||
}, |
|||
|
|||
clear_node: function() { |
|||
arguments[0] = this.key_wrapper(arguments[0]); |
|||
return this._super.apply(this, arguments); |
|||
}, |
|||
|
|||
get_node: function() { |
|||
arguments[0] = this.key_wrapper(arguments[0]); |
|||
return this._super.apply(this, arguments); |
|||
}, |
|||
}); |
|||
|
|||
screens.ProductListWidget.include({ |
|||
init: function () { |
|||
this._super.apply(this, arguments); |
|||
this.pos.get('orders').bind( |
|||
'add remove change', |
|||
$.proxy(this, "renderElement") |
|||
); |
|||
this.pos.bind( |
|||
'change:selectedOrder', |
|||
$.proxy(this, "renderElement") |
|||
); |
|||
this.product_cache.key_wrapper = $.proxy( |
|||
this, |
|||
"calculate_cache_key" |
|||
); |
|||
}, |
|||
|
|||
calculate_cache_key: function (product) { |
|||
var result = product + ',' + this._get_active_pricelist().id; |
|||
return result; |
|||
}, |
|||
|
|||
_get_active_pricelist: function () { |
|||
var current_order = this.pos.get_order(); |
|||
var current_pricelist = this.pos.default_pricelist; |
|||
if (current_order) { |
|||
current_pricelist = current_order.pricelist; |
|||
} |
|||
return current_pricelist; |
|||
}, |
|||
}); |
|||
|
|||
screens.ClientListScreenWidget.include({ |
|||
save_changes: function () { |
|||
this._super(); |
|||
if (this.has_client_changed()) { |
|||
var currentOrder = this.pos.get('selectedOrder'); |
|||
var orderLines = currentOrder.get('orderLines').models; |
|||
var partner = currentOrder.get_client(); |
|||
this.pos.pricelist_engine.update_products_ui(partner); |
|||
this.pos.pricelist_engine.update_ticket(partner, orderLines); |
|||
var order = this.pos.get_order(), |
|||
pricelist = false; |
|||
if (this.new_client) { |
|||
pricelist = _.findWhere( |
|||
this.pos.pricelists, |
|||
{'id': this.new_client.property_product_pricelist[0]} |
|||
); |
|||
} |
|||
order.set_pricelist(pricelist || this.pos.default_pricelist); |
|||
} |
|||
return this._super.apply(this, arguments); |
|||
}, |
|||
}); |
|||
|
|||
exports.set_pricelist_button = screens.ActionButtonWidget.extend({ |
|||
template: 'SetPricelistButton', |
|||
init: function (parent, options) { |
|||
this._super(parent, options); |
|||
|
|||
this.pos.get('orders').bind('add remove change', function () { |
|||
this.renderElement(); |
|||
}, this); |
|||
|
|||
this.pos.bind('change:selectedOrder', function () { |
|||
this.renderElement(); |
|||
}, this); |
|||
}, |
|||
|
|||
button_click: function () { |
|||
var self = this; |
|||
|
|||
var pricelists = _.map(self.pos.pricelists, function (pricelist) { |
|||
return { |
|||
label: pricelist.name, |
|||
item: pricelist |
|||
}; |
|||
}); |
|||
|
|||
self.gui.show_popup('selection', { |
|||
title: _t('Select pricelist'), |
|||
list: pricelists, |
|||
confirm: function (pricelist) { |
|||
var order = self.pos.get_order(); |
|||
order.set_pricelist(pricelist); |
|||
}, |
|||
is_selected: function (pricelist) { |
|||
return pricelist.id === self.pos.get_order().pricelist.id; |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
get_current_pricelist_name: function () { |
|||
var name = _t('Pricelist'); |
|||
var order = this.pos.get_order(); |
|||
|
|||
if (order) { |
|||
var pricelist = order.pricelist; |
|||
|
|||
if (pricelist) { |
|||
name = pricelist.display_name; |
|||
} |
|||
} |
|||
} |
|||
return name; |
|||
}, |
|||
}); |
|||
|
|||
screens.define_action_button({ |
|||
'name': 'set_pricelist', |
|||
'widget': exports.set_pricelist_button, |
|||
'condition': function () { |
|||
return this.pos.pricelists.length > 1; |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
return exports; |
|||
}); |
@ -1,184 +0,0 @@ |
|||
/****************************************************************************** |
|||
* Point Of Sale - Pricelist for POS Odoo |
|||
* Copyright (C) 2014 Taktik (http://www.taktik.be)
|
|||
* @author Adil Houmadi <ah@taktik.be> |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License as |
|||
* published by the Free Software Foundation, either version 3 of the |
|||
* License, or (at your option) any later version. |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* You should have received a copy of the GNU Affero General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
* |
|||
******************************************************************************/ |
|||
(function () { |
|||
'use strict'; |
|||
|
|||
openerp.Tour.register({ |
|||
id: 'pos_pricelist_order', |
|||
name: 'Complete a order trough the Front-End using POS Pricelist', |
|||
path: '/web#model=pos.session.opening&action=point_of_sale.action_pos_session_opening', |
|||
mode: 'test', |
|||
steps: [ |
|||
{ |
|||
wait: 2000, |
|||
title: 'Wait for screen to be ready' |
|||
}, |
|||
{ |
|||
wait: 2000, |
|||
title: 'Load the Session', |
|||
waitNot: '.oe_loading:visible', |
|||
element: 'span:contains("Resume Session"),' + |
|||
'span:contains("Start Session")' |
|||
}, |
|||
{ |
|||
title: 'Loading Screen', |
|||
waitFor: '.loader' |
|||
}, |
|||
{ |
|||
wait: 2000, |
|||
title: 'The Point of Sale', |
|||
waitFor: '.pos' |
|||
}, |
|||
{ |
|||
title: "We will buy some Products!, let's add (POS Product 1)", |
|||
element: '.product-list ' + |
|||
'.product-name:contains("POS Product 1")' |
|||
}, |
|||
{ |
|||
wait: 5000, |
|||
title: 'The order total has been ' + |
|||
'updated to the correct value : 100€', |
|||
waitFor: '.order .total .value:contains("100.00 €")' |
|||
}, |
|||
{ |
|||
wait: 5000, |
|||
title: 'We will add one more unit!', |
|||
element: '.product-list ' + |
|||
'.product-name:contains("POS Product 1")' |
|||
}, |
|||
{ |
|||
wait: 4000, |
|||
title: 'We will add another unit', |
|||
element: '.product-list ' + |
|||
'.product-name:contains("POS Product 1")' |
|||
}, |
|||
{ |
|||
wait: 4000, |
|||
title: 'The order total should be updated ' + |
|||
': 270€ which means 90€/Unit (Rule 10% Discount from 3 Units)', |
|||
waitFor: '.order .total .value:contains("270.00 €")' |
|||
}, |
|||
{ |
|||
wait: 8000, |
|||
title: 'We will add another product', |
|||
element: '.product-list ' + |
|||
'.product-name:contains("POS Product 2")' |
|||
}, |
|||
{ |
|||
wait: 4000, |
|||
title: 'We will add another unit for this product ' + |
|||
'(POS Product 2)', |
|||
element: '.product-list ' + |
|||
'.product-name:contains("POS Product 2")' |
|||
}, |
|||
{ |
|||
wait: 4000, |
|||
title: "Let's verify the total that we should pay," + |
|||
" it's should be equal to : 450€, which means that <br>" + |
|||
"10% Discount if offered if we buy 2 units of " + |
|||
"(POS Product 2), Rule based on standard price", |
|||
waitFor: '.order .total .value:contains("450.00 €")' |
|||
}, |
|||
{ |
|||
wait: 10000, |
|||
title: "Now, we will add (POS Product 3), for this " + |
|||
"product if we buy more then 2 units <br>" + |
|||
"20% Discount is given by supplier to our customers", |
|||
element: '.product-list .product-name:contains("POS Product 3")' |
|||
}, |
|||
{ |
|||
wait: 10000, |
|||
title: 'We will add another unit for ' + |
|||
'this product (POS Product 3)', |
|||
element: '.product-list ' + |
|||
'.product-name:contains("POS Product 3")' |
|||
}, |
|||
{ |
|||
wait: 5000, |
|||
title: "Let's check the total (610€)", |
|||
waitFor: '.order .total .value:contains("610.00 €")' |
|||
}, |
|||
{ |
|||
wait: 5000, |
|||
title: "Now, we will add (POS Product 4), this product " + |
|||
"belong to (Comptuer) category in which " + |
|||
"we apply 5% if customer buy more then 2 products", |
|||
element: '.product-list ' + |
|||
'.product-name:contains("POS Product 4")' |
|||
}, |
|||
{ |
|||
wait: 10000, |
|||
title: 'We will add another unit for ' + |
|||
'this product (POS Product 4)', |
|||
element: '.product-list ' + |
|||
'.product-name:contains("POS Product 4")' |
|||
}, |
|||
{ |
|||
wait: 5000, |
|||
title: "Let's check the total again (800€)", |
|||
waitFor: '.order .total .value:contains("800.00 €")' |
|||
}, |
|||
{ |
|||
wait: 5000, |
|||
title: "Let's pay the order", |
|||
element: ".paypad-button:contains('Bank')" |
|||
}, |
|||
{ |
|||
wait: 1000, |
|||
title: "Let's accept the payment", |
|||
onload: function () { |
|||
window._print = window.print; |
|||
window.print = function () { |
|||
console.log('Print!') |
|||
}; |
|||
}, |
|||
element: ".button .iconlabel:contains('Validate'):visible" |
|||
}, |
|||
{ |
|||
wait: 1000, |
|||
title: "Let's finish the order", |
|||
element: ".button:not(.disabled) " + |
|||
".iconlabel:contains('Next'):visible" |
|||
}, |
|||
{ |
|||
wait: 1000, |
|||
onload: function () { |
|||
window.print = window._print; |
|||
window._print = undefined; |
|||
}, |
|||
title: "Let's wait for the order posting", |
|||
waitFor: ".oe_status.js_synch .js_connected:visible" |
|||
}, |
|||
{ |
|||
wait: 1000, |
|||
title: "Let's close the Point of Sale", |
|||
element: ".header-button:contains('Close')" |
|||
}, |
|||
{ |
|||
title: "Let's confirm", |
|||
element: ".header-button.confirm:contains('Confirm')" |
|||
}, |
|||
{ |
|||
title: "Wait for the backend to ready itself", |
|||
element: 'span:contains("Resume Session"),' + |
|||
'span:contains("Start Session")' |
|||
} |
|||
] |
|||
}); |
|||
|
|||
})(); |
@ -1,87 +0,0 @@ |
|||
/****************************************************************************** |
|||
* Point Of Sale - Pricelist for POS Odoo |
|||
* Copyright (C) 2014 Taktik (http://www.taktik.be)
|
|||
* @author Adil Houmadi <ah@taktik.be> |
|||
* |
|||
* This program is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License as |
|||
* published by the Free Software Foundation, either version 3 of the |
|||
* License, or (at your option) any later version. |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* You should have received a copy of the GNU Affero General Public License |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
* |
|||
******************************************************************************/ |
|||
function pos_pricelist_widgets(instance, module) { |
|||
|
|||
var round_di = instance.web.round_decimals; |
|||
|
|||
module.OrderWidget = module.OrderWidget.extend({ |
|||
set_value: function (val) { |
|||
this._super(val); |
|||
var order = this.pos.get('selectedOrder'); |
|||
if (this.editable && order.getSelectedLine()) { |
|||
var mode = this.numpad_state.get('mode'); |
|||
if (mode === 'price') { |
|||
order.getSelectedLine().set_manual_price(true); |
|||
} |
|||
} |
|||
} |
|||
}); |
|||
|
|||
module.OrderButtonWidget = module.OrderButtonWidget.extend({ |
|||
selectOrder: function (event) { |
|||
this._super(event); |
|||
var partner = this.order.get_client() |
|||
? this.order.get_client() |
|||
: false; |
|||
this.pos.pricelist_engine.update_products_ui(partner); |
|||
} |
|||
}); |
|||
|
|||
instance.point_of_sale.ProductListWidget.include({ |
|||
init: function (parent, options) { |
|||
this._super(parent, options); |
|||
this.display_price_with_taxes = false; |
|||
if ( |
|||
posmodel |
|||
&& posmodel.config |
|||
&& posmodel.config.display_price_with_taxes |
|||
) { |
|||
this.display_price_with_taxes |
|||
= posmodel.config.display_price_with_taxes |
|||
} |
|||
}, |
|||
renderElement: function () { |
|||
this._super(); |
|||
var order = posmodel.get_order(); |
|||
var customer = null; |
|||
if(order) { |
|||
customer = order.get_client(); |
|||
} |
|||
this.pos.pricelist_engine.update_products_ui(customer); |
|||
} |
|||
}); |
|||
|
|||
module.PosBaseWidget.include({ |
|||
format_pr: function(amount, precision) { |
|||
// Do not call _super because no addon or XML is using this method
|
|||
var currency = (this.pos && this.pos.currency) ? this.pos.currency : {symbol:'$', position: 'after', rounding: 0.01, decimals: 2}; |
|||
var decimals = currency.decimals; |
|||
|
|||
if (precision && (typeof this.pos.dp[precision]) !== undefined) { |
|||
decimals = this.pos.dp[precision]; |
|||
} |
|||
|
|||
if (typeof amount === 'number') { |
|||
amount = round_di(amount,decimals).toFixed(decimals); |
|||
amount = openerp.instances[this.session.name].web.format_value(round_di(amount, decimals), { type: 'float', digits: [69, decimals]}); |
|||
} |
|||
return amount |
|||
} |
|||
}); |
|||
} |
|||
|
@ -1,37 +1,51 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<templates id="template" xml:space="preserve"> |
|||
<t t-extend="Product"> |
|||
<t t-jquery=".product-img" t-operation="replace"> |
|||
<div class="product-img"> |
|||
<img t-att-src='image_url' /> |
|||
<t t-if="!product.to_weight"> |
|||
<span class="price-tag"> |
|||
<t t-if="widget.display_price_with_taxes"> |
|||
<t t-esc="widget.format_currency(product.price_with_taxes,'Product Price')"/> |
|||
</t> |
|||
<t t-if="!widget.display_price_with_taxes"> |
|||
<t t-esc="widget.format_currency(product.price,'Product Price')"/> |
|||
</t> |
|||
</span> |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2018 Tecnativa - Jairo Llopis |
|||
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). --> |
|||
|
|||
<templates> |
|||
<t t-name="SetPricelistButton"> |
|||
<div class='control-button o_pricelist_button'> |
|||
<i class='fa fa-th-list' /> <t t-esc='widget.get_current_pricelist_name()'/> |
|||
</div> |
|||
</t> |
|||
|
|||
<t t-extend="ClientDetailsEdit"> |
|||
<t t-jquery=".client-details-right" t-operation="append"> |
|||
<div t-attf-class='client-detail #{widget.pos.pricelists.length <= 1 ? "oe_hidden" : ""}'> |
|||
<span class='label'>Pricelist</span> |
|||
<select class='detail needsclick' name='property_product_pricelist'> |
|||
<t t-foreach='widget.pos.pricelists' t-as='pricelist'> |
|||
<option t-att-value='pricelist.id' |
|||
t-att-selected="partner.property_product_pricelist ? (pricelist.id === partner.property_product_pricelist[0] ? true : undefined) : undefined"> |
|||
<t t-esc='pricelist.display_name'/> |
|||
</option> |
|||
</t> |
|||
</select> |
|||
</div> |
|||
</t> |
|||
</t> |
|||
|
|||
<t t-extend="ClientDetails"> |
|||
<t t-jquery=".client-details-right" t-operation="append"> |
|||
<div t-attf-class='client-detail #{widget.pos.pricelists.length <= 1 ? "oe_hidden" : ""}'> |
|||
<span class='label'>Pricelist</span> |
|||
<t t-if='partner.property_product_pricelist'> |
|||
<span class='detail property_product_pricelist'><t t-esc='partner.property_product_pricelist[1]'/></span> |
|||
</t> |
|||
<t t-if="product.to_weight"> |
|||
<span class="price-tag"> |
|||
<t t-if="widget.display_price_with_taxes"> |
|||
<t t-esc="widget.format_currency(product.price_with_taxes,'Product Price')+'/Kg'"/> |
|||
</t> |
|||
<t t-if="!widget.display_price_with_taxes"> |
|||
<t t-esc="widget.format_currency(product.price,'Product Price')+'/Kg'"/> |
|||
</t> |
|||
</span> |
|||
<t t-if='!partner.property_product_pricelist'> |
|||
<span class='detail property_product_pricelist empty'>N/A</span> |
|||
</t> |
|||
</div> |
|||
</t> |
|||
</t> |
|||
<t t-extend="PosTicket"> |
|||
<t t-jquery="t[t-esc='orderline.get_quantity_str_with_unit()']" t-operation="after"> |
|||
<t t-if="orderline.quantity != 1"> |
|||
x<t t-esc="widget.format_pr(orderline.get_display_unit_price())"/> |
|||
</t> |
|||
|
|||
<t t-extend="Product"> |
|||
<t t-jquery=".price-tag:eq(0)" t-operation="inner"> |
|||
<t t-esc="widget.format_currency(product.get_price(widget._get_active_pricelist(), 1),'Product Price')"/> |
|||
</t> |
|||
|
|||
<t t-jquery=".price-tag:eq(0)" t-operation="inner"> |
|||
<t t-esc="widget.format_currency(product.get_price(widget._get_active_pricelist(), 1),'Product Price')+'/'+widget.pos.units_by_id[product.uom_id[0]].name"/> |
|||
</t> |
|||
</t> |
|||
</templates> |
|||
</templates> |
@ -0,0 +1,16 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2018 Tecnativa - Jairo Llopis |
|||
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). --> |
|||
|
|||
<odoo> |
|||
<template id="assets" inherit_id="point_of_sale.assets"> |
|||
<xpath expr="."> |
|||
<script |
|||
type="text/javascript" |
|||
src="/pos_pricelist/static/src/js/models.js"/> |
|||
<script |
|||
type="text/javascript" |
|||
src="/pos_pricelist/static/src/js/screens.js"/> |
|||
</xpath> |
|||
</template> |
|||
</odoo> |
@ -1,28 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# Point Of Sale - Pricelist for POS Odoo |
|||
# Copyright (C) 2014 Taktik (http://www.taktik.be) |
|||
# @author Adil Houmadi <ah@taktik.be> |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
import openerp.tests |
|||
|
|||
|
|||
@openerp.tests.common.at_install(False) |
|||
@openerp.tests.common.post_install(True) |
|||
class TestPOS(openerp.tests.HttpCase): |
|||
def test_01_pos(self): |
|||
self.phantom_js("/", "openerp.Tour.run('pos_pricelist_order', 'test')", |
|||
"openerp.Tour.tours.pos_pricelist_order", |
|||
login="admin") |
@ -1,28 +0,0 @@ |
|||
<?xml version="1.0"?> |
|||
<openerp> |
|||
<data> |
|||
|
|||
<record id="view_pos_pos_form" model="ir.ui.view"> |
|||
<field name="name">pos.order</field> |
|||
<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="//field[@name='lines']/tree/field[@name='discount']" position="after"> |
|||
<field name="tax_ids" widget="many2many_tags"/> |
|||
</xpath> |
|||
<page string="Payments" position="after"> |
|||
<page string="Taxes"> |
|||
<field name="taxes"> |
|||
<tree editable="bottom" string="Taxes detail"> |
|||
<field name="name"/> |
|||
<field name="base"/> |
|||
<field name="amount"/> |
|||
</tree> |
|||
</field> |
|||
</page> |
|||
</page> |
|||
</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</openerp> |
@ -0,0 +1,41 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2018 Tecnativa - Jairo Llopis |
|||
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). --> |
|||
|
|||
<odoo> |
|||
<record id="view_pos_config_form" model="ir.ui.view"> |
|||
<field name="name">pos.config.form.view</field> |
|||
<field name="model">pos.config</field> |
|||
<field name="priority">100</field> |
|||
<field name="inherit_id" ref="point_of_sale.view_pos_config_form"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//field[@name='pricelist_id']" position="replace"/> |
|||
|
|||
<xpath expr="//sheet"> |
|||
<group |
|||
name="pricelist_setting" |
|||
string="Pricelists" |
|||
groups="product.group_sale_pricelist"> |
|||
<group> |
|||
<field name="use_pricelist"/> |
|||
</group> |
|||
<group attrs="{'invisible': [('use_pricelist','=',False)], 'required' : [('use_pricelist', '=', True)]}"> |
|||
<field |
|||
name="available_pricelist_ids" |
|||
widget="many2many_tags"/> |
|||
<field |
|||
name="pricelist_id" |
|||
domain="[('id', 'in', available_pricelist_ids)]" |
|||
options="{'no_create': True}"/> |
|||
<button |
|||
name="%(product.product_pricelist_action2)d" |
|||
icon="fa-arrow-right" |
|||
type="action" |
|||
string="Pricelists" |
|||
class="btn-link"/> |
|||
</group> |
|||
</group> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
</odoo> |
@ -1,29 +0,0 @@ |
|||
<openerp> |
|||
<data> |
|||
<template id="pos_pricelist_assets_backend" |
|||
name="pos_pricelist_assets_backend" |
|||
inherit_id="point_of_sale.assets_backend"> |
|||
<xpath expr="." position="inside"> |
|||
<script src="/pos_pricelist/static/src/js/db.js" |
|||
type="text/javascript"></script> |
|||
<script src="/pos_pricelist/static/src/js/models.js" |
|||
type="text/javascript"></script> |
|||
<script src="/pos_pricelist/static/src/js/widgets.js" |
|||
type="text/javascript"></script> |
|||
<script src="/pos_pricelist/static/src/js/screens.js" |
|||
type="text/javascript"></script> |
|||
<script src="/pos_pricelist/static/src/js/tests.js" |
|||
type="text/javascript"></script> |
|||
<script src="/pos_pricelist/static/src/js/main.js" |
|||
type="text/javascript"></script> |
|||
</xpath> |
|||
</template> |
|||
|
|||
<template id="pos_pricelist_assets" name="pos_pricelist_css" inherit_id="point_of_sale.index"> |
|||
<xpath expr="//script[@id='loading-script']" position="before"> |
|||
<link rel="stylesheet" href="/pos_pricelist/static/src/css/style.css"/> |
|||
</xpath> |
|||
</template> |
|||
|
|||
</data> |
|||
</openerp> |
@ -1,15 +0,0 @@ |
|||
<?xml version="1.0"?> |
|||
<openerp> |
|||
<data> |
|||
<record id="view_pos_config_form_pos_pricelist" model="ir.ui.view"> |
|||
<field name="name">view.pos.config.form.pos.pricelist</field> |
|||
<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_big_scrollbars" position="after"> |
|||
<field name="display_price_with_taxes"/> |
|||
</field> |
|||
</field> |
|||
</record> |
|||
</data> |
|||
</openerp> |
@ -0,0 +1 @@ |
|||
oca.decorators |
Write
Preview
Loading…
Cancel
Save
Reference in new issue