[IMP] website_sale_aplicoop: surface the tax display setting on the Eskaera page

Pricing now follows website_sale, which includes the website's `Display
Product Prices`. That setting defaults to tax-excluded in 18.0, so a website
nobody configured shows Eskaera prices without VAT -- correct behaviour, but
easy to read as a bug when the members are consumers and expect the price they
will pay.

The setting is a related field website_sale already exposes, so it now appears
in the Eskaera block too, right where the co-op switches the feature on, rather
than only under eCommerce.

Tests cover both values on the shop and the listing paths, so the tax-excluded
case is a decision on record instead of a surprise.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
GitHub Copilot 2026-08-17 19:13:57 +02:00
parent 5a2f5d120f
commit f81c1ca8e7
2 changed files with 76 additions and 0 deletions

View file

@ -129,6 +129,67 @@ class TestStandardPricelistResolution(PricingDelegationCommon, TransactionCase):
self.assertEqual(resolved, expected)
@tagged("post_install", "-at_install")
class TestTaxDisplayFollowsTheWebsite(PricingDelegationCommon, TransactionCase):
"""Displayed prices honour the website's `Display Product Prices`.
Eskaera used to hardcode the tax-included display and ignore the setting.
Now it follows website_sale, which means a website left on the Odoo default
(`tax_excluded`) shows prices without VAT -- correct, but surprising enough
to be worth pinning down here.
"""
def setUp(self):
super().setUp()
self.pricelist = self._create_pricelist("Display PL")
self.tax_21 = self._create_tax("IVA 21%", 21.0)
self.product = self._create_product("Display Product", 100.0, self.tax_21)
def _price(self):
return self.controller._get_pricing_info(
self.product, self.pricelist, quantity=1.0
)
def test_gross_price_on_a_tax_included_website(self):
"""A consumer-facing website quotes what the member pays."""
self.website.show_line_subtotals_tax_selection = "tax_included"
pricing = self._price()
self.assertAlmostEqual(pricing["price"], 121.0, places=2)
self.assertAlmostEqual(pricing["price_unit"], 100.0, places=2)
self.assertTrue(pricing["tax_included"])
def test_net_price_on_a_tax_excluded_website(self):
"""A website set to tax-excluded shows the net price."""
self.website.show_line_subtotals_tax_selection = "tax_excluded"
pricing = self._price()
self.assertAlmostEqual(pricing["price"], 100.0, places=2)
self.assertAlmostEqual(pricing["price_unit"], 100.0, places=2)
self.assertFalse(pricing["tax_included"])
def test_the_setting_is_what_moves_the_price(self):
"""Nothing but the website setting changes between the two."""
self.website.show_line_subtotals_tax_selection = "tax_included"
gross = self._price()["price"]
self.website.show_line_subtotals_tax_selection = "tax_excluded"
net = self._price()["price"]
self.assertAlmostEqual(gross - net, 21.0, places=2)
def test_batched_listing_follows_the_same_setting(self):
"""The listing path must not disagree with the single-product one."""
self.website.show_line_subtotals_tax_selection = "tax_excluded"
batched = self.controller._compute_price_info(self.product, self.pricelist)
self.assertAlmostEqual(batched[self.product.id]["price"], 100.0, places=2)
self.assertFalse(batched[self.product.id]["tax_included"])
@tagged("post_install", "-at_install")
class TestTaxIncludedFiscalPosition(PricingDelegationCommon, TransactionCase):
"""A remapped tax-included tax must rebase the displayed price."""

View file

@ -21,6 +21,21 @@
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" invisible="not eskaera_enabled">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<label for="show_line_subtotals_tax_selection" string="Product Prices"/>
<div class="text-muted">
Eskaera shows the same prices as the shop. Members
are consumers, so this is normally "Tax Included".
</div>
<div class="content-group">
<div class="mt16">
<field name="show_line_subtotals_tax_selection" class="o_light_label" widget="radio"/>
</div>
</div>
</div>
</div>
</div>
<h2>Shop Performance</h2>
<div class="row mt16 o_settings_container" id="eskaera_shop_settings">