[IMP] account_loan: Add fixed-annuity-begin
This commit is contained in:
parent
6d29b2fad1
commit
3b92b3dca6
@ -1,8 +1,8 @@
|
|||||||
# Copyright 2018 Creu Blanca
|
# Copyright 2018 Creu Blanca
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
{
|
{
|
||||||
"name": "Account Loan",
|
"name": "Account Loan management",
|
||||||
"version": "12.0.1.0.0",
|
"version": "12.0.1.1.0",
|
||||||
"author": "Creu Blanca,Odoo Community Association (OCA)",
|
"author": "Creu Blanca,Odoo Community Association (OCA)",
|
||||||
"website": "http://github.com/OCA/account-financial-tools",
|
"website": "http://github.com/OCA/account-financial-tools",
|
||||||
"license": "AGPL-3",
|
"license": "AGPL-3",
|
||||||
|
@ -106,6 +106,7 @@ class AccountLoan(models.Model):
|
|||||||
loan_type = fields.Selection(
|
loan_type = fields.Selection(
|
||||||
[
|
[
|
||||||
('fixed-annuity', 'Fixed Annuity'),
|
('fixed-annuity', 'Fixed Annuity'),
|
||||||
|
('fixed-annuity-begin', 'Fixed Annuity Begin'),
|
||||||
('fixed-principal', 'Fixed Principal'),
|
('fixed-principal', 'Fixed Principal'),
|
||||||
('interest', 'Only interest'),
|
('interest', 'Only interest'),
|
||||||
],
|
],
|
||||||
@ -281,6 +282,14 @@ class AccountLoan(models.Model):
|
|||||||
record.fixed_loan_amount,
|
record.fixed_loan_amount,
|
||||||
-record.residual_amount
|
-record.residual_amount
|
||||||
))
|
))
|
||||||
|
elif record.loan_type == 'fixed-annuity-begin':
|
||||||
|
record.fixed_amount = - record.currency_id.round(numpy.pmt(
|
||||||
|
record.loan_rate() / 100,
|
||||||
|
record.fixed_periods,
|
||||||
|
record.fixed_loan_amount,
|
||||||
|
-record.residual_amount,
|
||||||
|
when='begin'
|
||||||
|
))
|
||||||
elif record.loan_type == 'fixed-principal':
|
elif record.loan_type == 'fixed-principal':
|
||||||
record.fixed_amount = record.currency_id.round(
|
record.fixed_amount = record.currency_id.round(
|
||||||
(record.fixed_loan_amount - record.residual_amount) /
|
(record.fixed_loan_amount - record.residual_amount) /
|
||||||
|
@ -166,6 +166,19 @@ class AccountLoanLine(models.Model):
|
|||||||
self.pending_principal_amount,
|
self.pending_principal_amount,
|
||||||
-self.loan_id.residual_amount
|
-self.loan_id.residual_amount
|
||||||
))
|
))
|
||||||
|
if (
|
||||||
|
self.loan_type == 'fixed-annuity-begin' and
|
||||||
|
self.loan_id.round_on_end
|
||||||
|
):
|
||||||
|
return self.loan_id.fixed_amount
|
||||||
|
if self.loan_type == 'fixed-annuity-begin':
|
||||||
|
return self.currency_id.round(- numpy.pmt(
|
||||||
|
self.loan_id.loan_rate() / 100,
|
||||||
|
self.loan_id.periods - self.sequence + 1,
|
||||||
|
self.pending_principal_amount,
|
||||||
|
-self.loan_id.residual_amount,
|
||||||
|
when='begin'
|
||||||
|
))
|
||||||
|
|
||||||
def check_amount(self):
|
def check_amount(self):
|
||||||
"""Recompute amounts if the annuity has not been processed"""
|
"""Recompute amounts if the annuity has not been processed"""
|
||||||
@ -177,7 +190,7 @@ class AccountLoanLine(models.Model):
|
|||||||
if (
|
if (
|
||||||
self.sequence == self.loan_id.periods and
|
self.sequence == self.loan_id.periods and
|
||||||
self.loan_id.round_on_end and
|
self.loan_id.round_on_end and
|
||||||
self.loan_type == 'fixed-annuity'
|
self.loan_type in ['fixed-annuity', 'fixed-annuity-begin']
|
||||||
):
|
):
|
||||||
self.interests_amount = self.currency_id.round(
|
self.interests_amount = self.currency_id.round(
|
||||||
self.loan_id.fixed_amount - self.pending_principal_amount +
|
self.loan_id.fixed_amount - self.pending_principal_amount +
|
||||||
@ -186,13 +199,24 @@ class AccountLoanLine(models.Model):
|
|||||||
self.payment_amount = self.currency_id.round(self.compute_amount())
|
self.payment_amount = self.currency_id.round(self.compute_amount())
|
||||||
elif not self.loan_id.round_on_end:
|
elif not self.loan_id.round_on_end:
|
||||||
self.interests_amount = self.currency_id.round(
|
self.interests_amount = self.currency_id.round(
|
||||||
self.pending_principal_amount * self.loan_id.loan_rate() / 100)
|
self.compute_interest())
|
||||||
self.payment_amount = self.currency_id.round(self.compute_amount())
|
self.payment_amount = self.currency_id.round(self.compute_amount())
|
||||||
else:
|
else:
|
||||||
self.interests_amount = (
|
self.interests_amount = self.compute_interest()
|
||||||
self.pending_principal_amount * self.loan_id.loan_rate() / 100)
|
|
||||||
self.payment_amount = self.compute_amount()
|
self.payment_amount = self.compute_amount()
|
||||||
|
|
||||||
|
def compute_interest(self):
|
||||||
|
if self.loan_type == 'fixed-annuity-begin':
|
||||||
|
return -numpy.ipmt(
|
||||||
|
self.loan_id.loan_rate() / 100,
|
||||||
|
2,
|
||||||
|
self.loan_id.periods - self.sequence + 1,
|
||||||
|
self.pending_principal_amount,
|
||||||
|
-self.loan_id.residual_amount,
|
||||||
|
when='begin'
|
||||||
|
)
|
||||||
|
return self.pending_principal_amount * self.loan_id.loan_rate() / 100
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def check_move_amount(self):
|
def check_move_amount(self):
|
||||||
"""
|
"""
|
||||||
|
@ -164,6 +164,50 @@ class TestLoan(TransactionCase):
|
|||||||
'date': line.date,
|
'date': line.date,
|
||||||
}).run()
|
}).run()
|
||||||
|
|
||||||
|
def test_fixed_annuity_begin_loan(self):
|
||||||
|
amount = 10000
|
||||||
|
periods = 24
|
||||||
|
loan = self.create_loan('fixed-annuity-begin', amount, 1, periods)
|
||||||
|
self.assertTrue(loan.line_ids)
|
||||||
|
self.assertEqual(len(loan.line_ids), periods)
|
||||||
|
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||||
|
self.assertAlmostEqual(
|
||||||
|
- numpy.pmt(1 / 100 / 12, 24, 10000, when='begin'),
|
||||||
|
line.payment_amount, 2)
|
||||||
|
self.assertEqual(line.long_term_principal_amount, 0)
|
||||||
|
loan.long_term_loan_account_id = self.lt_loan_account
|
||||||
|
loan.compute_lines()
|
||||||
|
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||||
|
self.assertGreater(line.long_term_principal_amount, 0)
|
||||||
|
self.post(loan)
|
||||||
|
self.assertTrue(loan.start_date)
|
||||||
|
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||||
|
self.assertTrue(line)
|
||||||
|
self.assertFalse(line.move_ids)
|
||||||
|
self.assertFalse(line.invoice_ids)
|
||||||
|
wzd = self.env['account.loan.generate.wizard'].create({})
|
||||||
|
action = wzd.run()
|
||||||
|
self.assertTrue(action)
|
||||||
|
self.assertFalse(wzd.run())
|
||||||
|
self.assertTrue(line.move_ids)
|
||||||
|
self.assertIn(line.move_ids.id, action['domain'][0][2])
|
||||||
|
line.move_ids.post()
|
||||||
|
loan.rate = 2
|
||||||
|
loan.compute_lines()
|
||||||
|
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||||
|
self.assertAlmostEqual(
|
||||||
|
- numpy.pmt(1 / 100 / 12, periods, amount, when='begin'),
|
||||||
|
line.payment_amount, 2)
|
||||||
|
line = loan.line_ids.filtered(lambda r: r.sequence == 2)
|
||||||
|
self.assertAlmostEqual(
|
||||||
|
- numpy.pmt(2 / 100 / 12, periods - 1,
|
||||||
|
line.pending_principal_amount, when='begin'),
|
||||||
|
line.payment_amount, 2
|
||||||
|
)
|
||||||
|
line = loan.line_ids.filtered(lambda r: r.sequence == 3)
|
||||||
|
with self.assertRaises(UserError):
|
||||||
|
line.view_process_values()
|
||||||
|
|
||||||
def test_fixed_annuity_loan(self):
|
def test_fixed_annuity_loan(self):
|
||||||
amount = 10000
|
amount = 10000
|
||||||
periods = 24
|
periods = 24
|
||||||
|
Loading…
x
Reference in New Issue
Block a user