75 lines
3.5 KiB
Python
75 lines
3.5 KiB
Python
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
|