175 lines
6.3 KiB
Python
175 lines
6.3 KiB
Python
# Copyright 2023 Ecosoft Co., Ltd. (http://ecosoft.co.th)
|
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
|
|
|
from odoo import Command, fields
|
|
from odoo.exceptions import UserError, ValidationError
|
|
from odoo.tests import Form, TransactionCase
|
|
|
|
|
|
class TestAccountManualCurrency(TransactionCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.inv_model = cls.env["account.move"]
|
|
cls.payment_model = cls.env["account.payment"]
|
|
cls.payment_register_model = cls.env["account.payment.register"]
|
|
cls.register_view_id = "account.view_account_payment_register_form"
|
|
# Activate Multi Currency
|
|
cls.usd_currency = cls.env.ref("base.USD")
|
|
cls.eur_currency = cls.env.ref("base.EUR")
|
|
cls.eur_currency.active = True
|
|
|
|
cls.partner1 = cls.env.ref("base.res_partner_3")
|
|
|
|
cls.cash = cls.env["account.journal"].create(
|
|
{"name": "Cash Test", "type": "cash", "code": "CT"}
|
|
)
|
|
|
|
def _create_invoice(
|
|
self,
|
|
partner,
|
|
invoice_type,
|
|
currency,
|
|
manual_currency=False,
|
|
manual_currency_rate=0.0,
|
|
type_currency="company_rate",
|
|
):
|
|
inv_line = [
|
|
Command.create(
|
|
{
|
|
"product_id": self.env.ref("product.product_product_8").id,
|
|
"name": "Test Invoice Line",
|
|
"quantity": 1.0,
|
|
"price_unit": 100.0,
|
|
"tax_ids": False,
|
|
},
|
|
)
|
|
]
|
|
invoice = self.inv_model.create(
|
|
{
|
|
"partner_id": partner.id,
|
|
"invoice_date": fields.Date.today(),
|
|
"move_type": invoice_type,
|
|
"currency_id": currency.id,
|
|
"manual_currency": manual_currency,
|
|
"type_currency": type_currency,
|
|
"manual_currency_rate": manual_currency_rate,
|
|
"invoice_line_ids": inv_line,
|
|
}
|
|
)
|
|
return invoice
|
|
|
|
def test_01_account_move_inverse_currency(self):
|
|
# Create invoice with custom rate: 10 USD = 1 EUR
|
|
invoice1 = self._create_invoice(
|
|
self.partner1,
|
|
"in_invoice",
|
|
self.eur_currency,
|
|
True,
|
|
10,
|
|
"inverse_company_rate",
|
|
)
|
|
invoice1.get_view()
|
|
self.assertTrue(invoice1.is_manual)
|
|
# Currency will recompute to default
|
|
self.assertTrue(invoice1.manual_currency)
|
|
self.assertAlmostEqual(invoice1.manual_currency_rate, 10)
|
|
self.assertAlmostEqual(invoice1.invoice_currency_rate, 0.1) # Inverse rate
|
|
invoice1.action_refresh_currency()
|
|
self.assertNotEqual(invoice1.manual_currency_rate, 10)
|
|
total_currency_not_manual = invoice1.total_company_currency
|
|
self.assertAlmostEqual(
|
|
total_currency_not_manual,
|
|
sum(
|
|
invoice1.line_ids.filtered(lambda line: line.balance > 0).mapped(
|
|
"balance"
|
|
)
|
|
),
|
|
)
|
|
# Use manual currency
|
|
with Form(invoice1) as inv:
|
|
inv.manual_currency = True
|
|
inv.type_currency = "inverse_company_rate"
|
|
inv.manual_currency_rate = 20 # Convert rate: 20 USD = 1 EUR
|
|
inv.save()
|
|
# After manual currency, total currency will recompute
|
|
self.assertNotEqual(invoice1.total_company_currency, total_currency_not_manual)
|
|
self.assertAlmostEqual(
|
|
invoice1.total_company_currency,
|
|
sum(
|
|
invoice1.line_ids.filtered(lambda line: line.balance > 0).mapped(
|
|
"balance"
|
|
)
|
|
),
|
|
)
|
|
invoice1.action_post()
|
|
self.assertEqual(invoice1.state, "posted")
|
|
# Can't refresh rate when state is not draft
|
|
with self.assertRaises(ValidationError):
|
|
invoice1.action_refresh_currency()
|
|
|
|
# Create invoice
|
|
invoice2 = self._create_invoice(self.partner1, "in_invoice", self.usd_currency)
|
|
invoice2.action_post()
|
|
self.assertEqual(invoice2.state, "posted")
|
|
|
|
# Register Payment
|
|
# Can't register payment with not same manual currency
|
|
ctx = {
|
|
"active_ids": (invoice1 + invoice2).mapped("line_ids").ids,
|
|
"active_model": "account.move.line",
|
|
}
|
|
with self.assertRaises(UserError):
|
|
Form(
|
|
self.payment_register_model.with_context(**ctx),
|
|
view=self.register_view_id,
|
|
).save()
|
|
ctx = {
|
|
"active_ids": [invoice1.id],
|
|
"active_model": "account.move",
|
|
}
|
|
with Form(
|
|
self.payment_register_model.with_context(**ctx),
|
|
view=self.register_view_id,
|
|
) as f:
|
|
f.amount = invoice1.amount_total
|
|
wiz = f.save()
|
|
wiz.action_create_payments()
|
|
|
|
def test_02_manual_currency_rate_on_inv_payment(self):
|
|
# Create invoice with custom rate: 10 EUR = 1 USD
|
|
invoice1 = self._create_invoice(
|
|
self.partner1,
|
|
"in_invoice",
|
|
self.eur_currency,
|
|
True,
|
|
10,
|
|
"company_rate",
|
|
)
|
|
invoice1.action_post()
|
|
self.assertTrue(invoice1.manual_currency)
|
|
self.assertAlmostEqual(invoice1.manual_currency_rate, 10.0)
|
|
self.assertAlmostEqual(invoice1.invoice_currency_rate, 10.0) # Inverse rate
|
|
self.assertAlmostEqual(invoice1.invoice_line_ids.balance, 10.0)
|
|
# Register with manual currency
|
|
# Convert rate: 20 EUR = 1 USD
|
|
ctx = {
|
|
"active_ids": [invoice1.id],
|
|
"active_model": "account.move",
|
|
}
|
|
with Form(
|
|
self.payment_register_model.with_context(**ctx),
|
|
view=self.register_view_id,
|
|
) as f:
|
|
f.amount = invoice1.amount_total
|
|
f.manual_currency = True
|
|
f.type_currency = "company_rate"
|
|
f.manual_currency_rate = 20
|
|
wiz = f.save()
|
|
action_payment = wiz.action_create_payments()
|
|
payment = self.payment_model.browse(action_payment["res_id"])
|
|
move_payment = payment.move_id
|
|
self.assertAlmostEqual(move_payment.manual_currency_rate, 20)
|
|
self.assertAlmostEqual(move_payment.invoice_currency_rate, 20)
|
|
self.assertAlmostEqual(abs(move_payment.line_ids[0].balance), 5)
|