[MIG] account_loan: Mirgation to 16.0
This commit is contained in:
parent
e5e38a86e0
commit
bf6075876f
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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"],
|
||||||
|
@ -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):
|
||||||
if vals.get("name", "/") == "/":
|
for vals in vals_list:
|
||||||
vals["name"] = self.get_default_name(vals)
|
if vals.get("name", "/") == "/":
|
||||||
return super().create(vals)
|
vals["name"] = self._get_default_name(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
|
@ -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(
|
||||||
if record.loan_id.post_invoice:
|
record._long_term_move_vals()
|
||||||
invoice.action_post()
|
)
|
||||||
|
if record.loan_id.post_invoice:
|
||||||
|
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,
|
"account_id": self.loan_id.short_term_loan_account_id.id,
|
||||||
0,
|
"credit": self.long_term_principal_amount,
|
||||||
{
|
"debit": 0,
|
||||||
"account_id": self.loan_id.short_term_loan_account_id.id,
|
},
|
||||||
"credit": self.long_term_principal_amount,
|
{
|
||||||
"debit": 0,
|
"account_id": self.long_term_loan_account_id.id,
|
||||||
"exclude_from_invoice_tab": True,
|
"credit": 0,
|
||||||
},
|
"debit": self.long_term_principal_amount,
|
||||||
),
|
},
|
||||||
(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
{
|
|
||||||
"account_id": self.long_term_loan_account_id.id,
|
|
||||||
"credit": 0,
|
|
||||||
"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)
|
@ -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
|
4
account_loan/readme/HISTORY.rst
Normal file
4
account_loan/readme/HISTORY.rst
Normal 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.
|
@ -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
|
||||||
|
@ -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,20 +1,20 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<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&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&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 > Adviser > Loans</cite></li>
|
<li>Go to <cite>Invoicing / Accounting > Adviser > 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 <<a class="reference external" href="mailto:etobella@creublanca.es">etobella@creublanca.es</a>></li>
|
<li>Enric Tobella <<a class="reference external" href="mailto:etobella@creublanca.es">etobella@creublanca.es</a>></li>
|
||||||
<li>Bhavesh Odedra <<a class="reference external" href="mailto:bodedra@opensourceintegrators.com">bodedra@opensourceintegrators.com</a>></li>
|
<li>Bhavesh Odedra <<a class="reference external" href="mailto:bodedra@opensourceintegrators.com">bodedra@opensourceintegrators.com</a>></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>
|
||||||
|
@ -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,18 +300,22 @@ 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]))
|
||||||
self.assertIn(
|
for move in line.move_ids:
|
||||||
line.move_ids.id,
|
self.assertIn(
|
||||||
self.env["account.move"].search(loan.view_account_moves()["domain"]).ids,
|
move,
|
||||||
)
|
self.env["account.move"].search(loan.view_account_moves()["domain"]),
|
||||||
self.assertEqual(
|
)
|
||||||
line.move_ids.id,
|
for move in line.move_ids.filtered(lambda r: r.is_invoice()):
|
||||||
self.env["account.move"].search(loan.view_account_invoices()["domain"]).id,
|
self.assertIn(
|
||||||
)
|
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,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -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" />
|
||||||
|
@ -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()
|
@ -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>
|
@ -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()
|
@ -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):
|
Loading…
Reference in New Issue
Block a user