47 lines
1.6 KiB
Python
47 lines
1.6 KiB
Python
"""Exchange-difference calculation helper.
|
|
|
|
Pure-Python FX gain/loss computation. The engine uses this for rapid
|
|
pre-checks; Odoo's account.move._create_exchange_difference_move() is
|
|
invoked separately for the actual GL posting.
|
|
"""
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass
|
|
class ExchangeDiffResult:
|
|
needs_diff_move: bool
|
|
diff_amount: float # in company currency; positive = gain, negative = loss
|
|
line_company_amount: float
|
|
against_company_amount: float
|
|
|
|
|
|
def compute_exchange_diff(*, line_amount, line_currency_code, against_amount,
|
|
against_currency_code, line_rate, against_rate) -> ExchangeDiffResult:
|
|
"""Compute whether an exchange-diff move is needed and its magnitude.
|
|
|
|
Args:
|
|
line_amount: Bank line amount in its currency
|
|
line_currency_code: e.g. 'USD'
|
|
against_amount: Matched journal item amount in its currency
|
|
against_currency_code: e.g. 'USD' (or different)
|
|
line_rate: FX rate (foreign per company currency) at line date
|
|
against_rate: FX rate at journal item posting date
|
|
|
|
Returns:
|
|
ExchangeDiffResult with needs_diff_move flag and computed diff
|
|
in company currency (positive = gain, negative = loss).
|
|
"""
|
|
line_company = line_amount * line_rate
|
|
against_company = against_amount * against_rate
|
|
|
|
diff = line_company - against_company
|
|
needs_diff = abs(diff) > 0.005 # rounding tolerance
|
|
|
|
return ExchangeDiffResult(
|
|
needs_diff_move=needs_diff,
|
|
diff_amount=round(diff, 2),
|
|
line_company_amount=round(line_company, 2),
|
|
against_company_amount=round(against_company, 2),
|
|
)
|