Skip to content

Commit

Permalink
[IMP] account_loan: Allow to increase the amount of the loan
Browse files Browse the repository at this point in the history
  • Loading branch information
etobella committed Sep 28, 2023
1 parent 7781a19 commit 90a5bf5
Show file tree
Hide file tree
Showing 9 changed files with 364 additions and 34 deletions.
1 change: 1 addition & 0 deletions account_loan/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"category": "Accounting",
"depends": ["account"],
"data": [
"wizards/account_loan_increase_amount.xml",
"data/ir_sequence_data.xml",
"security/ir.model.access.csv",
"security/account_loan_security.xml",
Expand Down
37 changes: 23 additions & 14 deletions account_loan/models/account_loan_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,34 +238,38 @@ def _check_move_amount(self):
+ self.interests_amount
)

def _move_vals(self):
def _move_vals(self, journal=False, account=False):
return {
"loan_line_id": self.id,
"loan_id": self.loan_id.id,
"date": self.date,
"ref": self.name,
"journal_id": self.loan_id.journal_id.id,
"line_ids": [Command.create(vals) for vals in self._move_line_vals()],
"journal_id": (journal and journal.id) or self.loan_id.journal_id.id,
"line_ids": [
Command.create(vals) for vals in self._move_line_vals(account=account)
],
}

def _move_line_vals(self):
def _move_line_vals(self, account=False):
vals = []
partner = self.loan_id.partner_id.with_company(self.loan_id.company_id)
vals.append(
{
"account_id": partner.property_account_payable_id.id,
"account_id": (account and account.id)
or partner.property_account_payable_id.id,
"partner_id": partner.id,
"credit": self.payment_amount,
"debit": 0,
}
)
vals.append(
{
"account_id": self.loan_id.interest_expenses_account_id.id,
"credit": 0,
"debit": self.interests_amount,
}
)
if self.interests_amount:
vals.append(
{
"account_id": self.loan_id.interest_expenses_account_id.id,
"credit": 0,
"debit": self.interests_amount,
}
)
vals.append(
{
"account_id": self.loan_id.short_term_loan_account_id.id,
Expand Down Expand Up @@ -326,7 +330,7 @@ def _invoice_line_vals(self):
)
return vals

def _generate_move(self):
def _generate_move(self, journal=False, account=False):
"""
Computes and post the moves of loans
:return: list of account.move generated
Expand All @@ -338,7 +342,9 @@ def _generate_move(self):
lambda r: r.date < record.date and not r.move_ids
):
raise UserError(_("Some moves must be created first"))
move = self.env["account.move"].create(record._move_vals())
move = self.env["account.move"].create(
record._move_vals(journal=journal, account=account)
)
move.action_post()
res.append(move.id)
return res
Expand Down Expand Up @@ -372,6 +378,9 @@ def _generate_invoice(self):
for line in invoice.invoice_line_ids:
line.tax_ids = line._get_computed_taxes()
invoice.flush_recordset()
invoice.filtered(
lambda m: m.currency_id.round(m.amount_total) < 0
).action_switch_invoice_into_refund_credit_note()
if record.loan_id.post_invoice:
invoice.action_post()
if (
Expand Down
1 change: 1 addition & 0 deletions account_loan/security/ir.model.access.csv
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ access_account_loan_line,account.loan.line,model_account_loan_line,account.group
access_account_loan_line_manager,account.loan.line,model_account_loan_line,account.group_account_manager,1,1,1,1
access_account_loan_generate_wizard,access_account_loan_generate_wizard,model_account_loan_generate_wizard,account.group_account_manager,1,1,1,1
access_account_loan_pay_amount,access_account_loan_pay_amount,model_account_loan_pay_amount,account.group_account_manager,1,1,1,1
access_account_loan_increase_amount,access_account_loan_increase_amount,model_account_loan_increase_amount,account.group_account_manager,1,1,1,1
access_account_loan_post,access_account_loan_post,model_account_loan_post,account.group_account_manager,1,1,1,1
167 changes: 156 additions & 11 deletions account_loan/tests/test_loan.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,52 @@ def test_round_on_end(self):
self.assertEqual(line_1.principal_amount, 0)
self.assertEqual(line_end.principal_amount, 500000)

def test_increase_amount_validation(self):
amount = 10000
periods = 24
loan = self.create_loan("fixed-annuity", 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_financial.pmt(1 / 100 / 12, 24, 10000), 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)
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])
self.assertTrue(line.move_ids)
self.assertEqual(line.move_ids.state, "posted")
with self.assertRaises(UserError):
self.env["account.loan.increase.amount"].with_context(
default_loan_id=loan.id
).create(
{
"amount": (amount - amount / periods) / 2,
"date": line.date + relativedelta(months=-1),
}
).run()
with self.assertRaises(UserError):
self.env["account.loan.increase.amount"].with_context(
default_loan_id=loan.id
).create({"amount": 0, "date": line.date}).run()
with self.assertRaises(UserError):
self.env["account.loan.increase.amount"].with_context(
default_loan_id=loan.id
).create({"amount": -100, "date": line.date}).run()

def test_pay_amount_validation(self):
amount = 10000
periods = 24
Expand Down Expand Up @@ -132,26 +178,125 @@ def test_pay_amount_validation(self):
self.assertTrue(line.move_ids)
self.assertEqual(line.move_ids.state, "posted")
with self.assertRaises(UserError):
self.env["account.loan.pay.amount"].create(
self.env["account.loan.pay.amount"].with_context(
default_loan_id=loan.id
).create(
{
"loan_id": loan.id,
"amount": (amount - amount / periods) / 2,
"fees": 100,
"date": line.date + relativedelta(months=-1),
}
).run()
with self.assertRaises(UserError):
self.env["account.loan.pay.amount"].create(
{"loan_id": loan.id, "amount": amount, "fees": 100, "date": line.date}
).run()
self.env["account.loan.pay.amount"].with_context(
default_loan_id=loan.id
).create({"amount": amount, "fees": 100, "date": line.date}).run()
with self.assertRaises(UserError):
self.env["account.loan.pay.amount"].create(
{"loan_id": loan.id, "amount": 0, "fees": 100, "date": line.date}
).run()
self.env["account.loan.pay.amount"].with_context(
default_loan_id=loan.id
).create({"amount": 0, "fees": 100, "date": line.date}).run()
with self.assertRaises(UserError):
self.env["account.loan.pay.amount"].create(
{"loan_id": loan.id, "amount": -100, "fees": 100, "date": line.date}
).run()
self.env["account.loan.pay.amount"].with_context(
default_loan_id=loan.id
).create({"amount": -100, "fees": 100, "date": line.date}).run()

def test_increase_amount_loan(self):
amount = 10000
periods = 24
loan = self.create_loan("fixed-annuity", 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_financial.pmt(1 / 100 / 12, 24, 10000), 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)
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])
self.assertTrue(line.move_ids)
self.assertEqual(line.move_ids.state, "posted")
pending_principal_amount = loan.pending_principal_amount
action = (
self.env["account.loan.increase.amount"]
.with_context(default_loan_id=loan.id)
.create(
{
"amount": 1000,
"date": line.date,
}
)
.run()
)
new_move = self.env[action["res_model"]].search(action["domain"])
new_move.ensure_one()
self.assertFalse(new_move.is_invoice())
self.assertEqual(loan, new_move.loan_id)
self.assertEqual(loan.pending_principal_amount, pending_principal_amount + 1000)

def test_increase_amount_leasing(self):
amount = 10000
periods = 24
loan = self.create_loan("fixed-annuity", 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_financial.pmt(1 / 100 / 12, 24, 10000), line.payment_amount, 2
)
self.assertEqual(line.long_term_principal_amount, 0)
loan.is_leasing = True
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)
wzd = self.env["account.loan.generate.wizard"].create(
{
"date": fields.date.today() + relativedelta(days=1),
"loan_type": "leasing",
}
)
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])
self.assertTrue(line.move_ids)
self.assertEqual(line.move_ids.state, "posted")
pending_principal_amount = loan.pending_principal_amount
action = (
self.env["account.loan.increase.amount"]
.with_context(default_loan_id=loan.id)
.create(
{
"amount": 1000,
"date": line.date,
}
)
.run()
)
new_move = self.env[action["res_model"]].search(action["domain"])
new_move.ensure_one()
self.assertFalse(new_move.is_invoice())
self.assertEqual(loan, new_move.loan_id)
self.assertEqual(loan.pending_principal_amount, pending_principal_amount + 1000)

def test_fixed_annuity_begin_loan(self):
amount = 10000
Expand Down
23 changes: 20 additions & 3 deletions account_loan/views/account_loan_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,29 @@
<button
name="%(account_loan_pay_amount_action)d"
class="oe_stat_button"
icon="fa-usd"
icon="fa-arrow-down"
attrs="{'invisible': [('state', '!=', 'posted')]}"
type="action"
string="Pay amount"
groups="account.group_account_manager"
/>
>
<div class="o_field_widget o_stat_info">
<span class="o_stat_text">Deduct</span>
<span class="o_stat_text">Debt</span>
</div>
</button>
<button
name="%(account_loan_increase_amount_act_window)d"
class="oe_stat_button"
icon="fa-arrow-up"
attrs="{'invisible': [('state', '!=', 'posted')]}"
type="action"
groups="account.group_account_manager"
>
<div class="o_field_widget o_stat_info">
<span class="o_stat_text">Increase</span>
<span class="o_stat_text">Debt</span>
</div>
</button>
</div>
<h1>
<field name="name" />
Expand Down
1 change: 1 addition & 0 deletions account_loan/wizards/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
from . import account_loan_generate_entries
from . import account_loan_pay_amount
from . import account_loan_post
from . import account_loan_increase_amount
Loading

0 comments on commit 90a5bf5

Please sign in to comment.