refactor: remove redundant accounting logic and configurations for POS loyalty discounts
This commit is contained in:
parent
a7c6781af5
commit
b2964f66ec
@ -8,7 +8,7 @@ This module modifies the loyalty reward discount calculation in POS to apply dis
|
|||||||
|
|
||||||
2. **Tax-Exclusive Display**: Discount values are displayed as tax-exclusive in the POS receipt.
|
2. **Tax-Exclusive Display**: Discount values are displayed as tax-exclusive in the POS receipt.
|
||||||
|
|
||||||
3. **Proper Accounting Entries**: Accounting entries are created with tax only on the credit side, ensuring compliance with accounting standards.
|
|
||||||
|
|
||||||
## Technical Changes
|
## Technical Changes
|
||||||
|
|
||||||
@ -17,12 +17,7 @@ This module modifies the loyalty reward discount calculation in POS to apply dis
|
|||||||
- Modified `static/src/overrides/models/loyalty.js` to calculate discounts on tax-exclusive amounts
|
- Modified `static/src/overrides/models/loyalty.js` to calculate discounts on tax-exclusive amounts
|
||||||
- Ensured discount line values are tax-exclusive for display purposes
|
- Ensured discount line values are tax-exclusive for display purposes
|
||||||
|
|
||||||
### Backend Changes
|
|
||||||
|
|
||||||
- Created `models/pos_order.py` to handle accounting entries for loyalty discounts
|
|
||||||
- Created `models/loyalty_reward.py` to ensure discount products are properly configured
|
|
||||||
- Created `models/account_move.py` to ensure discount lines in account moves are tax-exclusive
|
|
||||||
- Created `models/pos_session.py` to handle session-level accounting for loyalty discounts
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@ -8,9 +8,7 @@
|
|||||||
This module modifies the loyalty reward discount calculation in POS to apply discounts before tax calculation.
|
This module modifies the loyalty reward discount calculation in POS to apply discounts before tax calculation.
|
||||||
""",
|
""",
|
||||||
"depends": ["point_of_sale", "pos_loyalty"],
|
"depends": ["point_of_sale", "pos_loyalty"],
|
||||||
"data": [
|
"data": [],
|
||||||
"views/res_config_settings_views.xml",
|
|
||||||
],
|
|
||||||
"assets": {
|
"assets": {
|
||||||
"point_of_sale._assets_pos": [
|
"point_of_sale._assets_pos": [
|
||||||
'pos_loyalty_discount_before_tax/static/src/overrides/models/loyalty.js',
|
'pos_loyalty_discount_before_tax/static/src/overrides/models/loyalty.js',
|
||||||
|
|||||||
@ -1,3 +1 @@
|
|||||||
from . import pos_config
|
# Empty init as redundant accounting logic was removed
|
||||||
from . import pos_session
|
|
||||||
from . import res_config_settings
|
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
from odoo import fields, models
|
|
||||||
|
|
||||||
class PosConfig(models.Model):
|
|
||||||
_inherit = 'pos.config'
|
|
||||||
|
|
||||||
discount_100_income_account_id = fields.Many2one(
|
|
||||||
'account.account',
|
|
||||||
string='100% Discount Income Account',
|
|
||||||
help='Account used for Income when an order has a 100% discount (0 total).',
|
|
||||||
domain="[('deprecated', '=', False)]"
|
|
||||||
)
|
|
||||||
discount_100_expense_account_id = fields.Many2one(
|
|
||||||
'account.account',
|
|
||||||
string='100% Discount Expense Account',
|
|
||||||
help='Account used for Expense/Discount when an order has a 100% discount (0 total).',
|
|
||||||
domain="[('deprecated', '=', False)]"
|
|
||||||
)
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
from odoo import models, _
|
|
||||||
from odoo.tools import float_is_zero
|
|
||||||
|
|
||||||
class PosSession(models.Model):
|
|
||||||
_inherit = 'pos.session'
|
|
||||||
|
|
||||||
def _create_account_move(self, balancing_account=False, amount_to_balance=0, bank_payment_method_diffs=None):
|
|
||||||
"""
|
|
||||||
Extend _create_account_move to generate additional journal entry lines
|
|
||||||
for 100% discount orders (where total amount is 0).
|
|
||||||
"""
|
|
||||||
# Call super to generate the standard move
|
|
||||||
data = super(PosSession, self)._create_account_move(balancing_account, amount_to_balance, bank_payment_method_diffs)
|
|
||||||
|
|
||||||
if not self.config_id.discount_100_income_account_id or not self.config_id.discount_100_expense_account_id:
|
|
||||||
return data
|
|
||||||
|
|
||||||
# Identify orders with 0 absolute paid amount but non-zero gross amount
|
|
||||||
# We look for orders where amount_total is near zero.
|
|
||||||
# Note: 100% discount orders have amount_total = 0.
|
|
||||||
|
|
||||||
MoveLine = data.get('MoveLine')
|
|
||||||
if not MoveLine:
|
|
||||||
# Depending on Odoo 19's internal structure changes, fallback / ensure MoveLine exists. Odoo 17 returns a dict with 'MoveLine'.
|
|
||||||
MoveLine = self.env['account.move.line']
|
|
||||||
|
|
||||||
income_account = self.config_id.discount_100_income_account_id
|
|
||||||
expense_account = self.config_id.discount_100_expense_account_id
|
|
||||||
|
|
||||||
# Helper to convert amount to company currency if needed, similar to Odoo's internals
|
|
||||||
def _get_amounts(amount, date):
|
|
||||||
return self._update_amounts({'amount': 0, 'amount_converted': 0}, {'amount': amount}, date)
|
|
||||||
|
|
||||||
zero_value_moves = []
|
|
||||||
|
|
||||||
for order in self._get_closed_orders():
|
|
||||||
if float_is_zero(order.amount_total, precision_rounding=self.currency_id.rounding):
|
|
||||||
# Calculate the exact discount amount applied by loyalty rewards
|
|
||||||
discount_amount = sum(
|
|
||||||
abs(line.price_subtotal)
|
|
||||||
for line in order.lines
|
|
||||||
if line.price_subtotal < 0 and (getattr(line, 'is_reward_line', False) or getattr(line, 'reward_id', False))
|
|
||||||
)
|
|
||||||
|
|
||||||
if float_is_zero(discount_amount, precision_rounding=self.currency_id.rounding):
|
|
||||||
continue
|
|
||||||
|
|
||||||
amounts = _get_amounts(discount_amount, order.date_order)
|
|
||||||
|
|
||||||
# Create Credit Line (Income)
|
|
||||||
# We use _credit_amounts helper logic style manually
|
|
||||||
credit_vals = {
|
|
||||||
'name': _('100%% Discount Income: %s') % order.name,
|
|
||||||
'account_id': income_account.id,
|
|
||||||
'move_id': self.move_id.id,
|
|
||||||
'partner_id': order.partner_id.id or False,
|
|
||||||
}
|
|
||||||
credit_vals.update(self._credit_amounts(credit_vals, amounts['amount'], amounts['amount_converted']))
|
|
||||||
zero_value_moves.append(credit_vals)
|
|
||||||
|
|
||||||
# Create Debit Line (Expense/Discount)
|
|
||||||
debit_vals = {
|
|
||||||
'name': _('100%% Discount Expense: %s') % order.name,
|
|
||||||
'account_id': expense_account.id,
|
|
||||||
'move_id': self.move_id.id,
|
|
||||||
'partner_id': order.partner_id.id or False,
|
|
||||||
}
|
|
||||||
debit_vals.update(self._debit_amounts(debit_vals, amounts['amount'], amounts['amount_converted']))
|
|
||||||
zero_value_moves.append(debit_vals)
|
|
||||||
|
|
||||||
if zero_value_moves and self.move_id:
|
|
||||||
MoveLine.with_context(check_move_validity=False).create(zero_value_moves)
|
|
||||||
|
|
||||||
return data
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
from odoo import fields, models
|
|
||||||
|
|
||||||
class ResConfigSettings(models.TransientModel):
|
|
||||||
_inherit = 'res.config.settings'
|
|
||||||
|
|
||||||
pos_discount_100_income_account_id = fields.Many2one(
|
|
||||||
related='pos_config_id.discount_100_income_account_id',
|
|
||||||
readonly=False,
|
|
||||||
)
|
|
||||||
pos_discount_100_expense_account_id = fields.Many2one(
|
|
||||||
related='pos_config_id.discount_100_expense_account_id',
|
|
||||||
readonly=False,
|
|
||||||
)
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<odoo>
|
|
||||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
|
||||||
<field name="name">res.config.settings.view.form.inherit.pos.loyalty.discount.100</field>
|
|
||||||
<field name="model">res.config.settings</field>
|
|
||||||
<field name="inherit_id" ref="point_of_sale.res_config_settings_view_form"/>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<xpath expr="//block[@id='pos_accounting_section']" position="inside">
|
|
||||||
<setting id="discount_100_account" title="Accounting entries for 100% discount orders" string="100% Discount Accounting">
|
|
||||||
<div class="row">
|
|
||||||
<label string="Income Account" for="pos_discount_100_income_account_id" class="col-lg-3 o_light_label"/>
|
|
||||||
<field name="pos_discount_100_income_account_id"/>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<label string="Expense/Discount Account" for="pos_discount_100_expense_account_id" class="col-lg-3 o_light_label"/>
|
|
||||||
<field name="pos_discount_100_expense_account_id"/>
|
|
||||||
</div>
|
|
||||||
</setting>
|
|
||||||
</xpath>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
</odoo>
|
|
||||||
Loading…
Reference in New Issue
Block a user