add feature to zero debit tax line and subtract the credit line tax when POS journal entry posted

This commit is contained in:
admin.suherdy 2025-11-08 00:00:21 +07:00
parent f05f7fd47b
commit dfae28eeaa
6 changed files with 130 additions and 1 deletions

View File

@ -1 +1,3 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
from . import models

Binary file not shown.

3
models/__init__.py Normal file
View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import pos_session

Binary file not shown.

Binary file not shown.

124
models/pos_session.py Normal file
View File

@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-
import logging
from collections import defaultdict
from odoo import models
from odoo.tools.float_utils import float_is_zero, float_round
_logger = logging.getLogger(__name__)
class PosSession(models.Model):
_inherit = "pos.session"
def _create_account_move(self, balancing_account=False, amount_to_balance=0, bank_payment_method_diffs=None):
data = super()._create_account_move(
balancing_account=balancing_account,
amount_to_balance=amount_to_balance,
bank_payment_method_diffs=bank_payment_method_diffs,
)
self._adjust_vat_tax_lines()
return data
def _adjust_vat_tax_lines(self):
"""Remove debit VAT tax lines and reduce matching credit VAT totals."""
for session in self:
move = session.move_id
if not move or move.state != "draft":
continue
tax_lines = move.line_ids.filtered(lambda l: l.display_type == "tax")
debit_tax_lines = tax_lines.filtered(lambda l: l.balance > 0)
if not debit_tax_lines:
continue
grouped = defaultdict(list)
for debit_line in debit_tax_lines:
key = (
debit_line.account_id.id,
debit_line.tax_repartition_line_id.id if debit_line.tax_repartition_line_id else None,
)
grouped[key].append(debit_line)
company_currency = move.company_currency_id
for key, lines_to_remove in grouped.items():
account_id, repartition_id = key
credit_candidates = tax_lines.filtered(
lambda l: l not in debit_tax_lines
and l.account_id.id == account_id
and l.balance < 0
and (not repartition_id or l.tax_repartition_line_id.id == repartition_id)
)
if not credit_candidates and repartition_id:
credit_candidates = tax_lines.filtered(
lambda l: l not in debit_tax_lines and l.account_id.id == account_id and l.balance < 0
)
if not credit_candidates:
_logger.warning(
"POS session %s move %s: could not find credit VAT line to adjust for account %s.",
session.name,
move.name or move.ref,
account_id,
)
continue
for debit_line in lines_to_remove:
remaining_balance = debit_line.balance
remaining_amount_currency = (
debit_line.amount_currency if debit_line.currency_id else 0.0
)
for credit_line in credit_candidates:
if float_is_zero(remaining_balance, precision_rounding=company_currency.rounding):
break
credit_available = -credit_line.balance
consume = min(credit_available, remaining_balance)
if float_is_zero(consume, precision_rounding=company_currency.rounding):
continue
proportion = consume / remaining_balance if remaining_balance else 0.0
step_amount_currency = (
remaining_amount_currency * proportion if credit_line.currency_id else 0.0
)
new_balance = credit_line.balance + consume
if float_is_zero(new_balance, precision_rounding=company_currency.rounding):
new_debit = 0.0
new_credit = 0.0
elif new_balance < 0:
new_debit = 0.0
new_credit = -new_balance
else:
new_debit = new_balance
new_credit = 0.0
write_vals = {
"debit": float_round(new_debit, precision_rounding=company_currency.rounding),
"credit": float_round(new_credit, precision_rounding=company_currency.rounding),
}
if credit_line.currency_id:
currency = credit_line.currency_id
new_amount_currency = credit_line.amount_currency + step_amount_currency
write_vals["amount_currency"] = float_round(
new_amount_currency, precision_rounding=currency.rounding
)
credit_line.with_context(check_move_validity=False).write(write_vals)
remaining_balance -= consume
if credit_line.currency_id:
remaining_amount_currency -= step_amount_currency
if not float_is_zero(remaining_balance, precision_rounding=company_currency.rounding):
_logger.warning(
"POS session %s move %s: VAT debit removal left unmatched balance of %s.",
session.name,
move.name or move.ref,
remaining_balance,
)
zero_vals = {"debit": 0.0, "credit": 0.0}
if debit_line.currency_id:
zero_vals["amount_currency"] = 0.0
if "tax_base_amount" in debit_line._fields:
zero_vals["tax_base_amount"] = 0.0
debit_line.with_context(check_move_validity=False).write(zero_vals)