[DOC] product_pricelist_total_margin: Update documentation for v1.1.0
- Update README with margin_type field documentation - Add detailed explanations for both calculation methods: * Markup (on cost): PVP = Cost × (1 + markup%) * Commercial Margin (on PVP): PVP = Cost / (1 - margin%) - Add examples comparing both methods - Update features list with new capabilities - Update configuration steps to include margin_type selector - Update technical details with new field specifications - Update test coverage section (11 tests) - Add logging examples for both methods - Update changelog with v18.0.1.1.0 release notes - Bump version to 18.0.1.1.0 in __manifest__.py - Update summary to reflect new features
This commit is contained in:
parent
55406ca22d
commit
07cc0eb517
2 changed files with 76 additions and 13 deletions
|
|
@ -22,20 +22,36 @@ Pricelist B: 25% markup → 4.446 × 1.25 = 5.5575€
|
|||
|
||||
With this module, you can calculate the **total margin** by summing percentages:
|
||||
|
||||
#### Option 1: Markup (on cost)
|
||||
```
|
||||
Base price: 4.68€
|
||||
Total margin: -5% + 25% = 20%
|
||||
Final price: 4.68 × 1.20 = 5.616€
|
||||
Effective margin: (5.616 - 4.68) / 5.616 = 16.67%
|
||||
```
|
||||
|
||||
**Result:** 5.62€ (effective margin: 20%)
|
||||
**Result:** 5.62€ (20% markup on cost)
|
||||
|
||||
#### Option 2: Commercial Margin (on PVP)
|
||||
```
|
||||
Base price: 4.68€
|
||||
Total margin: -5% + 25% = 20%
|
||||
Final price: 4.68 / 0.80 = 5.85€
|
||||
Effective margin: (5.85 - 4.68) / 5.85 = 20%
|
||||
```
|
||||
|
||||
**Result:** 5.85€ (20% commercial margin on PVP)
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ **Additive margin calculation** across chained pricelists
|
||||
- ✅ **Two calculation methods:**
|
||||
- **Markup (on cost):** `PVP = Cost × (1 + markup%)`
|
||||
- **Commercial Margin (on PVP):** `PVP = Cost / (1 - margin%)`
|
||||
- ✅ **Opt-in via checkbox** - doesn't affect existing pricelists
|
||||
- ✅ **Compatible with custom bases** (`last_purchase_price` from `product_sale_price_from_pricelist`)
|
||||
- ✅ **Supports all formula extras** (price_round, price_surcharge, price_min/max_margin)
|
||||
- ✅ **Global min/max margin limits** (configurable in Settings > Sales)
|
||||
- ✅ **Multi-level chains** - works with 2+ pricelists in sequence
|
||||
- ✅ **Currency conversion** - handles multi-currency scenarios
|
||||
- ✅ **Detailed logging** - debug pricing calculations easily
|
||||
|
|
@ -84,7 +100,10 @@ Create a pricelist that chains to the base one:
|
|||
- **Based on:** Other Pricelist → Select "Base Pricelist - Last Purchase Price"
|
||||
- **Price Computation:** Formula
|
||||
- **Discount:** -25% (negative = 25% markup)
|
||||
- **☑️ Use Total Margin:** Check this box!
|
||||
- **☑️ Total Margin Mode:** Check this box!
|
||||
- **Calculation Method:** Choose between:
|
||||
- **Markup (on cost)** - Default, calculates `PVP = Cost × (1 + markup%)`
|
||||
- **Commercial Margin (on PVP)** - Calculates `PVP = Cost / (1 - margin%)`
|
||||
|
||||
### Step 3: Assign to Products
|
||||
|
||||
|
|
@ -113,19 +132,38 @@ After product category (+25%): 5.5575€ ❌ Wrong effective margin: 18.8%
|
|||
Product: Flour (cesta básica, repostería)
|
||||
Purchase price: 4.68€
|
||||
Total margin: -5% + 25% = 20%
|
||||
Final price: 5.616€ ✅ Correct effective margin: 20%
|
||||
|
||||
Option 1 - Markup:
|
||||
Final price: 4.68 × 1.20 = 5.616€ ✅ Markup 20% on cost
|
||||
|
||||
Option 2 - Commercial Margin:
|
||||
Final price: 4.68 / 0.80 = 5.85€ ✅ Margin 20% on PVP
|
||||
```
|
||||
|
||||
**Which method to choose?**
|
||||
- **Markup (on cost):** Traditional markup calculation, margin on cost base
|
||||
- **Commercial Margin (on PVP):** Retail/commercial margin, ensures exact margin percentage on final price
|
||||
|
||||
## Technical Details
|
||||
|
||||
### New Field
|
||||
### New Fields
|
||||
|
||||
- **Model:** `product.pricelist.item`
|
||||
- **Field:** `use_total_margin` (Boolean)
|
||||
|
||||
#### `use_total_margin` (Boolean)
|
||||
- **Default:** False (opt-in)
|
||||
- **Visibility:** Only shown when:
|
||||
- `compute_price = 'formula'`
|
||||
- `base = 'pricelist'` (chained pricelist)
|
||||
- **Purpose:** Enable additive margin calculation instead of compound
|
||||
|
||||
#### `margin_type` (Selection)
|
||||
- **Default:** `'markup'`
|
||||
- **Options:**
|
||||
- `'markup'` - Markup (on cost): `PVP = Cost × (1 + markup%)`
|
||||
- `'margin'` - Commercial Margin (on PVP): `PVP = Cost / (1 - margin%)`
|
||||
- **Visibility:** Only shown when `use_total_margin = True`
|
||||
- **Purpose:** Choose the calculation method for the total margin
|
||||
|
||||
### Methods
|
||||
|
||||
|
|
@ -159,9 +197,14 @@ Main override that:
|
|||
1. Checks if `use_total_margin=True` and conditions are met
|
||||
2. Calls helper methods to get base price and margins
|
||||
3. Sums margins additively: `total_margin = sum(margins)`
|
||||
4. Applies total margin: `price = base_price * (1 + total_margin / 100)`
|
||||
5. Applies formula extras
|
||||
6. Falls back to standard behavior if conditions not met
|
||||
4. Applies global min/max margin limits if configured
|
||||
5. Applies total margin using selected method:
|
||||
- **Markup:** `price = base_price * (1 + total_margin / 100)`
|
||||
- **Commercial Margin:** `price = base_price / (1 - total_margin / 100)`
|
||||
6. Applies formula extras
|
||||
7. Falls back to standard behavior if conditions not met
|
||||
|
||||
**Safety:** Commercial margin >= 100% is capped at 99% to avoid division by zero
|
||||
|
||||
### Logging
|
||||
|
||||
|
|
@ -170,7 +213,12 @@ All calculations are logged with `[TOTAL MARGIN]` prefix for easy debugging:
|
|||
```python
|
||||
_logger.info("[TOTAL MARGIN] Item %s: base=%s, margin=%.2f%%", ...)
|
||||
_logger.info("[TOTAL MARGIN] Margins: ['5.0%', '25.0%'] = 20.0% total")
|
||||
_logger.info("[TOTAL MARGIN] Base price 4.68 * (1 + 20.0%) = 5.616")
|
||||
|
||||
# Markup method:
|
||||
_logger.info("[TOTAL MARGIN] Markup: Base 4.68 * (1 + 20.0%) = 5.616")
|
||||
|
||||
# Commercial Margin method:
|
||||
_logger.info("[TOTAL MARGIN] Commercial Margin: Base 4.68 / (1 - 20.0%) = 5.85")
|
||||
```
|
||||
|
||||
View logs:
|
||||
|
|
@ -189,12 +237,16 @@ docker-compose run odoo odoo -d odoo --test-enable --stop-after-init -u product_
|
|||
### Test Coverage
|
||||
|
||||
- ✅ Compound margin (default behavior preserved)
|
||||
- ✅ Total margin (additive calculation)
|
||||
- ✅ Total margin with Markup calculation
|
||||
- ✅ Total margin with Commercial Margin calculation
|
||||
- ✅ Formula extras (round, surcharge, min/max)
|
||||
- ✅ Global min/max margin limits
|
||||
- ✅ 3-level pricelist chains
|
||||
- ✅ Different base types (last_purchase_price, list_price)
|
||||
- ✅ Currency conversions
|
||||
|
||||
**Total:** 11 tests, all passing
|
||||
|
||||
## Compatibility
|
||||
|
||||
- **Odoo Version:** 18.0
|
||||
|
|
@ -271,10 +323,21 @@ AGPL-3.0 or later
|
|||
|
||||
## Changelog
|
||||
|
||||
### 18.0.1.1.0 (2026-02-21)
|
||||
|
||||
- **[IMP]** Add `margin_type` field to choose between calculation methods
|
||||
- **Markup (on cost):** `PVP = Cost × (1 + markup%)`
|
||||
- **Commercial Margin (on PVP):** `PVP = Cost / (1 - margin%)`
|
||||
- Add 2 new tests for both calculation methods
|
||||
- Add safety cap for commercial margin >= 100% (caps at 99%)
|
||||
- Improve logging to show which calculation method is used
|
||||
- Total: 11 tests passing
|
||||
|
||||
### 18.0.1.0.0 (2026-02-21)
|
||||
|
||||
- Initial implementation
|
||||
- Support for additive margin calculation in chained pricelists
|
||||
- Compatible with `last_purchase_price` custom base
|
||||
- Comprehensive test suite
|
||||
- Global min/max margin limits configuration
|
||||
- Comprehensive test suite (9 tests)
|
||||
- Detailed logging for debugging
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
{ # noqa: B018
|
||||
"name": "Product Pricelist Total Margin",
|
||||
"version": "18.0.1.0.0",
|
||||
"version": "18.0.1.1.0",
|
||||
"category": "Sales/Products",
|
||||
"summary": "Calculate total margin additively instead of compounding in chained pricelists",
|
||||
"summary": "Calculate total margin additively with Markup or Commercial Margin methods",
|
||||
"author": "Odoo Community Association (OCA), Criptomart",
|
||||
"website": "https://git.criptomart.net/criptomart/addons-cm",
|
||||
"license": "AGPL-3",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue