Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions account_payment_pro/models/account_payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,18 @@ class AccountPayment(models.Model):
@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
# Si se pasa company_id explícitamente por contexto, evitamos que journal_id
# proveniente de ir.default (valores predeterminados del usuario) y perteneciente
# a otra compañía dispare el precompute _compute_company_id y sobreescriba la
# compañía correcta del pago por la compañía principal del entorno.
default_company_id = self._context.get("default_company_id")
if default_company_id and "journal_id" in res:
journal = self.env["account.journal"].browse(res["journal_id"])
if journal.company_id.id != default_company_id:
res.pop("journal_id")
ir_defaults = self.env["ir.default"].with_company(default_company_id)._get_model_defaults(self._name)
if "journal_id" in ir_defaults:
res["journal_id"] = self.env["account.journal"].browse(ir_defaults["journal_id"]).id
if "previous_currency_id" in fields_list and "previous_currency_id" not in res:
currency_id = res.get("currency_id")
if not currency_id:
Expand Down Expand Up @@ -378,11 +390,14 @@ def _onchange_currency_recompute_amount(self):
amount = rec.env.context.get("default_amount")
rec.update({"amount_exact": amount, "amount": amount})

@api.depends("amount", "amount_exact", "other_currency", "force_amount_company_currency")
@api.depends(
"amount", "amount_exact", "other_currency", "force_amount_company_currency", "amount_company_currency_signed"
)
def _compute_amount_company_currency(self):
"""
* Si las monedas son iguales devuelve 1
* si no, si hay force_amount_company_currency, devuelve ese valor
* si ya hay asiento, usa el importe contable nativo sin signo
* sino, devuelve el amount convertido a la moneda de la cia
"""
for rec in self:
Expand All @@ -391,9 +406,14 @@ def _compute_amount_company_currency(self):
amount_company_currency = amount
elif rec.force_amount_company_currency:
amount_company_currency = rec.force_amount_company_currency
elif rec.move_id:
amount_company_currency = abs(rec.amount_company_currency_signed)
else:
amount_company_currency = rec.currency_id._convert(
amount, rec.company_id.currency_id, rec.company_id, rec.date
amount,
rec.company_id.currency_id,
rec.company_id,
rec.date,
)
rec.amount_company_currency = amount_company_currency

Expand Down
30 changes: 30 additions & 0 deletions account_payment_pro/tests/test_account_paymet_pro_unit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,36 @@ def test_force_amount_company_currency_without_payment_pro(self):
msg="Liquidity line balance should still use forced amount after synchronization",
)

def test_posted_payment_without_payment_pro_keeps_accounting_rate_after_rate_change(self):
self.company.use_payment_pro = False

payment = self.env["account.payment"].create(
{
"payment_type": "inbound",
"partner_type": "customer",
"partner_id": self.partner_ri.id,
"journal_id": self.company_bank_journal.id,
"amount": 100.0,
"currency_id": self.eur_currency.id,
"date": self.today,
}
)
payment.action_post()

liquidity_lines = payment.move_id.line_ids.filtered(
lambda line: line.account_id == payment.outstanding_account_id
)
accounting_amount = abs(sum(liquidity_lines.mapped("balance")))
self.assertAlmostEqual(accounting_amount, 100000.0, places=2)
self.assertAlmostEqual(payment.amount_company_currency, accounting_amount, places=2)
self.assertAlmostEqual(payment.exchange_rate, 1000.0, places=2)

self.rates[1].inverse_company_rate = 2000
payment.invalidate_recordset(["amount_company_currency", "exchange_rate"])

self.assertAlmostEqual(payment.amount_company_currency, accounting_amount, places=2)
self.assertAlmostEqual(payment.exchange_rate, 1000.0, places=2)

def test_write_off_line_amounts_company_vs_payment_currency(self):
"""Minimal test: company currency vs payment currency, force company amount and check write-off line balance"""
# Use existing company and ensure we have a different currency for the payment
Expand Down
1 change: 1 addition & 0 deletions l10n_ar_payment_bundle/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
from . import account_payment_method
from . import account_journal
from . import account_payment_register
from . import account_move_line
22 changes: 22 additions & 0 deletions l10n_ar_payment_bundle/models/account_move_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from odoo import models


class AccountMoveLine(models.Model):
_inherit = "account.move.line"

def action_register_payment(self, ctx=None):
action = super().action_register_payment(ctx=ctx)
# Si el diario por defecto es bundle
journal = self.env["account.journal"].search(
[
*self.env["account.journal"]._check_company_domain(self.company_id),
("type", "in", ["bank", "cash", "credit"]),
],
limit=1,
)

if "payment_bundle" in (
journal.inbound_payment_method_line_ids + journal.outbound_payment_method_line_ids
).mapped("code"):
action.setdefault("context", {})["default_amount"] = 0
return action
3 changes: 2 additions & 1 deletion l10n_ar_payment_bundle/models/account_payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,4 +355,5 @@ def _compute_warnings(self):

@api.onchange("to_pay_move_line_ids")
def _onchange_amount(self):
super(AccountPayment, self.filtered(lambda r: r.payment_method_code != "payment_bundle"))._onchange_amount()
payments = self.filtered(lambda r: r.payment_method_code != "payment_bundle" and not r.main_payment_id)
super(AccountPayment, payments)._onchange_amount()
54 changes: 54 additions & 0 deletions l10n_ar_payment_bundle/tests/test_payment_difference.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,57 @@ def test_payment_difference_zero_when_exact(self):
places=2,
msg="Payment difference should be 0 when amounts match exactly",
)

def test_link_payment_onchange_does_not_override_remaining_amount(self):
"""Linked payments should keep the remaining amount suggested by the x2many context."""
invoice = self._create_invoice(10511.35)
invoice.action_post()

payment = self._create_payment_bundle()
payment.to_pay_move_line_ids = invoice.line_ids.filtered(
lambda l: l.account_id.account_type in ("asset_receivable", "liability_payable")
)

self.env["account.payment"].create(
{
"payment_type": "inbound",
"partner_type": "customer",
"partner_id": self.partner.id,
"journal_id": self.bank_journal.id,
"amount": 500.0,
"main_payment_id": payment.id,
}
)

virtual_payment = self.env["account.payment"].new(
{
"payment_type": "inbound",
"partner_type": "customer",
"partner_id": self.partner.id,
"journal_id": self.bundle_journal.id,
"payment_method_line_id": self.payment_method_line.id,
"amount": 0.0,
"to_pay_move_line_ids": [
Command.set(
invoice.line_ids.filtered(
lambda l: l.account_id.account_type in ("asset_receivable", "liability_payable")
).ids
)
],
}
)
linked_payment = self.env["account.payment"].new(
{
"payment_type": "inbound",
"partner_type": "customer",
"partner_id": self.partner.id,
"journal_id": self.bank_journal.id,
"amount": 10011.35,
"main_payment_id": virtual_payment,
}
)
self.assertFalse(linked_payment.main_payment_id._origin)

linked_payment._onchange_amount()

self.assertAlmostEqual(linked_payment.amount, 10011.35, places=2)
40 changes: 40 additions & 0 deletions l10n_latam_check_ux/models/account_payment.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,43 @@ def action_draft(self):
)

super().action_draft()

def _is_latam_check_transfer(self):
self.ensure_one()
return super()._is_latam_check_transfer() or (
self.is_internal_transfer
and bool(self.l10n_latam_move_check_ids)
and self.destination_account_id == self.company_id.transfer_account_id
)

@api.constrains(
"is_internal_transfer",
"payment_type",
"payment_method_line_id",
"destination_journal_id",
"l10n_latam_move_check_ids",
)
def _check_inbound_transfer_checks_current_journal(self):
"""Keep server-side behavior aligned with the wizard domain in Odoo.

For inbound internal transfers receiving third-party checks, all selected checks
must come from the same current journal: the source journal (`destination_journal_id`).
"""
for rec in self.filtered(
lambda x: (
x.state == "draft"
and x.is_internal_transfer
and x.payment_type == "inbound"
and x.payment_method_line_id.code == "in_third_party_checks"
and x.destination_journal_id
and x.l10n_latam_move_check_ids
)
):
invalid_checks = rec.l10n_latam_move_check_ids.filtered(
lambda c: c.current_journal_id != rec.destination_journal_id
)
if invalid_checks:
raise ValidationError(
"All selected checks must belong to the source journal (%s)."
% rec.destination_journal_id.display_name
)
Loading