2
0

[MIG] account_loan: Mirgation to 16.0

This commit is contained in:
Enric Tobella 2023-09-15 10:04:47 +02:00
parent e5e38a86e0
commit bf6075876f
20 changed files with 221 additions and 180 deletions

View File

@ -7,7 +7,7 @@ Account Loan management
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:ede8542c931551ec36dabc09621d29b3bcb54586fcad8fd3c4509b95ce8198bf !! source digest: sha256:c9f87eb07ebda20ab00e0446ae5e5908b6a64086fd868f2bfc58e4e9f7dc68b0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@ -17,13 +17,13 @@ Account Loan management
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github
:target: https://github.com/OCA/account-financial-tools/tree/14.0/account_loan :target: https://github.com/OCA/account-financial-tools/tree/16.0/account_loan
:alt: OCA/account-financial-tools :alt: OCA/account-financial-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/account-financial-tools-14-0/account-financial-tools-14-0-account_loan :target: https://translation.odoo-community.org/projects/account-financial-tools-16-0/account-financial-tools-16-0-account_loan
:alt: Translate me on Weblate :alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=14.0 :target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=16.0
:alt: Try me on Runboat :alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5| |badge1| |badge2| |badge3| |badge4| |badge5|
@ -68,13 +68,21 @@ On a posted loan you can:
:alt: Try me on Runbot :alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/92/12.0 :target: https://runbot.odoo-community.org/runbot/92/12.0
Changelog
=========
16.0.1.0.0
~~~~~~~~~~
Due to the changes on 16, we will generate two moves on leasings, one for the invoice, and another one for the change from long to short term.
Bug Tracker Bug Tracker
=========== ===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-tools/issues>`_. Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-tools/issues>`_.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_loan%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. `feedback <https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_loan%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues. Do not contact contributors directly about support or help with technical issues.
@ -106,6 +114,14 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use. promote its widespread use.
This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/14.0/account_loan>`_ project on GitHub. .. |maintainer-etobella| image:: https://github.com/etobella.png?size=40px
:target: https://github.com/etobella
:alt: etobella
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-etobella|
This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/16.0/account_loan>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@ -1,4 +1,4 @@
# 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).
from . import model from . import models
from . import wizard from . import wizards

View File

@ -2,7 +2,7 @@
# 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 management", "name": "Account Loan management",
"version": "14.0.1.0.6", "version": "16.0.1.0.0",
"author": "Creu Blanca,Odoo Community Association (OCA)", "author": "Creu Blanca,Odoo Community Association (OCA)",
"website": "https://github.com/OCA/account-financial-tools", "website": "https://github.com/OCA/account-financial-tools",
"license": "AGPL-3", "license": "AGPL-3",
@ -12,13 +12,14 @@
"data/ir_sequence_data.xml", "data/ir_sequence_data.xml",
"security/ir.model.access.csv", "security/ir.model.access.csv",
"security/account_loan_security.xml", "security/account_loan_security.xml",
"wizard/account_loan_generate_entries_view.xml", "wizards/account_loan_generate_entries_view.xml",
"wizard/account_loan_pay_amount_view.xml", "wizards/account_loan_pay_amount_view.xml",
"wizard/account_loan_post_view.xml", "wizards/account_loan_post_view.xml",
"views/account_loan_view.xml", "views/account_loan_view.xml",
"views/account_move_view.xml", "views/account_move_view.xml",
], ],
"installable": True, "installable": True,
"maintainers": ["etobella"],
"external_dependencies": { "external_dependencies": {
"python": ["numpy>=1.15", "numpy-financial<=1.0.0"], "python": ["numpy>=1.15", "numpy-financial<=1.0.0"],
"deb": ["libatlas-base-dev"], "deb": ["libatlas-base-dev"],

View File

@ -267,7 +267,7 @@ class AccountLoan(models.Model):
if record.loan_type == "fixed-annuity": if record.loan_type == "fixed-annuity":
record.fixed_amount = -record.currency_id.round( record.fixed_amount = -record.currency_id.round(
numpy_financial.pmt( numpy_financial.pmt(
record.loan_rate() / 100, record._loan_rate() / 100,
record.fixed_periods, record.fixed_periods,
record.fixed_loan_amount, record.fixed_loan_amount,
-record.residual_amount, -record.residual_amount,
@ -276,7 +276,7 @@ class AccountLoan(models.Model):
elif record.loan_type == "fixed-annuity-begin": elif record.loan_type == "fixed-annuity-begin":
record.fixed_amount = -record.currency_id.round( record.fixed_amount = -record.currency_id.round(
numpy_financial.pmt( numpy_financial.pmt(
record.loan_rate() / 100, record._loan_rate() / 100,
record.fixed_periods, record.fixed_periods,
record.fixed_loan_amount, record.fixed_loan_amount,
-record.residual_amount, -record.residual_amount,
@ -292,7 +292,7 @@ class AccountLoan(models.Model):
record.fixed_amount = 0.0 record.fixed_amount = 0.0
@api.model @api.model
def compute_rate(self, rate, rate_type, method_period): def _compute_rate(self, rate, rate_type, method_period):
""" """
Returns the real rate Returns the real rate
:param rate: Rate :param rate: Rate
@ -309,10 +309,10 @@ class AccountLoan(models.Model):
@api.depends("rate", "method_period", "rate_type") @api.depends("rate", "method_period", "rate_type")
def _compute_rate_period(self): def _compute_rate_period(self):
for record in self: for record in self:
record.rate_period = record.loan_rate() record.rate_period = record._loan_rate()
def loan_rate(self): def _loan_rate(self):
return self.compute_rate(self.rate, self.rate_type, self.method_period) return self._compute_rate(self.rate, self.rate_type, self.method_period)
@api.depends("journal_id", "company_id") @api.depends("journal_id", "company_id")
def _compute_currency(self): def _compute_currency(self):
@ -345,20 +345,21 @@ class AccountLoan(models.Model):
self.short_term_loan_account_id self.short_term_loan_account_id
) = self.long_term_loan_account_id = False ) = self.long_term_loan_account_id = False
def get_default_name(self, vals): def _get_default_name(self, vals):
return self.env["ir.sequence"].next_by_code("account.loan") or "/" return self.env["ir.sequence"].next_by_code("account.loan") or "/"
@api.model @api.model_create_multi
def create(self, vals): def create(self, vals_list):
for vals in vals_list:
if vals.get("name", "/") == "/": if vals.get("name", "/") == "/":
vals["name"] = self.get_default_name(vals) vals["name"] = self._get_default_name(vals)
return super().create(vals) return super().create(vals_list)
def post(self): def post(self):
self.ensure_one() self.ensure_one()
if not self.start_date: if not self.start_date:
self.start_date = fields.Date.today() self.start_date = fields.Date.today()
self.compute_draft_lines() self._compute_draft_lines()
self.write({"state": "posted"}) self.write({"state": "posted"})
def close(self): def close(self):
@ -367,10 +368,10 @@ class AccountLoan(models.Model):
def compute_lines(self): def compute_lines(self):
self.ensure_one() self.ensure_one()
if self.state == "draft": if self.state == "draft":
return self.compute_draft_lines() return self._compute_draft_lines()
return self.compute_posted_lines() return self._compute_posted_lines()
def compute_posted_lines(self): def _compute_posted_lines(self):
""" """
Recompute the amounts of not finished lines. Useful if rate is changed Recompute the amounts of not finished lines. Useful if rate is changed
""" """
@ -381,12 +382,12 @@ class AccountLoan(models.Model):
else: else:
line.rate = self.rate_period line.rate = self.rate_period
line.pending_principal_amount = amount line.pending_principal_amount = amount
line.check_amount() line._check_amount()
amount -= line.payment_amount - line.interests_amount amount -= line.payment_amount - line.interests_amount
if self.long_term_loan_account_id: if self.long_term_loan_account_id:
self.check_long_term_principal_amount() self._check_long_term_principal_amount()
def check_long_term_principal_amount(self): def _check_long_term_principal_amount(self):
""" """
Recomputes the long term pending principal of unfinished lines. Recomputes the long term pending principal of unfinished lines.
""" """
@ -408,7 +409,7 @@ class AccountLoan(models.Model):
) )
amount = line.long_term_pending_principal_amount amount = line.long_term_pending_principal_amount
def new_line_vals(self, sequence, date, amount): def _new_line_vals(self, sequence, date, amount):
return { return {
"loan_id": self.id, "loan_id": self.id,
"sequence": sequence, "sequence": sequence,
@ -417,7 +418,7 @@ class AccountLoan(models.Model):
"rate": self.rate_period, "rate": self.rate_period,
} }
def compute_draft_lines(self): def _compute_draft_lines(self):
self.ensure_one() self.ensure_one()
self.fixed_periods = self.periods self.fixed_periods = self.periods
self.fixed_loan_amount = self.loan_amount self.fixed_loan_amount = self.loan_amount
@ -432,13 +433,13 @@ class AccountLoan(models.Model):
date += delta date += delta
for i in range(1, self.periods + 1): for i in range(1, self.periods + 1):
line = self.env["account.loan.line"].create( line = self.env["account.loan.line"].create(
self.new_line_vals(i, date, amount) self._new_line_vals(i, date, amount)
) )
line.check_amount() line._check_amount()
date += delta date += delta
amount -= line.payment_amount - line.interests_amount amount -= line.payment_amount - line.interests_amount
if self.long_term_loan_account_id: if self.long_term_loan_account_id:
self.check_long_term_principal_amount() self._check_long_term_principal_amount()
def view_account_moves(self): def view_account_moves(self):
self.ensure_one() self.ensure_one()
@ -457,7 +458,7 @@ class AccountLoan(models.Model):
return result return result
@api.model @api.model
def generate_loan_entries(self, date): def _generate_loan_entries(self, date):
""" """
Generate the moves of unfinished loans before date Generate the moves of unfinished loans before date
:param date: :param date:
@ -470,16 +471,16 @@ class AccountLoan(models.Model):
lines = record.line_ids.filtered( lines = record.line_ids.filtered(
lambda r: r.date <= date and not r.move_ids lambda r: r.date <= date and not r.move_ids
) )
res += lines.generate_move() res += lines._generate_move()
return res return res
@api.model @api.model
def generate_leasing_entries(self, date): def _generate_leasing_entries(self, date):
res = [] res = []
for record in self.search( for record in self.search(
[("state", "=", "posted"), ("is_leasing", "=", True)] [("state", "=", "posted"), ("is_leasing", "=", True)]
): ):
res += record.line_ids.filtered( res += record.line_ids.filtered(
lambda r: r.date <= date and not r.move_ids lambda r: r.date <= date and not r.move_ids
).generate_invoice() )._generate_invoice()
return res return res

View File

@ -3,7 +3,7 @@
import logging import logging
from odoo import _, api, fields, models from odoo import Command, _, api, fields, models
from odoo.exceptions import UserError from odoo.exceptions import UserError
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -131,7 +131,7 @@ class AccountLoanLine(models.Model):
) )
rec.principal_amount = rec.payment_amount - rec.interests_amount rec.principal_amount = rec.payment_amount - rec.interests_amount
def compute_amount(self): def _compute_amount(self):
""" """
Computes the payment amount Computes the payment amount
:return: Amount to be payed on the annuity :return: Amount to be payed on the annuity
@ -155,7 +155,7 @@ class AccountLoanLine(models.Model):
if self.loan_type == "fixed-annuity": if self.loan_type == "fixed-annuity":
return self.currency_id.round( return self.currency_id.round(
-numpy_financial.pmt( -numpy_financial.pmt(
self.loan_id.loan_rate() / 100, self.loan_id._loan_rate() / 100,
self.loan_id.periods - self.sequence + 1, self.loan_id.periods - self.sequence + 1,
self.pending_principal_amount, self.pending_principal_amount,
-self.loan_id.residual_amount, -self.loan_id.residual_amount,
@ -166,7 +166,7 @@ class AccountLoanLine(models.Model):
if self.loan_type == "fixed-annuity-begin": if self.loan_type == "fixed-annuity-begin":
return self.currency_id.round( return self.currency_id.round(
-numpy_financial.pmt( -numpy_financial.pmt(
self.loan_id.loan_rate() / 100, self.loan_id._loan_rate() / 100,
self.loan_id.periods - self.sequence + 1, self.loan_id.periods - self.sequence + 1,
self.pending_principal_amount, self.pending_principal_amount,
-self.loan_id.residual_amount, -self.loan_id.residual_amount,
@ -174,7 +174,7 @@ class AccountLoanLine(models.Model):
) )
) )
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"""
if self.move_ids: if self.move_ids:
raise UserError( raise UserError(
@ -190,27 +190,27 @@ class AccountLoanLine(models.Model):
- self.pending_principal_amount - self.pending_principal_amount
+ self.loan_id.residual_amount + self.loan_id.residual_amount
) )
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.compute_interest()) self.interests_amount = self.currency_id.round(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.compute_interest() self.interests_amount = self._compute_interest()
self.payment_amount = self.compute_amount() self.payment_amount = self._compute_amount()
def compute_interest(self): def _compute_interest(self):
if self.loan_type == "fixed-annuity-begin": if self.loan_type == "fixed-annuity-begin":
return -numpy_financial.ipmt( return -numpy_financial.ipmt(
self.loan_id.loan_rate() / 100, self.loan_id._loan_rate() / 100,
2, 2,
self.loan_id.periods - self.sequence + 1, self.loan_id.periods - self.sequence + 1,
self.pending_principal_amount, self.pending_principal_amount,
-self.loan_id.residual_amount, -self.loan_id.residual_amount,
when="begin", when="begin",
) )
return self.pending_principal_amount * self.loan_id.loan_rate() / 100 return self.pending_principal_amount * self.loan_id._loan_rate() / 100
def check_move_amount(self): def _check_move_amount(self):
""" """
Changes the amounts of the annuity once the move is posted Changes the amounts of the annuity once the move is posted
:return: :return:
@ -238,17 +238,17 @@ class AccountLoanLine(models.Model):
+ self.interests_amount + self.interests_amount
) )
def move_vals(self): def _move_vals(self):
return { return {
"loan_line_id": self.id, "loan_line_id": self.id,
"loan_id": self.loan_id.id, "loan_id": self.loan_id.id,
"date": self.date, "date": self.date,
"ref": self.name, "ref": self.name,
"journal_id": self.loan_id.journal_id.id, "journal_id": self.loan_id.journal_id.id,
"line_ids": [(0, 0, vals) for vals in self.move_line_vals()], "line_ids": [Command.create(vals) for vals in self._move_line_vals()],
} }
def move_line_vals(self): def _move_line_vals(self):
vals = [] vals = []
partner = self.loan_id.partner_id.with_company(self.loan_id.company_id) partner = self.loan_id.partner_id.with_company(self.loan_id.company_id)
vals.append( vals.append(
@ -290,7 +290,7 @@ class AccountLoanLine(models.Model):
) )
return vals return vals
def invoice_vals(self): def _invoice_vals(self):
return { return {
"loan_line_id": self.id, "loan_line_id": self.id,
"loan_id": self.loan_id.id, "loan_id": self.loan_id.id,
@ -299,10 +299,12 @@ class AccountLoanLine(models.Model):
"invoice_date": self.date, "invoice_date": self.date,
"journal_id": self.loan_id.journal_id.id, "journal_id": self.loan_id.journal_id.id,
"company_id": self.loan_id.company_id.id, "company_id": self.loan_id.company_id.id,
"invoice_line_ids": [(0, 0, vals) for vals in self.invoice_line_vals()], "invoice_line_ids": [
Command.create(vals) for vals in self._invoice_line_vals()
],
} }
def invoice_line_vals(self): def _invoice_line_vals(self):
vals = list() vals = list()
vals.append( vals.append(
{ {
@ -324,7 +326,7 @@ class AccountLoanLine(models.Model):
) )
return vals return vals
def generate_move(self): def _generate_move(self):
""" """
Computes and post the moves of loans Computes and post the moves of loans
:return: list of account.move generated :return: list of account.move generated
@ -336,12 +338,24 @@ class AccountLoanLine(models.Model):
lambda r: r.date < record.date and not r.move_ids lambda r: r.date < record.date and not r.move_ids
): ):
raise UserError(_("Some moves must be created first")) 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())
move.action_post() move.action_post()
res.append(move.id) res.append(move.id)
return res return res
def generate_invoice(self): def _long_term_move_vals(self):
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._get_long_term_move_line_vals()
],
}
def _generate_invoice(self):
""" """
Computes invoices of leases Computes invoices of leases
:return: list of account.move generated :return: list of account.move generated
@ -353,45 +367,37 @@ class AccountLoanLine(models.Model):
lambda r: r.date < record.date and not r.move_ids lambda r: r.date < record.date and not r.move_ids
): ):
raise UserError(_("Some invoices must be created first")) raise UserError(_("Some invoices must be created first"))
invoice = self.env["account.move"].create(record.invoice_vals()) invoice = self.env["account.move"].create(record._invoice_vals())
res.append(invoice.id) res.append(invoice.id)
for line in invoice.invoice_line_ids: for line in invoice.invoice_line_ids:
line.tax_ids = line._get_computed_taxes() line.tax_ids = line._get_computed_taxes()
invoice.with_context( invoice.flush_recordset()
check_move_validity=False if record.loan_id.post_invoice:
)._recompute_dynamic_lines(recompute_all_taxes=True) invoice.action_post()
invoice._check_balanced()
if ( if (
record.long_term_loan_account_id record.long_term_loan_account_id
and record.long_term_principal_amount != 0 and record.long_term_principal_amount != 0
): ):
invoice.write({"line_ids": record._get_long_term_move_line_vals()}) move = self.env["account.move"].create(
record._long_term_move_vals()
)
if record.loan_id.post_invoice: if record.loan_id.post_invoice:
invoice.action_post() move.action_post()
res.append(move.id)
return res return res
def _get_long_term_move_line_vals(self): def _get_long_term_move_line_vals(self):
return [ return [
(
0,
0,
{ {
"account_id": self.loan_id.short_term_loan_account_id.id, "account_id": self.loan_id.short_term_loan_account_id.id,
"credit": self.long_term_principal_amount, "credit": self.long_term_principal_amount,
"debit": 0, "debit": 0,
"exclude_from_invoice_tab": True,
}, },
),
(
0,
0,
{ {
"account_id": self.long_term_loan_account_id.id, "account_id": self.long_term_loan_account_id.id,
"credit": 0, "credit": 0,
"debit": self.long_term_principal_amount, "debit": self.long_term_principal_amount,
"exclude_from_invoice_tab": True,
}, },
),
] ]
def view_account_values(self): def view_account_values(self):
@ -405,9 +411,9 @@ class AccountLoanLine(models.Model):
"""Computes the annuity and returns the result""" """Computes the annuity and returns the result"""
self.ensure_one() self.ensure_one()
if self.is_leasing: if self.is_leasing:
self.generate_invoice() self._generate_invoice()
else: else:
self.generate_move() self._generate_move()
return self.view_account_values() return self.view_account_values()
def view_account_moves(self): def view_account_moves(self):
@ -421,7 +427,7 @@ class AccountLoanLine(models.Model):
} }
result["domain"] = [("loan_line_id", "=", self.id)] result["domain"] = [("loan_line_id", "=", self.id)]
if len(self.move_ids) == 1: if len(self.move_ids) == 1:
res = self.env.ref("account.move.form", False) res = self.env.ref("account.view_move_form", False)
result["views"] = [(res and res.id or False, "form")] result["views"] = [(res and res.id or False, "form")]
result["res_id"] = self.move_ids.id result["res_id"] = self.move_ids.id
return result return result
@ -437,7 +443,6 @@ class AccountLoanLine(models.Model):
} }
result["domain"] = [ result["domain"] = [
("loan_line_id", "=", self.id), ("loan_line_id", "=", self.id),
("move_type", "=", "in_invoice"),
] ]
if len(self.move_ids) == 1: if len(self.move_ids) == 1:
res = self.env.ref("account.view_move_form", False) res = self.env.ref("account.view_move_form", False)

View File

@ -24,11 +24,9 @@ class AccountMove(models.Model):
for record in self: for record in self:
loan_line_id = record.loan_line_id loan_line_id = record.loan_line_id
if loan_line_id: if loan_line_id:
if not record.loan_line_id:
record.loan_line_id = loan_line_id
record.loan_id = loan_line_id.loan_id record.loan_id = loan_line_id.loan_id
record.loan_line_id.check_move_amount() record.loan_line_id._check_move_amount()
record.loan_line_id.loan_id.compute_posted_lines() record.loan_line_id.loan_id._compute_posted_lines()
if record.loan_line_id.sequence == record.loan_id.periods: if record.loan_line_id.sequence == record.loan_id.periods:
record.loan_id.close() record.loan_id.close()
return res return res

View File

@ -0,0 +1,4 @@
16.0.1.0.0
~~~~~~~~~~
Due to the changes on 16, we will generate two moves on leasings, one for the invoice, and another one for the change from long to short term.

View File

@ -1,6 +1,6 @@
To use this module, you need to: To use this module, you need to:
#. Go to `Invoicing / Accounting > Adviser > Loans` #. Go to `Invoicing / Accounting > Accounting > Loans`
#. Configure a loan selecting the company, loan type, amount, rate and accounts #. Configure a loan selecting the company, loan type, amount, rate and accounts
#. Post the loan, it will automatically create an account move with the #. Post the loan, it will automatically create an account move with the
expected amounts expected amounts

View File

@ -3,7 +3,6 @@ access_account_loan,account.loan,model_account_loan,account.group_account_user,1
access_account_loan_manager,account.loan,model_account_loan,account.group_account_manager,1,1,1,1 access_account_loan_manager,account.loan,model_account_loan,account.group_account_manager,1,1,1,1
access_account_loan_line,account.loan.line,model_account_loan_line,account.group_account_user,1,0,0,0 access_account_loan_line,account.loan.line,model_account_loan_line,account.group_account_user,1,0,0,0
access_account_loan_line_manager,account.loan.line,model_account_loan_line,account.group_account_manager,1,1,1,1 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_user,1,0,0,0 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_user,1,0,0,0 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_post,access_account_loan_post,model_account_loan_post,account.group_account_user,1,0,0,0 access_account_loan_post,access_account_loan_post,model_account_loan_post,account.group_account_manager,1,1,1,1
access_account_loan_post_manager,access_account_loan_post_manager,model_account_loan_post,account.group_account_manager,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
3 access_account_loan_manager account.loan model_account_loan account.group_account_manager 1 1 1 1
4 access_account_loan_line account.loan.line model_account_loan_line account.group_account_user 1 0 0 0
5 access_account_loan_line_manager account.loan.line model_account_loan_line account.group_account_manager 1 1 1 1
6 access_account_loan_generate_wizard access_account_loan_generate_wizard model_account_loan_generate_wizard account.group_account_user account.group_account_manager 1 0 1 0 1 0 1
7 access_account_loan_pay_amount access_account_loan_pay_amount model_account_loan_pay_amount account.group_account_user account.group_account_manager 1 0 1 0 1 0 1
8 access_account_loan_post access_account_loan_post model_account_loan_post account.group_account_user account.group_account_manager 1 0 1 0 1 0 1
access_account_loan_post_manager access_account_loan_post_manager model_account_loan_post account.group_account_manager 1 1 1 1

View File

@ -3,18 +3,18 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" /> <meta name="generator" content="Docutils: http://docutils.sourceforge.net/" />
<title>Account Loan management</title> <title>Account Loan management</title>
<style type="text/css"> <style type="text/css">
/* /*
:Author: David Goodger (goodger@python.org) :Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ :Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain. :Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils. Default cascading style sheet for the HTML output of Docutils.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet. customize this style sheet.
*/ */
@ -367,9 +367,9 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:ede8542c931551ec36dabc09621d29b3bcb54586fcad8fd3c4509b95ce8198bf !! source digest: sha256:c9f87eb07ebda20ab00e0446ae5e5908b6a64086fd868f2bfc58e4e9f7dc68b0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-financial-tools/tree/14.0/account_loan"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-financial-tools-14-0/account-financial-tools-14-0-account_loan"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&amp;target_branch=14.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p> <p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/16.0/account_loan"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/account-financial-tools-16-0/account-financial-tools-16-0-account_loan"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module extends the functionality of accounting to support loans. <p>This module extends the functionality of accounting to support loans.
It will create automatically moves or invoices for loans. It will create automatically moves or invoices for loans.
Moreover, you can check the pending amount to be paid and reduce the debt.</p> Moreover, you can check the pending amount to be paid and reduce the debt.</p>
@ -388,18 +388,22 @@ Moreover, you can check the pending amount to be paid and reduce the debt.</p>
<p><strong>Table of contents</strong></p> <p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents"> <div class="contents local topic" id="contents">
<ul class="simple"> <ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li> <li><a class="reference internal" href="#usage" id="id2">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li> <li><a class="reference internal" href="#changelog" id="id3">Changelog</a><ul>
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul> <li><a class="reference internal" href="#id1" id="id4">16.0.1.0.0</a></li>
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li> </ul>
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li> </li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li> <li><a class="reference internal" href="#bug-tracker" id="id5">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id6">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id7">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id8">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id9">Maintainers</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
<div class="section" id="usage"> <div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1> <h1><a class="toc-backref" href="#id2">Usage</a></h1>
<p>To use this module, you need to:</p> <p>To use this module, you need to:</p>
<ol class="arabic simple"> <ol class="arabic simple">
<li>Go to <cite>Invoicing / Accounting &gt; Adviser &gt; Loans</cite></li> <li>Go to <cite>Invoicing / Accounting &gt; Adviser &gt; Loans</cite></li>
@ -417,24 +421,31 @@ leases before a selected date</li>
</ul> </ul>
<a class="reference external image-reference" href="https://runbot.odoo-community.org/runbot/92/12.0"><img alt="Try me on Runbot" src="https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas" /></a> <a class="reference external image-reference" href="https://runbot.odoo-community.org/runbot/92/12.0"><img alt="Try me on Runbot" src="https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas" /></a>
</div> </div>
<div class="section" id="changelog">
<h1><a class="toc-backref" href="#id3">Changelog</a></h1>
<div class="section" id="id1">
<h2><a class="toc-backref" href="#id4">16.0.1.0.0</a></h2>
<p>Due to the changes on 16, we will generate two moves on leasings, one for the invoice, and another one for the change from long to short term.</p>
</div>
</div>
<div class="section" id="bug-tracker"> <div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1> <h1><a class="toc-backref" href="#id5">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>. <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_loan%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p> <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_loan%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-3">Credits</a></h1> <h1><a class="toc-backref" href="#id6">Credits</a></h1>
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-4">Authors</a></h2> <h2><a class="toc-backref" href="#id7">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Creu Blanca</li> <li>Creu Blanca</li>
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2> <h2><a class="toc-backref" href="#id8">Contributors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Enric Tobella &lt;<a class="reference external" href="mailto:etobella&#64;creublanca.es">etobella&#64;creublanca.es</a>&gt;</li> <li>Enric Tobella &lt;<a class="reference external" href="mailto:etobella&#64;creublanca.es">etobella&#64;creublanca.es</a>&gt;</li>
<li>Bhavesh Odedra &lt;<a class="reference external" href="mailto:bodedra&#64;opensourceintegrators.com">bodedra&#64;opensourceintegrators.com</a>&gt;</li> <li>Bhavesh Odedra &lt;<a class="reference external" href="mailto:bodedra&#64;opensourceintegrators.com">bodedra&#64;opensourceintegrators.com</a>&gt;</li>
@ -442,13 +453,15 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
</ul> </ul>
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2> <h2><a class="toc-backref" href="#id9">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p> <p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a> <a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose <p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use.</p> promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/14.0/account_loan">OCA/account-financial-tools</a> project on GitHub.</p> <p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external" href="https://github.com/etobella"><img alt="etobella" src="https://github.com/etobella.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/16.0/account_loan">OCA/account-financial-tools</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p> <p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div> </div>
</div> </div>

View File

@ -18,42 +18,37 @@ except (ImportError, IOError) as err:
@tagged("post_install", "-at_install") @tagged("post_install", "-at_install")
class TestLoan(TransactionCase): class TestLoan(TransactionCase):
def setUp(self): @classmethod
super().setUp() def setUpClass(cls):
self.company = self.browse_ref("base.main_company") super().setUpClass()
self.company_02 = self.env["res.company"].create({"name": "Auxiliar company"}) cls.company = cls.env.ref("base.main_company")
self.journal = self.env["account.journal"].create( cls.company_02 = cls.env["res.company"].create({"name": "Auxiliar company"})
cls.journal = cls.env["account.journal"].create(
{ {
"company_id": self.company.id, "company_id": cls.company.id,
"type": "purchase", "type": "purchase",
"name": "Debts", "name": "Debts",
"code": "DBT", "code": "DBT",
} }
) )
self.loan_account = self.create_account( cls.loan_account = cls.create_account(
"DEP", "DEP",
"depreciation", "depreciation",
self.browse_ref("account.data_account_type_current_liabilities").id, "liability_current",
) )
self.payable_account = self.create_account( cls.payable_account = cls.create_account("PAY", "payable", "liability_payable")
"PAY", "payable", self.browse_ref("account.data_account_type_payable").id cls.asset_account = cls.create_account("ASSET", "asset", "liability_payable")
) cls.interests_account = cls.create_account("FEE", "Fees", "expense")
self.asset_account = self.create_account( cls.lt_loan_account = cls.create_account(
"ASSET", "asset", self.browse_ref("account.data_account_type_payable").id
)
self.interests_account = self.create_account(
"FEE", "Fees", self.browse_ref("account.data_account_type_expenses").id
)
self.lt_loan_account = self.create_account(
"LTD", "LTD",
"Long term depreciation", "Long term depreciation",
self.browse_ref("account.data_account_type_non_current_liabilities").id, "liability_non_current",
) )
self.partner = self.env["res.partner"].create({"name": "Bank"}) cls.partner = cls.env["res.partner"].create({"name": "Bank"})
self.product = self.env["product.product"].create( cls.product = cls.env["product.product"].create(
{"name": "Payment", "type": "service"} {"name": "Payment", "type": "service"}
) )
self.interests_product = self.env["product.product"].create( cls.interests_product = cls.env["product.product"].create(
{"name": "Bank fee", "type": "service"} {"name": "Bank fee", "type": "service"}
) )
@ -281,8 +276,10 @@ class TestLoan(TransactionCase):
) )
self.assertTrue(line.has_invoices) self.assertTrue(line.has_invoices)
self.assertTrue(line.has_moves) self.assertTrue(line.has_moves)
self.assertIn(line.move_ids.id, action["domain"][0][2]) self.assertEqual(
loan.refresh() line.move_ids, self.env[action["res_model"]].search(action["domain"])
)
loan.invalidate_recordset()
with self.assertRaises(UserError): with self.assertRaises(UserError):
self.env["account.loan.pay.amount"].create( self.env["account.loan.pay.amount"].create(
{ {
@ -303,17 +300,21 @@ class TestLoan(TransactionCase):
} }
).run() ).run()
self.assertTrue(line.move_ids) self.assertTrue(line.move_ids)
self.assertEqual(line.move_ids.state, "draft") self.assertTrue(line.move_ids.filtered(lambda r: r.is_invoice()))
self.assertTrue(line.move_ids.filtered(lambda r: not r.is_invoice()))
self.assertTrue(all([m.state == "draft" for m in line.move_ids]))
self.assertTrue(line.has_moves) self.assertTrue(line.has_moves)
line.move_ids.action_post() line.move_ids.action_post()
self.assertEqual(line.move_ids.state, "posted") self.assertTrue(all([m.state == "posted" for m in line.move_ids]))
for move in line.move_ids:
self.assertIn( self.assertIn(
line.move_ids.id, move,
self.env["account.move"].search(loan.view_account_moves()["domain"]).ids, self.env["account.move"].search(loan.view_account_moves()["domain"]),
) )
self.assertEqual( for move in line.move_ids.filtered(lambda r: r.is_invoice()):
line.move_ids.id, self.assertIn(
self.env["account.move"].search(loan.view_account_invoices()["domain"]).id, move,
self.env["account.move"].search(loan.view_account_invoices()["domain"]),
) )
with self.assertRaises(UserError): with self.assertRaises(UserError):
self.env["account.loan.pay.amount"].create( self.env["account.loan.pay.amount"].create(
@ -398,7 +399,7 @@ class TestLoan(TransactionCase):
self.assertTrue(line.move_ids) self.assertTrue(line.move_ids)
self.assertEqual(line.move_ids.state, "posted") self.assertEqual(line.move_ids.state, "posted")
self.assertEqual(loan.state, "closed") self.assertEqual(loan.state, "closed")
loan.refresh() loan.invalidate_recordset()
self.assertEqual(loan.payment_amount - loan.interests_amount, amount) self.assertEqual(loan.payment_amount - loan.interests_amount, amount)
self.assertEqual(loan.pending_principal_amount, 0) self.assertEqual(loan.pending_principal_amount, 0)
@ -432,13 +433,14 @@ class TestLoan(TransactionCase):
with self.assertRaises(UserError): with self.assertRaises(UserError):
post.run() post.run()
def create_account(self, code, name, type_id): @classmethod
return self.env["account.account"].create( def create_account(cls, code, name, account_type):
return cls.env["account.account"].create(
{ {
"company_id": self.company.id, "company_id": cls.company.id,
"name": name, "name": name,
"code": code, "code": code,
"user_type_id": type_id, "account_type": account_type,
"reconcile": True, "reconcile": True,
} }
) )

View File

@ -7,7 +7,7 @@
<field name="name">account.loan.tree</field> <field name="name">account.loan.tree</field>
<field name="model">account.loan</field> <field name="model">account.loan</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Loans"> <tree>
<field name="name" /> <field name="name" />
<field name="company_id" /> <field name="company_id" />
<field name="is_leasing" /> <field name="is_leasing" />
@ -22,7 +22,7 @@
<field name="name">account.loan.form</field> <field name="name">account.loan.form</field>
<field name="model">account.loan</field> <field name="model">account.loan</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Loan"> <form>
<header> <header>
<button name="compute_lines" type="object" string="Compute items" /> <button name="compute_lines" type="object" string="Compute items" />
<button <button
@ -30,11 +30,12 @@
states="draft" states="draft"
type="action" type="action"
string="Post" string="Post"
groups="account.group_account_manager"
/> />
<field name="state" widget="statusbar" /> <field name="state" widget="statusbar" />
</header> </header>
<sheet> <sheet>
<div class="oe_button_box"> <div name="button_box" class="oe_button_box">
<button <button
name="view_account_moves" name="view_account_moves"
class="oe_stat_button" class="oe_stat_button"
@ -58,6 +59,7 @@
attrs="{'invisible': [('state', '!=', 'posted')]}" attrs="{'invisible': [('state', '!=', 'posted')]}"
type="action" type="action"
string="Pay amount" string="Pay amount"
groups="account.group_account_manager"
/> />
</div> </div>
<h1> <h1>
@ -153,7 +155,7 @@
<field name="name">account.loan.line.tree</field> <field name="name">account.loan.line.tree</field>
<field name="model">account.loan.line</field> <field name="model">account.loan.line</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Loan items" create="0"> <tree create="0">
<field name="sequence" /> <field name="sequence" />
<field name="date" /> <field name="date" />
<field name="rate" /> <field name="rate" />

View File

@ -18,18 +18,18 @@ class AccountLoanGenerateWizard(models.TransientModel):
[("leasing", "Leasings"), ("loan", "Loans")], required=True, default="loan" [("leasing", "Leasings"), ("loan", "Loans")], required=True, default="loan"
) )
def run_leasing(self): def _run_leasing(self):
created_ids = self.env["account.loan"].generate_leasing_entries(self.date) created_ids = self.env["account.loan"]._generate_leasing_entries(self.date)
result = self.env["ir.actions.act_window"]._for_xml_id( result = self.env["ir.actions.act_window"]._for_xml_id(
"account.action_move_out_invoice_type" "account.action_move_out_invoice_type"
) )
if len(created_ids) == 0: if len(created_ids) == 0:
return return
result["domain"] = [("id", "in", created_ids), ("type", "=", "in_invoice")] result["domain"] = [("id", "in", created_ids)]
return result return result
def run_loan(self): def _run_loan(self):
created_ids = self.env["account.loan"].generate_loan_entries(self.date) created_ids = self.env["account.loan"]._generate_loan_entries(self.date)
result = self.env["ir.actions.act_window"]._for_xml_id( result = self.env["ir.actions.act_window"]._for_xml_id(
"account.action_move_line_form" "account.action_move_line_form"
) )
@ -41,5 +41,5 @@ class AccountLoanGenerateWizard(models.TransientModel):
def run(self): def run(self):
self.ensure_one() self.ensure_one()
if self.loan_type == "leasing": if self.loan_type == "leasing":
return self.run_leasing() return self._run_leasing()
return self.run_loan() return self._run_loan()

View File

@ -37,6 +37,6 @@
id="account_loan_generate_wizard_menu" id="account_loan_generate_wizard_menu"
parent="account.menu_finance_entries_generate_entries" parent="account.menu_finance_entries_generate_entries"
sequence="111" sequence="111"
groups="base.group_no_one" groups="account.group_account_manager"
/> />
</odoo> </odoo>

View File

@ -69,7 +69,7 @@ class AccountLoan(models.TransientModel):
sequence = min(lines.mapped("sequence")) sequence = min(lines.mapped("sequence"))
for line in lines: for line in lines:
line.sequence += 1 line.sequence += 1
line.flush() line.flush_recordset()
old_line = lines.filtered(lambda r: r.sequence == sequence + 1) old_line = lines.filtered(lambda r: r.sequence == sequence + 1)
pending = old_line.pending_principal_amount pending = old_line.pending_principal_amount
if self.loan_id.currency_id.compare_amounts(self.amount, pending) == 1: if self.loan_id.currency_id.compare_amounts(self.amount, pending) == 1:
@ -91,10 +91,10 @@ class AccountLoan(models.TransientModel):
line.pending_principal_amount = amount line.pending_principal_amount = amount
if line.sequence != sequence: if line.sequence != sequence:
line.rate = self.loan_id.rate_period line.rate = self.loan_id.rate_period
line.check_amount() line._check_amount()
amount -= line.payment_amount - line.interests_amount amount -= line.payment_amount - line.interests_amount
if self.loan_id.long_term_loan_account_id: if self.loan_id.long_term_loan_account_id:
self.loan_id.check_long_term_principal_amount() self.loan_id._check_long_term_principal_amount()
if self.loan_id.currency_id.compare_amounts(pending, self.amount) == 0: if self.loan_id.currency_id.compare_amounts(pending, self.amount) == 0:
self.loan_id.write({"state": "cancelled"}) self.loan_id.write({"state": "cancelled"})
return new_line.view_process_values() return new_line.view_process_values()

View File

@ -1,6 +1,6 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details. # Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import _, api, fields, models from odoo import Command, _, api, fields, models
from odoo.exceptions import UserError from odoo.exceptions import UserError
@ -81,7 +81,7 @@ class AccountLoanPost(models.TransientModel):
"date": self.loan_id.start_date, "date": self.loan_id.start_date,
"ref": self.loan_id.name, "ref": self.loan_id.name,
"journal_id": self.journal_id.id, "journal_id": self.journal_id.id,
"line_ids": [(0, 0, vals) for vals in self.move_line_vals()], "line_ids": [Command.create(vals) for vals in self.move_line_vals()],
} }
def run(self): def run(self):