-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by legalsylvain
- Loading branch information
Showing
25 changed files
with
454 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Copyright (C) 2022-Today GRAP (http://www.grap.coop) | ||
# @author Sylvain LE GAL (https://twitter.com/legalsylvain) | ||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html | ||
|
||
{ | ||
"name": "Point of Sale - Display All Discounts", | ||
"summary": "Display discount amount on PoS cashier screen and print it on ticket" | ||
"calculated from the difference between a sale with default pricelist", | ||
"version": "16.0.1.0.0", | ||
"category": "Point of Sale", | ||
"maintainers": ["legalsylvain"], | ||
"author": "GRAP,Odoo Community Association (OCA)", | ||
"website": "https://github.com/OCA/pos", | ||
"license": "AGPL-3", | ||
"depends": ["point_of_sale"], | ||
"data": [ | ||
"views/view_product_template.xml", | ||
], | ||
"assets": { | ||
"point_of_sale.assets": [ | ||
"pos_discount_all/static/src/js/models.js", | ||
"pos_discount_all/static/src/xml/OrderSummary.xml", | ||
], | ||
"web.assets_tests": [ | ||
"pos_discount_all/tests/tours/PosDiscountAllTour.tour.js", | ||
], | ||
}, | ||
"demo": [ | ||
"demo/product_product.xml", | ||
"demo/res_groups.xml", | ||
], | ||
"installable": True, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<!-- | ||
Copyright (C) 2022-Today GRAP (http://www.grap.coop) | ||
@author Sylvain LE GAL (https://twitter.com/legalsylvain) | ||
License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html | ||
--> | ||
<odoo> | ||
<record id="product_discount" model="product.product"> | ||
<field name="name">Discount Product</field> | ||
<field name="is_discount" eval="True" /> | ||
<field name="list_price">-1.0</field> | ||
<field name="taxes_id" eval="[(6,0,[])]" /> | ||
<field name="available_in_pos" eval="True" /> | ||
</record> | ||
</odoo> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<!-- | ||
Copyright (C) 2022-Today GRAP (http://www.grap.coop) | ||
@author Sylvain LE GAL (https://twitter.com/legalsylvain) | ||
License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html | ||
--> | ||
<odoo> | ||
<record id="product.group_sale_pricelist" model="res.groups"> | ||
<field name="users" eval="[(4, ref('base.user_admin'))]" /> | ||
</record> | ||
|
||
<record id="product.group_product_pricelist" model="res.groups"> | ||
<field name="users" eval="[(4, ref('base.user_admin'))]" /> | ||
</record> | ||
</odoo> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from . import pos_session | ||
from . import product_template |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Copyright (C) 2022-Today GRAP (http://www.grap.coop) | ||
# @author Sylvain LE GAL (https://twitter.com/legalsylvain) | ||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html | ||
|
||
from odoo import models | ||
|
||
|
||
class PosSession(models.Model): | ||
_inherit = "pos.session" | ||
|
||
def _loader_params_product_product(self): | ||
res = super()._loader_params_product_product() | ||
res["search_params"]["fields"].append("is_discount") | ||
return res |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Copyright (C) 2022-Today GRAP (http://www.grap.coop) | ||
# @author Sylvain LE GAL (https://twitter.com/legalsylvain) | ||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html | ||
|
||
from odoo import fields, models | ||
|
||
|
||
class ProductTemplate(models.Model): | ||
_inherit = "product.template" | ||
|
||
is_discount = fields.Boolean( | ||
string="Is a Discount", | ||
help="Check this box if you use this product to realize" | ||
" discount on sale. If check the sale lines will be" | ||
" ignored when computing the amount without discount." | ||
" If you use 'Pos Discount' Odoo module, you should" | ||
" check this box for the product you configured" | ||
" as the 'Discount Product' on your PoS config.", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
* Go to "Point of Sale > Products" | ||
* Create or edit your discount products | ||
* Check the box "Is a Discount" | ||
|
||
.. image:: ../static/description/product_template_form.png |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* Sylvain LE GAL (https://twitter.com/legalsylvain) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
The development of this module has been financially supported by: | ||
|
||
* UGESS, Union Nationale des Groupements des épiceries Sociales et Solidaires (https://ugess.org/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
This module extends the functionality of point of sale module, to | ||
display on the PoS ticket, the amount of the discount applied for this sale. | ||
Contrary to the logic of Odoo and the OCA | ||
(https://github.com/OCA/sale-workflow/tree/14.0/sale_discount_display_amount) | ||
the amount of the discount is the difference between the theoretical sale with the default price list and the actual sale amount. | ||
So it take into accounts: | ||
|
||
- explicit discount set on pos.order.line. (as for odoo ``sale`` module) | ||
- fixed price set on pos.order.line | ||
- discount generated by specific pricelist | ||
|
||
Also the module ignores in the computation of undiscounted amount lines, the | ||
lines with a 'Discount Product'. | ||
(see the configure section.) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
**Note** | ||
|
||
In the javascript file, we could write | ||
|
||
.. code-block:: javascript | ||
const PosDiscountAllOrder = () => | ||
class extends Order { | ||
} | ||
However, this code doesn't work if ``pos_sale`` module is installed. For that | ||
reason we code the declaration as Odoo does, and add eslint exception. | ||
|
||
|
||
.. code-block:: javascript | ||
// eslint-disable-next-line no-shadow | ||
const PosDiscountAllOrder = (Order) => | ||
// eslint-disable-next-line no-shadow | ||
class PosDiscountAllOrder extends Order { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
Open your point of Sale | ||
|
||
Make an order. for exemple, | ||
- select the product 'Conference chair (39.40$)' | ||
- select the pricelist -10% | ||
- add a discount of 1$ | ||
|
||
The total discount is 1$ + 10% * 39.40 = 4.94$ | ||
|
||
.. image:: ../static/description/order_summary.png | ||
|
||
Note, the discount displayed on the ticket is updated, to take into account all the discount. | ||
|
||
.. image:: ../static/description/pos_receipt.png |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
Copyright (C) 2022-Today GRAP (http://www.grap.coop) | ||
@author Sylvain LE GAL (https://twitter.com/legalsylvain) | ||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
*/ | ||
|
||
odoo.define("pos_discount_all.models", function (require) { | ||
"use strict"; | ||
|
||
const {Order, Orderline} = require("point_of_sale.models"); | ||
const Registries = require("point_of_sale.Registries"); | ||
const {round_precision: round_pr} = require("web.utils"); | ||
|
||
// eslint-disable-next-line no-shadow | ||
const PosDiscountAllOrder = (Order) => | ||
// eslint-disable-next-line no-shadow | ||
class PosDiscountAllOrder extends Order { | ||
// eslint-disable-line no-shadow | ||
// @override | ||
_get_ignored_product_ids_total_discount() { | ||
const productIds = super._get_ignored_product_ids_total_discount( | ||
...arguments | ||
); | ||
_.map(this.pos.db.product_by_id, function (product) { | ||
if (product.is_discount) { | ||
productIds.push(product.id); | ||
} | ||
}); | ||
return productIds; | ||
} | ||
|
||
get_total_with_tax_without_any_discount() { | ||
return round_pr( | ||
this.orderlines.reduce(function (sum, orderLine) { | ||
return ( | ||
sum + | ||
orderLine.get_total_without_any_discount().total_included | ||
); | ||
}, 0), | ||
this.pos.currency.rounding | ||
); | ||
} | ||
|
||
get_discount_amount_with_tax_without_any_discount() { | ||
return round_pr( | ||
this.get_total_with_tax_without_any_discount() - | ||
this.get_total_with_tax(), | ||
this.pos.currency.rounding | ||
); | ||
} | ||
|
||
export_for_printing() { | ||
var receipt = super.export_for_printing(...arguments); | ||
receipt.total_discount = | ||
this.get_discount_amount_with_tax_without_any_discount(); | ||
return receipt; | ||
} | ||
}; | ||
|
||
Registries.Model.extend(Order, PosDiscountAllOrder); | ||
|
||
// eslint-disable-next-line no-shadow | ||
const PosDiscountAllOrderLine = (Orderline) => | ||
// eslint-disable-next-line no-shadow | ||
class PosDiscountAllOrderLine extends Orderline { | ||
// eslint-disable-line no-shadow | ||
get_total_without_any_discount() { | ||
var product = this.get_product(); | ||
const ignored_product_ids = | ||
this.order._get_ignored_product_ids_total_discount(); | ||
if (ignored_product_ids.includes(product.id)) { | ||
return { | ||
total_excluded: 0.0, | ||
total_included: 0.0, | ||
}; | ||
} | ||
var price_unit_without_any_discount = product.get_price( | ||
this.pos.default_pricelist, | ||
this.get_quantity() | ||
); | ||
var taxes_ids = this.tax_ids || product.taxes_id; | ||
taxes_ids = _.filter(taxes_ids, (t) => t in this.pos.taxes_by_id); | ||
var product_taxes = this.pos.get_taxes_after_fp( | ||
taxes_ids, | ||
this.order.fiscal_position | ||
); | ||
var all_taxes_without_any_discount = this.compute_all( | ||
product_taxes, | ||
price_unit_without_any_discount, | ||
this.get_quantity(), | ||
this.pos.currency.rounding | ||
); | ||
return { | ||
total_excluded: all_taxes_without_any_discount.total_excluded, | ||
total_included: all_taxes_without_any_discount.total_included, | ||
}; | ||
} | ||
}; | ||
|
||
Registries.Model.extend(Orderline, PosDiscountAllOrderLine); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
<!-- | ||
Copyright (C) 2022-Today GRAP (http://www.grap.coop) | ||
@author Sylvain LE GAL (https://twitter.com/legalsylvain) | ||
License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html | ||
--> | ||
<templates id="template" xml:space="preserve"> | ||
|
||
<t | ||
t-name="OrderSummary" | ||
t-inherit="point_of_sale.OrderSummary" | ||
t-inherit-mode="extension" | ||
owl="1" | ||
> | ||
<xpath expr="//div[@t-if='_tax.hasTax']" position="after"> | ||
<t | ||
t-set="_discount_amount" | ||
t-value="props.order.get_discount_amount_with_tax_without_any_discount()" | ||
/> | ||
<div t-if="_discount_amount" class="subentry"> | ||
Discount Amount: | ||
<span class="value discount-amount"> | ||
<t t-esc="env.pos.format_currency(_discount_amount)" /> | ||
</span> | ||
</div> | ||
</xpath> | ||
</t> | ||
|
||
</templates> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import test_module |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Copyright (C) 2022-Today GRAP (http://www.grap.coop) | ||
# @author Sylvain LE GAL (https://twitter.com/legalsylvain) | ||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html | ||
|
||
|
||
from odoo.tests import tagged | ||
|
||
from odoo.addons.point_of_sale.tests.test_frontend import TestPointOfSaleHttpCommon | ||
|
||
|
||
@tagged("post_install", "-at_install") | ||
class TestUi(TestPointOfSaleHttpCommon): | ||
def test_pos_discount_all(self): | ||
|
||
pricelist = self.env["product.pricelist"].create( | ||
{ | ||
"name": "Pricelist -10%", | ||
} | ||
) | ||
self.env["product.pricelist.item"].create( | ||
{ | ||
"pricelist_id": pricelist.id, | ||
"name": "Pricelist Item -10%", | ||
"applied_on": "3_global", | ||
"compute_price": "percentage", | ||
"percent_price": 10, | ||
} | ||
) | ||
self.main_pos_config.write( | ||
{ | ||
"use_pricelist": True, | ||
"available_pricelist_ids": [(4, pricelist.id)], | ||
} | ||
) | ||
|
||
self.env["product.product"].create( | ||
{ | ||
"name": "Generic Product", | ||
"available_in_pos": True, | ||
"list_price": 10.0, | ||
"taxes_id": False, | ||
} | ||
) | ||
|
||
self.env["product.product"].create( | ||
{ | ||
"name": "Discount Product", | ||
"is_discount": True, | ||
"available_in_pos": True, | ||
"list_price": -1.0, | ||
"taxes_id": False, | ||
} | ||
) | ||
|
||
self.main_pos_config.open_ui() | ||
|
||
self.start_tour( | ||
f"/pos/ui?config_id={self.main_pos_config.id}", | ||
"PosDiscountAllTour", | ||
login="accountman", | ||
) |
Oops, something went wrong.