mirror of
https://github.com/OCA/account-financial-tools.git
synced 2025-02-02 12:47:26 +02:00
[MIG] account_loan: Migration to 13.0
Co-authored-by: Enric Tobella <etobella@creublanca.es> [UPD] Update account_loan.pot [UPD] README.rst
This commit is contained in:
committed by
Víctor Martínez
parent
f91d710bc5
commit
35efc16a0e
@@ -14,13 +14,13 @@ Account Loan management
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
.. |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/12.0/account_loan
|
||||
:target: https://github.com/OCA/account-financial-tools/tree/13.0/account_loan
|
||||
:alt: OCA/account-financial-tools
|
||||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
||||
:target: https://translation.odoo-community.org/projects/account-financial-tools-12-0/account-financial-tools-12-0-account_loan
|
||||
:target: https://translation.odoo-community.org/projects/account-financial-tools-13-0/account-financial-tools-13-0-account_loan
|
||||
:alt: Translate me on Weblate
|
||||
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
|
||||
:target: https://runbot.odoo-community.org/runbot/92/12.0
|
||||
:target: https://runbot.odoo-community.org/runbot/92/13.0
|
||||
:alt: Try me on Runbot
|
||||
|
||||
|badge1| |badge2| |badge3| |badge4| |badge5|
|
||||
@@ -71,7 +71,7 @@ Bug Tracker
|
||||
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.
|
||||
If you spotted it first, help us smashing it by providing a detailed and welcomed
|
||||
`feedback <https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_loan%0Aversion:%2012.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:%2013.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.
|
||||
|
||||
@@ -103,6 +103,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/12.0/account_loan>`_ project on GitHub.
|
||||
This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/13.0/account_loan>`_ project on GitHub.
|
||||
|
||||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
{
|
||||
"name": "Account Loan management",
|
||||
"version": "12.0.1.1.0",
|
||||
"version": "13.0.1.1.0",
|
||||
"author": "Creu Blanca,Odoo Community Association (OCA)",
|
||||
"website": "http://github.com/OCA/account-financial-tools",
|
||||
"license": "AGPL-3",
|
||||
@@ -19,5 +19,5 @@
|
||||
"views/account_move_view.xml",
|
||||
],
|
||||
"installable": True,
|
||||
"external_dependencies": {"python": ["numpy",],},
|
||||
"external_dependencies": {"python": ["numpy", "numpy-financial<=1.0.0"]},
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * account_loan
|
||||
# * account_loan
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 12.0\n"
|
||||
"Project-Id-Version: Odoo Server 13.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"Last-Translator: <>\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -54,25 +54,30 @@ msgstr ""
|
||||
msgid "Activities"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_loan__activity_exception_decoration
|
||||
msgid "Activity Exception Decoration"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_loan__activity_state
|
||||
msgid "Activity State"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:82
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:0
|
||||
#, python-format
|
||||
msgid "Amount cannot be bigger than debt"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:84
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:0
|
||||
#, python-format
|
||||
msgid "Amount cannot be less than zero"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: code:addons/account_loan/model/account_loan_line.py:186
|
||||
#: code:addons/account_loan/model/account_loan_line.py:0
|
||||
#, python-format
|
||||
msgid "Amount cannot be recomputed if moves or invoices exists already"
|
||||
msgstr ""
|
||||
@@ -125,17 +130,19 @@ msgid "Cancel Loan"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,state:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan__state__cancelled
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan_generate_wizard__date
|
||||
msgid "Choose the period for which you want to automatically post the depreciation lines of running assets"
|
||||
msgid ""
|
||||
"Choose the period for which you want to automatically post the depreciation "
|
||||
"lines of running assets"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,state:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan__state__closed
|
||||
msgid "Closed"
|
||||
msgstr ""
|
||||
|
||||
@@ -205,12 +212,12 @@ msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,state:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan__state__draft
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,rate_type:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan__rate_type__ear
|
||||
msgid "EAR"
|
||||
msgstr ""
|
||||
|
||||
@@ -225,12 +232,12 @@ msgid "Fixed Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,loan_type:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan__loan_type__fixed-annuity
|
||||
msgid "Fixed Annuity"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,loan_type:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan__loan_type__fixed-annuity-begin
|
||||
msgid "Fixed Annuity Begin"
|
||||
msgstr ""
|
||||
|
||||
@@ -245,7 +252,7 @@ msgid "Fixed Periods"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,loan_type:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan__loan_type__fixed-principal
|
||||
msgid "Fixed Principal"
|
||||
msgstr ""
|
||||
|
||||
@@ -295,17 +302,24 @@ msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__message_unread
|
||||
msgid "If checked new messages require your attention."
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_loan__activity_exception_icon
|
||||
msgid "Icon"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__activity_exception_icon
|
||||
msgid "Icon to indicate an exception activity."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__message_needaction
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__message_unread
|
||||
msgid "If checked, new messages require your attention."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__message_has_error
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__message_has_sms_error
|
||||
msgid "If checked, some messages have a delivery error."
|
||||
msgstr ""
|
||||
|
||||
@@ -324,12 +338,6 @@ msgstr ""
|
||||
msgid "Interests account"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model,name:account_loan.model_account_invoice
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_loan_line__invoice_ids
|
||||
msgid "Invoice"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model_terms:ir.ui.view,arch_db:account_loan.account_loan_form
|
||||
msgid "Invoices"
|
||||
@@ -410,7 +418,7 @@ msgid "Leasing"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan.generate.wizard,loan_type:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan_generate_wizard__loan_type__leasing
|
||||
msgid "Leasings"
|
||||
msgstr ""
|
||||
|
||||
@@ -426,7 +434,6 @@ msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model,name:account_loan.model_account_loan
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_invoice__loan_id
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_loan_line__loan_id
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_loan_pay_amount__loan_id
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_loan_post__loan_id
|
||||
@@ -441,7 +448,6 @@ msgid "Loan Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_invoice__loan_line_id
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_move__loan_line_id
|
||||
msgid "Loan Line"
|
||||
msgstr ""
|
||||
@@ -464,7 +470,7 @@ msgid "Loan items"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: sql_constraint:account.loan:0
|
||||
#: model:ir.model.constraint,message:account_loan.constraint_account_loan_name_uniq
|
||||
msgid "Loan name must be unique"
|
||||
msgstr ""
|
||||
|
||||
@@ -484,8 +490,8 @@ msgid "Loan product"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan.generate.wizard,loan_type:0
|
||||
#: model:ir.actions.act_window,name:account_loan.account_loan_action
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan_generate_wizard__loan_type__loan
|
||||
#: model:ir.ui.menu,name:account_loan.account_loan_menu
|
||||
#: model_terms:ir.ui.view,arch_db:account_loan.account_loan_tree
|
||||
msgid "Loans"
|
||||
@@ -566,7 +572,7 @@ msgid "Next Activity Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,rate_type:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan__rate_type__napr
|
||||
msgid "Nominal APR"
|
||||
msgstr ""
|
||||
|
||||
@@ -577,7 +583,7 @@ msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_loan__message_has_error_counter
|
||||
msgid "Number of error"
|
||||
msgid "Number of errors"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
@@ -601,21 +607,16 @@ msgid "Number of unread messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,loan_type:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan__loan_type__interest
|
||||
msgid "Only interest"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: code:addons/account_loan/wizard/account_loan_post.py:91
|
||||
#: code:addons/account_loan/wizard/account_loan_post.py:0
|
||||
#, python-format
|
||||
msgid "Only loans in draft state can be posted"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,activity_state:0
|
||||
msgid "Overdue"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.actions.act_window,name:account_loan.account_loan_pay_amount_action
|
||||
#: model_terms:ir.ui.view,arch_db:account_loan.account_loan_form
|
||||
@@ -652,7 +653,9 @@ msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan_line__long_term_pending_principal_amount
|
||||
msgid "Pending amount of the loan before the payment that will not be payed in, at least, 12 months"
|
||||
msgid ""
|
||||
"Pending amount of the loan before the payment that will not be payed in, at "
|
||||
"least, 12 months"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
@@ -665,11 +668,6 @@ msgstr ""
|
||||
msgid "Periods"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,activity_state:0
|
||||
msgid "Planned"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model_terms:ir.ui.view,arch_db:account_loan.account_loan_form
|
||||
msgid "Post"
|
||||
@@ -686,7 +684,7 @@ msgid "Post loan"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,state:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan__state__posted
|
||||
msgid "Posted"
|
||||
msgstr ""
|
||||
|
||||
@@ -702,12 +700,16 @@ msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__interests_product_id
|
||||
msgid "Product where the amount of interests will be assigned when the invoice is created"
|
||||
msgid ""
|
||||
"Product where the amount of interests will be assigned when the invoice is "
|
||||
"created"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__product_id
|
||||
msgid "Product where the amount of the loan will be assigned when the invoice is created"
|
||||
msgid ""
|
||||
"Product where the amount of the loan will be assigned when the invoice is "
|
||||
"created"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
@@ -727,7 +729,7 @@ msgid "Rate Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,rate_type:0
|
||||
#: model:ir.model.fields.selection,name:account_loan.selection__account_loan__rate_type__real
|
||||
msgid "Real rate"
|
||||
msgstr ""
|
||||
|
||||
@@ -743,7 +745,9 @@ msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__residual_amount
|
||||
msgid "Residual amount of the lease that must be payed on the end in order to acquire the asset"
|
||||
msgid ""
|
||||
"Residual amount of the lease that must be payed on the end in order to "
|
||||
"acquire the asset"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
@@ -763,13 +767,18 @@ msgstr ""
|
||||
msgid "Run"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_loan__message_has_sms_error
|
||||
msgid "SMS Delivery error"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_loan_line__sequence
|
||||
msgid "Sequence"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: sql_constraint:account.loan.line:0
|
||||
#: model:ir.model.constraint,message:account_loan.constraint_account_loan_line_sequence_loan
|
||||
msgid "Sequence must be unique in a loan"
|
||||
msgstr ""
|
||||
|
||||
@@ -779,37 +788,37 @@ msgid "Short term account"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:65
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:0
|
||||
#, python-format
|
||||
msgid "Some future invoices already exists"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:73
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:0
|
||||
#, python-format
|
||||
msgid "Some future moves already exists"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:61
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:0
|
||||
#, python-format
|
||||
msgid "Some invoices are not created"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: code:addons/account_loan/model/account_loan_line.py:358
|
||||
#: code:addons/account_loan/model/account_loan_line.py:0
|
||||
#, python-format
|
||||
msgid "Some invoices must be created first"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:69
|
||||
#: code:addons/account_loan/wizard/account_loan_pay_amount.py:0
|
||||
#, python-format
|
||||
msgid "Some moves are not created"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: code:addons/account_loan/model/account_loan_line.py:340
|
||||
#: code:addons/account_loan/model/account_loan_line.py:0
|
||||
#, python-format
|
||||
msgid "Some moves must be created first"
|
||||
msgstr ""
|
||||
@@ -837,17 +846,13 @@ msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__activity_state
|
||||
msgid "Status based on activities\n"
|
||||
msgid ""
|
||||
"Status based on activities\n"
|
||||
"Overdue: Due date is already passed\n"
|
||||
"Today: Activity date is today\n"
|
||||
"Planned: Future activities."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: selection:account.loan,activity_state:0
|
||||
msgid "Today"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan_line__payment_amount
|
||||
msgid "Total amount that will be payed (Annuity)"
|
||||
@@ -873,6 +878,11 @@ msgstr ""
|
||||
msgid "Total payments"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__activity_exception_decoration
|
||||
msgid "Type of the exception activity on record."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,field_description:account_loan.field_account_loan__message_unread
|
||||
msgid "Unread Messages"
|
||||
@@ -900,7 +910,9 @@ msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
#: model:ir.model.fields,help:account_loan.field_account_loan__round_on_end
|
||||
msgid "When checked, the differences will be applied on the last period, if it is unchecked, the annuity will be recalculated on each period."
|
||||
msgid ""
|
||||
"When checked, the differences will be applied on the last period, if it is "
|
||||
"unchecked, the annuity will be recalculated on each period."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_loan
|
||||
@@ -914,4 +926,3 @@ msgstr ""
|
||||
#: model_terms:ir.ui.view,arch_db:account_loan.account_loan_post_form
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
|
||||
|
||||
16
account_loan/migrations/13.0.1.1.0/post-migration.py
Normal file
16
account_loan/migrations/13.0.1.1.0/post-migration.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# Copyright 2021 Creu Blanca - Alba Riera
|
||||
|
||||
from openupgradelib import openupgrade
|
||||
|
||||
|
||||
@openupgrade.migrate()
|
||||
def migrate(env, version):
|
||||
openupgrade.logged_query(
|
||||
env.cr,
|
||||
"""
|
||||
UPDATE account_move am
|
||||
SET loan_line_id = ai.loan_line_id,
|
||||
loan_id = ai.loan_id
|
||||
FROM account_invoice ai
|
||||
WHERE ai.id = am.old_invoice_id and ai.loan_id is not null""",
|
||||
)
|
||||
@@ -1,7 +1,6 @@
|
||||
# Copyright 2018 Creu Blanca
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import account_invoice
|
||||
from . import account_loan
|
||||
from . import account_loan_line
|
||||
from . import account_move
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
# Copyright 2018 Creu Blanca
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class AccountInvoice(models.Model):
|
||||
_inherit = "account.invoice"
|
||||
|
||||
loan_line_id = fields.Many2one(
|
||||
"account.loan.line", readonly=True, ondelete="restrict",
|
||||
)
|
||||
loan_id = fields.Many2one(
|
||||
"account.loan", readonly=True, store=True, ondelete="restrict",
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def finalize_invoice_move_lines(self, move_lines):
|
||||
vals = super().finalize_invoice_move_lines(move_lines)
|
||||
if self.loan_line_id:
|
||||
ll = self.loan_line_id
|
||||
if ll.long_term_loan_account_id and ll.long_term_principal_amount != 0:
|
||||
vals.append(
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"account_id": ll.loan_id.short_term_loan_account_id.id,
|
||||
"credit": ll.long_term_principal_amount,
|
||||
"debit": 0,
|
||||
},
|
||||
)
|
||||
)
|
||||
vals.append(
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"account_id": ll.long_term_loan_account_id.id,
|
||||
"credit": 0,
|
||||
"debit": ll.long_term_principal_amount,
|
||||
},
|
||||
)
|
||||
)
|
||||
return vals
|
||||
@@ -11,7 +11,7 @@ from odoo import api, fields, models
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
try:
|
||||
import numpy
|
||||
import numpy_financial
|
||||
except (ImportError, IOError) as err:
|
||||
_logger.debug(err)
|
||||
|
||||
@@ -96,7 +96,7 @@ class AccountLoan(models.Model):
|
||||
help="Real rate that will be applied on each period",
|
||||
)
|
||||
rate_type = fields.Selection(
|
||||
[("napr", "Nominal APR"), ("ear", "EAR"), ("real", "Real rate"),],
|
||||
[("napr", "Nominal APR"), ("ear", "EAR"), ("real", "Real rate")],
|
||||
required=True,
|
||||
help="Method of computation of the applied rate",
|
||||
default="napr",
|
||||
@@ -253,7 +253,7 @@ class AccountLoan(models.Model):
|
||||
for record in self:
|
||||
if record.loan_type == "fixed-annuity":
|
||||
record.fixed_amount = -record.currency_id.round(
|
||||
numpy.pmt(
|
||||
numpy_financial.pmt(
|
||||
record.loan_rate() / 100,
|
||||
record.fixed_periods,
|
||||
record.fixed_loan_amount,
|
||||
@@ -262,7 +262,7 @@ class AccountLoan(models.Model):
|
||||
)
|
||||
elif record.loan_type == "fixed-annuity-begin":
|
||||
record.fixed_amount = -record.currency_id.round(
|
||||
numpy.pmt(
|
||||
numpy_financial.pmt(
|
||||
record.loan_rate() / 100,
|
||||
record.fixed_periods,
|
||||
record.fixed_loan_amount,
|
||||
@@ -341,7 +341,6 @@ class AccountLoan(models.Model):
|
||||
vals["name"] = self.get_default_name(vals)
|
||||
return super().create(vals)
|
||||
|
||||
@api.multi
|
||||
def post(self):
|
||||
self.ensure_one()
|
||||
if not self.start_date:
|
||||
@@ -349,11 +348,9 @@ class AccountLoan(models.Model):
|
||||
self.compute_draft_lines()
|
||||
self.write({"state": "posted"})
|
||||
|
||||
@api.multi
|
||||
def close(self):
|
||||
self.write({"state": "closed"})
|
||||
|
||||
@api.multi
|
||||
def compute_lines(self):
|
||||
self.ensure_one()
|
||||
if self.state == "draft":
|
||||
@@ -407,7 +404,6 @@ class AccountLoan(models.Model):
|
||||
"rate": self.rate_period,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def compute_draft_lines(self):
|
||||
self.ensure_one()
|
||||
self.fixed_periods = self.periods
|
||||
@@ -431,7 +427,6 @@ class AccountLoan(models.Model):
|
||||
if self.long_term_loan_account_id:
|
||||
self.check_long_term_principal_amount()
|
||||
|
||||
@api.multi
|
||||
def view_account_moves(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref("account.action_move_line_form")
|
||||
@@ -439,10 +434,9 @@ class AccountLoan(models.Model):
|
||||
result["domain"] = [("loan_id", "=", self.id)]
|
||||
return result
|
||||
|
||||
@api.multi
|
||||
def view_account_invoices(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref("account.action_invoice_tree2")
|
||||
action = self.env.ref("account.action_move_out_invoice_type")
|
||||
result = action.read()[0]
|
||||
result["domain"] = [("loan_id", "=", self.id), ("type", "=", "in_invoice")]
|
||||
return result
|
||||
@@ -471,6 +465,6 @@ class AccountLoan(models.Model):
|
||||
[("state", "=", "posted"), ("is_leasing", "=", True)]
|
||||
):
|
||||
res += record.line_ids.filtered(
|
||||
lambda r: r.date <= date and not r.invoice_ids
|
||||
lambda r: r.date <= date and not r.move_ids
|
||||
).generate_invoice()
|
||||
return res
|
||||
|
||||
@@ -8,7 +8,7 @@ from odoo.exceptions import UserError
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
try:
|
||||
import numpy
|
||||
import numpy_financial
|
||||
except (ImportError, IOError) as err:
|
||||
_logger.error(err)
|
||||
|
||||
@@ -90,7 +90,6 @@ class AccountLoanLine(models.Model):
|
||||
)
|
||||
move_ids = fields.One2many("account.move", inverse_name="loan_line_id",)
|
||||
has_moves = fields.Boolean(compute="_compute_has_moves")
|
||||
invoice_ids = fields.One2many("account.invoice", inverse_name="loan_line_id",)
|
||||
has_invoices = fields.Boolean(compute="_compute_has_invoices")
|
||||
_sql_constraints = [
|
||||
(
|
||||
@@ -105,10 +104,10 @@ class AccountLoanLine(models.Model):
|
||||
for record in self:
|
||||
record.has_moves = bool(record.move_ids)
|
||||
|
||||
@api.depends("invoice_ids")
|
||||
@api.depends("move_ids")
|
||||
def _compute_has_invoices(self):
|
||||
for record in self:
|
||||
record.has_invoices = bool(record.invoice_ids)
|
||||
record.has_invoices = bool(record.move_ids)
|
||||
|
||||
@api.depends("loan_id.name", "sequence")
|
||||
def _compute_name(self):
|
||||
@@ -146,7 +145,7 @@ class AccountLoanLine(models.Model):
|
||||
return self.loan_id.fixed_amount
|
||||
if self.loan_type == "fixed-annuity":
|
||||
return self.currency_id.round(
|
||||
-numpy.pmt(
|
||||
-numpy_financial.pmt(
|
||||
self.loan_id.loan_rate() / 100,
|
||||
self.loan_id.periods - self.sequence + 1,
|
||||
self.pending_principal_amount,
|
||||
@@ -157,7 +156,7 @@ class AccountLoanLine(models.Model):
|
||||
return self.loan_id.fixed_amount
|
||||
if self.loan_type == "fixed-annuity-begin":
|
||||
return self.currency_id.round(
|
||||
-numpy.pmt(
|
||||
-numpy_financial.pmt(
|
||||
self.loan_id.loan_rate() / 100,
|
||||
self.loan_id.periods - self.sequence + 1,
|
||||
self.pending_principal_amount,
|
||||
@@ -168,7 +167,7 @@ class AccountLoanLine(models.Model):
|
||||
|
||||
def check_amount(self):
|
||||
"""Recompute amounts if the annuity has not been processed"""
|
||||
if self.move_ids or self.invoice_ids:
|
||||
if self.move_ids:
|
||||
raise UserError(
|
||||
_("Amount cannot be recomputed if moves or invoices exists " "already")
|
||||
)
|
||||
@@ -192,7 +191,7 @@ class AccountLoanLine(models.Model):
|
||||
|
||||
def compute_interest(self):
|
||||
if self.loan_type == "fixed-annuity-begin":
|
||||
return -numpy.ipmt(
|
||||
return -numpy_financial.ipmt(
|
||||
self.loan_id.loan_rate() / 100,
|
||||
2,
|
||||
self.loan_id.periods - self.sequence + 1,
|
||||
@@ -202,7 +201,6 @@ class AccountLoanLine(models.Model):
|
||||
)
|
||||
return self.pending_principal_amount * self.loan_id.loan_rate() / 100
|
||||
|
||||
@api.multi
|
||||
def check_move_amount(self):
|
||||
"""
|
||||
Changes the amounts of the annuity once the move is posted
|
||||
@@ -286,16 +284,12 @@ class AccountLoanLine(models.Model):
|
||||
return vals
|
||||
|
||||
def invoice_vals(self):
|
||||
partner = self.loan_id.partner_id.with_context(
|
||||
force_company=self.loan_id.company_id.id
|
||||
)
|
||||
return {
|
||||
"loan_line_id": self.id,
|
||||
"loan_id": self.loan_id.id,
|
||||
"type": "in_invoice",
|
||||
"partner_id": self.loan_id.partner_id.id,
|
||||
"date_invoice": self.date,
|
||||
"account_id": partner.property_account_payable_id.id,
|
||||
"invoice_date": self.date,
|
||||
"journal_id": self.loan_id.journal_id.id,
|
||||
"company_id": self.loan_id.company_id.id,
|
||||
"invoice_line_ids": [(0, 0, vals) for vals in self.invoice_line_vals()],
|
||||
@@ -323,7 +317,6 @@ class AccountLoanLine(models.Model):
|
||||
)
|
||||
return vals
|
||||
|
||||
@api.multi
|
||||
def generate_move(self):
|
||||
"""
|
||||
Computes and post the moves of loans
|
||||
@@ -341,29 +334,59 @@ class AccountLoanLine(models.Model):
|
||||
res.append(move.id)
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def generate_invoice(self):
|
||||
"""
|
||||
Computes invoices of leases
|
||||
:return: list of account.invoice generated
|
||||
:return: list of account.move generated
|
||||
"""
|
||||
res = []
|
||||
for record in self:
|
||||
if not record.invoice_ids:
|
||||
if not record.move_ids:
|
||||
if record.loan_id.line_ids.filtered(
|
||||
lambda r: r.date < record.date and not r.invoice_ids
|
||||
lambda r: r.date < record.date and not r.move_ids
|
||||
):
|
||||
raise UserError(_("Some invoices must be created first"))
|
||||
invoice = self.env["account.invoice"].create(record.invoice_vals())
|
||||
invoice = self.env["account.move"].create(record.invoice_vals())
|
||||
res.append(invoice.id)
|
||||
for line in invoice.invoice_line_ids:
|
||||
line._set_taxes()
|
||||
invoice.compute_taxes()
|
||||
line.tax_ids = line._get_computed_taxes()
|
||||
invoice.with_context(
|
||||
check_move_validity=False
|
||||
)._recompute_dynamic_lines(recompute_all_taxes=True)
|
||||
invoice._check_balanced()
|
||||
if (
|
||||
record.long_term_loan_account_id
|
||||
and record.long_term_principal_amount != 0
|
||||
):
|
||||
invoice.write({"line_ids": record._get_long_term_move_line_vals()})
|
||||
if record.loan_id.post_invoice:
|
||||
invoice.action_invoice_open()
|
||||
invoice.post()
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def _get_long_term_move_line_vals(self):
|
||||
return [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"account_id": self.loan_id.short_term_loan_account_id.id,
|
||||
"credit": self.long_term_principal_amount,
|
||||
"debit": 0,
|
||||
"exclude_from_invoice_tab": True,
|
||||
},
|
||||
),
|
||||
(
|
||||
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):
|
||||
"""Shows the invoice if it is a leasing or the move if it is a loan"""
|
||||
self.ensure_one()
|
||||
@@ -371,7 +394,6 @@ class AccountLoanLine(models.Model):
|
||||
return self.view_account_invoices()
|
||||
return self.view_account_moves()
|
||||
|
||||
@api.multi
|
||||
def view_process_values(self):
|
||||
"""Computes the annuity and returns the result"""
|
||||
self.ensure_one()
|
||||
@@ -381,7 +403,6 @@ class AccountLoanLine(models.Model):
|
||||
self.generate_move()
|
||||
return self.view_account_values()
|
||||
|
||||
@api.multi
|
||||
def view_account_moves(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref("account.action_move_line_form")
|
||||
@@ -397,18 +418,17 @@ class AccountLoanLine(models.Model):
|
||||
result["res_id"] = self.move_ids.id
|
||||
return result
|
||||
|
||||
@api.multi
|
||||
def view_account_invoices(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref("account.action_invoice_tree2")
|
||||
action = self.env.ref("account.action_move_out_invoice_type")
|
||||
result = action.read()[0]
|
||||
result["context"] = {
|
||||
"default_loan_line_id": self.id,
|
||||
"default_loan_id": self.loan_id.id,
|
||||
}
|
||||
result["domain"] = [("loan_line_id", "=", self.id), ("type", "=", "in_invoice")]
|
||||
if len(self.invoice_ids) == 1:
|
||||
res = self.env.ref("account.invoice.supplier.form", False)
|
||||
if len(self.move_ids) == 1:
|
||||
res = self.env.ref("account.view_move_form", False)
|
||||
result["views"] = [(res and res.id or False, "form")]
|
||||
result["res_id"] = self.invoice_ids.id
|
||||
result["res_id"] = self.move_ids.id
|
||||
return result
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Copyright 2018 Creu Blanca
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class AccountMove(models.Model):
|
||||
@@ -14,11 +14,10 @@ class AccountMove(models.Model):
|
||||
"account.loan", readonly=True, store=True, ondelete="restrict",
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def post(self, invoice=False):
|
||||
res = super().post(invoice=invoice)
|
||||
def post(self):
|
||||
res = super().post()
|
||||
for record in self:
|
||||
loan_line_id = record.loan_line_id or (invoice and invoice.loan_line_id)
|
||||
loan_line_id = record.loan_line_id
|
||||
if loan_line_id:
|
||||
if not record.loan_line_id:
|
||||
record.loan_line_id = loan_line_id
|
||||
|
||||
@@ -367,7 +367,7 @@ ul.auto-toc {
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||
<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/12.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-12-0/account-financial-tools-12-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://runbot.odoo-community.org/runbot/92/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-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/13.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-13-0/account-financial-tools-13-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://runbot.odoo-community.org/runbot/92/13.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
|
||||
<p>This module extends the functionality of accounting to support 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>
|
||||
@@ -420,7 +420,7 @@ leases before a selected date</li>
|
||||
<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.
|
||||
If you spotted it first, help us smashing 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:%2012.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:%2013.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>
|
||||
</div>
|
||||
<div class="section" id="credits">
|
||||
@@ -446,7 +446,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
|
||||
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
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/12.0/account_loan">OCA/account-financial-tools</a> project on GitHub.</p>
|
||||
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/13.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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,15 +7,16 @@ from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import fields
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests import TransactionCase
|
||||
from odoo.tests import TransactionCase, tagged
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
try:
|
||||
import numpy
|
||||
import numpy_financial
|
||||
except (ImportError, IOError) as err:
|
||||
_logger.error(err)
|
||||
|
||||
|
||||
@tagged("post_install", "-at_install")
|
||||
class TestLoan(TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -108,7 +109,7 @@ class TestLoan(TransactionCase):
|
||||
self.assertEqual(len(loan.line_ids), periods)
|
||||
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||
self.assertAlmostEqual(
|
||||
-numpy.pmt(1 / 100 / 12, 24, 10000), line.payment_amount, 2
|
||||
-numpy_financial.pmt(1 / 100 / 12, 24, 10000), line.payment_amount, 2
|
||||
)
|
||||
self.assertEqual(line.long_term_principal_amount, 0)
|
||||
loan.long_term_loan_account_id = self.lt_loan_account
|
||||
@@ -120,14 +121,14 @@ class TestLoan(TransactionCase):
|
||||
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||
self.assertTrue(line)
|
||||
self.assertFalse(line.move_ids)
|
||||
self.assertFalse(line.invoice_ids)
|
||||
wzd = self.env["account.loan.generate.wizard"].create({})
|
||||
action = wzd.run()
|
||||
self.assertTrue(action)
|
||||
self.assertFalse(wzd.run())
|
||||
self.assertTrue(line.move_ids)
|
||||
self.assertIn(line.move_ids.id, action["domain"][0][2])
|
||||
line.move_ids.post()
|
||||
self.assertTrue(line.move_ids)
|
||||
self.assertEqual(line.move_ids.state, "posted")
|
||||
with self.assertRaises(UserError):
|
||||
self.env["account.loan.pay.amount"].create(
|
||||
{
|
||||
@@ -139,15 +140,15 @@ class TestLoan(TransactionCase):
|
||||
).run()
|
||||
with self.assertRaises(UserError):
|
||||
self.env["account.loan.pay.amount"].create(
|
||||
{"loan_id": loan.id, "amount": amount, "fees": 100, "date": line.date,}
|
||||
{"loan_id": loan.id, "amount": amount, "fees": 100, "date": line.date}
|
||||
).run()
|
||||
with self.assertRaises(UserError):
|
||||
self.env["account.loan.pay.amount"].create(
|
||||
{"loan_id": loan.id, "amount": 0, "fees": 100, "date": line.date,}
|
||||
{"loan_id": loan.id, "amount": 0, "fees": 100, "date": line.date}
|
||||
).run()
|
||||
with self.assertRaises(UserError):
|
||||
self.env["account.loan.pay.amount"].create(
|
||||
{"loan_id": loan.id, "amount": -100, "fees": 100, "date": line.date,}
|
||||
{"loan_id": loan.id, "amount": -100, "fees": 100, "date": line.date}
|
||||
).run()
|
||||
|
||||
def test_fixed_annuity_begin_loan(self):
|
||||
@@ -158,7 +159,9 @@ class TestLoan(TransactionCase):
|
||||
self.assertEqual(len(loan.line_ids), periods)
|
||||
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||
self.assertAlmostEqual(
|
||||
-numpy.pmt(1 / 100 / 12, 24, 10000, when="begin"), line.payment_amount, 2
|
||||
-numpy_financial.pmt(1 / 100 / 12, 24, 10000, when="begin"),
|
||||
line.payment_amount,
|
||||
2,
|
||||
)
|
||||
self.assertEqual(line.long_term_principal_amount, 0)
|
||||
loan.long_term_loan_account_id = self.lt_loan_account
|
||||
@@ -170,25 +173,25 @@ class TestLoan(TransactionCase):
|
||||
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||
self.assertTrue(line)
|
||||
self.assertFalse(line.move_ids)
|
||||
self.assertFalse(line.invoice_ids)
|
||||
wzd = self.env["account.loan.generate.wizard"].create({})
|
||||
action = wzd.run()
|
||||
self.assertTrue(action)
|
||||
self.assertFalse(wzd.run())
|
||||
self.assertTrue(line.move_ids)
|
||||
self.assertIn(line.move_ids.id, action["domain"][0][2])
|
||||
line.move_ids.post()
|
||||
self.assertTrue(line.move_ids)
|
||||
self.assertEqual(line.move_ids.state, "posted")
|
||||
loan.rate = 2
|
||||
loan.compute_lines()
|
||||
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||
self.assertAlmostEqual(
|
||||
-numpy.pmt(1 / 100 / 12, periods, amount, when="begin"),
|
||||
-numpy_financial.pmt(1 / 100 / 12, periods, amount, when="begin"),
|
||||
line.payment_amount,
|
||||
2,
|
||||
)
|
||||
line = loan.line_ids.filtered(lambda r: r.sequence == 2)
|
||||
self.assertAlmostEqual(
|
||||
-numpy.pmt(
|
||||
-numpy_financial.pmt(
|
||||
2 / 100 / 12, periods - 1, line.pending_principal_amount, when="begin"
|
||||
),
|
||||
line.payment_amount,
|
||||
@@ -206,7 +209,7 @@ class TestLoan(TransactionCase):
|
||||
self.assertEqual(len(loan.line_ids), periods)
|
||||
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||
self.assertAlmostEqual(
|
||||
-numpy.pmt(1 / 100 / 12, 24, 10000), line.payment_amount, 2
|
||||
-numpy_financial.pmt(1 / 100 / 12, 24, 10000), line.payment_amount, 2
|
||||
)
|
||||
self.assertEqual(line.long_term_principal_amount, 0)
|
||||
loan.long_term_loan_account_id = self.lt_loan_account
|
||||
@@ -218,23 +221,25 @@ class TestLoan(TransactionCase):
|
||||
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||
self.assertTrue(line)
|
||||
self.assertFalse(line.move_ids)
|
||||
self.assertFalse(line.invoice_ids)
|
||||
wzd = self.env["account.loan.generate.wizard"].create({})
|
||||
action = wzd.run()
|
||||
self.assertTrue(action)
|
||||
self.assertFalse(wzd.run())
|
||||
self.assertTrue(line.move_ids)
|
||||
self.assertIn(line.move_ids.id, action["domain"][0][2])
|
||||
line.move_ids.post()
|
||||
self.assertTrue(line.move_ids)
|
||||
self.assertEqual(line.move_ids.state, "posted")
|
||||
loan.rate = 2
|
||||
loan.compute_lines()
|
||||
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||
self.assertAlmostEqual(
|
||||
-numpy.pmt(1 / 100 / 12, periods, amount), line.payment_amount, 2
|
||||
-numpy_financial.pmt(1 / 100 / 12, periods, amount), line.payment_amount, 2
|
||||
)
|
||||
line = loan.line_ids.filtered(lambda r: r.sequence == 2)
|
||||
self.assertAlmostEqual(
|
||||
-numpy.pmt(2 / 100 / 12, periods - 1, line.pending_principal_amount),
|
||||
-numpy_financial.pmt(
|
||||
2 / 100 / 12, periods - 1, line.pending_principal_amount
|
||||
),
|
||||
line.payment_amount,
|
||||
2,
|
||||
)
|
||||
@@ -242,7 +247,7 @@ class TestLoan(TransactionCase):
|
||||
with self.assertRaises(UserError):
|
||||
line.view_process_values()
|
||||
|
||||
def test_fixed_principal_loan(self):
|
||||
def test_fixed_principal_loan_leasing(self):
|
||||
amount = 24000
|
||||
periods = 24
|
||||
loan = self.create_loan("fixed-principal", amount, 1, periods)
|
||||
@@ -266,12 +271,18 @@ class TestLoan(TransactionCase):
|
||||
self.assertFalse(line.has_moves)
|
||||
action = (
|
||||
self.env["account.loan.generate.wizard"]
|
||||
.create({"date": fields.date.today(), "loan_type": "leasing",})
|
||||
.create(
|
||||
{
|
||||
"date": fields.date.today() + relativedelta(days=1),
|
||||
"loan_type": "leasing",
|
||||
}
|
||||
)
|
||||
.run()
|
||||
)
|
||||
self.assertTrue(line.has_invoices)
|
||||
self.assertFalse(line.has_moves)
|
||||
self.assertIn(line.invoice_ids.id, action["domain"][0][2])
|
||||
self.assertTrue(line.has_moves)
|
||||
self.assertIn(line.move_ids.id, action["domain"][0][2])
|
||||
loan.refresh()
|
||||
with self.assertRaises(UserError):
|
||||
self.env["account.loan.pay.amount"].create(
|
||||
{
|
||||
@@ -291,17 +302,18 @@ class TestLoan(TransactionCase):
|
||||
+ relativedelta(months=-1),
|
||||
}
|
||||
).run()
|
||||
line.invoice_ids.action_invoice_open()
|
||||
self.assertTrue(line.move_ids)
|
||||
self.assertEqual(line.move_ids.state, "draft")
|
||||
self.assertTrue(line.has_moves)
|
||||
line.move_ids.post()
|
||||
self.assertEqual(line.move_ids.state, "posted")
|
||||
self.assertIn(
|
||||
line.move_ids.id,
|
||||
self.env["account.move"].search(loan.view_account_moves()["domain"]).ids,
|
||||
)
|
||||
self.assertEqual(
|
||||
line.invoice_ids.id,
|
||||
self.env["account.invoice"]
|
||||
.search(loan.view_account_invoices()["domain"])
|
||||
.id,
|
||||
line.move_ids.id,
|
||||
self.env["account.move"].search(loan.view_account_invoices()["domain"]).id,
|
||||
)
|
||||
with self.assertRaises(UserError):
|
||||
self.env["account.loan.pay.amount"].create(
|
||||
@@ -333,7 +345,7 @@ class TestLoan(TransactionCase):
|
||||
with self.assertRaises(UserError):
|
||||
line.view_process_values()
|
||||
|
||||
def test_fixed_principal_loan_auto_post(self):
|
||||
def test_fixed_principal_loan_auto_post_leasing(self):
|
||||
amount = 24000
|
||||
periods = 24
|
||||
loan = self.create_loan("fixed-principal", amount, 1, periods)
|
||||
@@ -355,7 +367,7 @@ class TestLoan(TransactionCase):
|
||||
self.assertFalse(line.has_invoices)
|
||||
self.assertFalse(line.has_moves)
|
||||
self.env["account.loan.generate.wizard"].create(
|
||||
{"date": fields.date.today(), "loan_type": "leasing",}
|
||||
{"date": fields.date.today(), "loan_type": "leasing"}
|
||||
).run()
|
||||
self.assertTrue(line.has_invoices)
|
||||
self.assertTrue(line.has_moves)
|
||||
@@ -383,9 +395,10 @@ class TestLoan(TransactionCase):
|
||||
for line in loan.line_ids:
|
||||
self.assertEqual(loan.state, "posted")
|
||||
line.view_process_values()
|
||||
line.move_ids.post()
|
||||
self.assertTrue(line.move_ids)
|
||||
self.assertEqual(line.move_ids.state, "posted")
|
||||
self.assertEqual(loan.state, "closed")
|
||||
|
||||
loan.refresh()
|
||||
self.assertEqual(loan.payment_amount - loan.interests_amount, amount)
|
||||
self.assertEqual(loan.pending_principal_amount, 0)
|
||||
|
||||
@@ -396,7 +409,8 @@ class TestLoan(TransactionCase):
|
||||
self.post(loan)
|
||||
line = loan.line_ids.filtered(lambda r: r.sequence == 1)
|
||||
line.view_process_values()
|
||||
line.move_ids.post()
|
||||
self.assertTrue(line.move_ids)
|
||||
self.assertEqual(line.move_ids.state, "posted")
|
||||
pay = self.env["account.loan.pay.amount"].create(
|
||||
{"loan_id": loan.id, "amount": 0, "fees": 100, "date": line.date}
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class AccountLoanGenerateWizard(models.TransientModel):
|
||||
@@ -15,12 +15,12 @@ class AccountLoanGenerateWizard(models.TransientModel):
|
||||
default=fields.Date.context_today,
|
||||
)
|
||||
loan_type = fields.Selection(
|
||||
[("leasing", "Leasings"), ("loan", "Loans"),], required=True, default="loan"
|
||||
[("leasing", "Leasings"), ("loan", "Loans")], required=True, default="loan"
|
||||
)
|
||||
|
||||
def run_leasing(self):
|
||||
created_ids = self.env["account.loan"].generate_leasing_entries(self.date)
|
||||
action = self.env.ref("account.action_invoice_tree2")
|
||||
action = self.env.ref("account.action_move_out_invoice_type")
|
||||
result = action.read()[0]
|
||||
if len(created_ids) == 0:
|
||||
return
|
||||
@@ -36,7 +36,6 @@ class AccountLoanGenerateWizard(models.TransientModel):
|
||||
result["domain"] = [("id", "in", created_ids)]
|
||||
return result
|
||||
|
||||
@api.multi
|
||||
def run(self):
|
||||
self.ensure_one()
|
||||
if self.loan_type == "leasing":
|
||||
|
||||
@@ -24,9 +24,9 @@ class AccountLoan(models.TransientModel):
|
||||
def _onchange_cancel_loan(self):
|
||||
if self.cancel_loan:
|
||||
self.amount = max(
|
||||
self.loan_id.line_ids.filtered(
|
||||
lambda r: not r.move_ids and not r.invoice_ids
|
||||
).mapped("pending_principal_amount")
|
||||
self.loan_id.line_ids.filtered(lambda r: not r.move_ids).mapped(
|
||||
"pending_principal_amount"
|
||||
)
|
||||
)
|
||||
|
||||
def new_line_vals(self, sequence):
|
||||
@@ -39,16 +39,15 @@ class AccountLoan(models.TransientModel):
|
||||
"date": self.date,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def run(self):
|
||||
self.ensure_one()
|
||||
if self.loan_id.is_leasing:
|
||||
if self.loan_id.line_ids.filtered(
|
||||
lambda r: r.date < self.date and not r.invoice_ids
|
||||
lambda r: r.date <= self.date and not r.move_ids
|
||||
):
|
||||
raise UserError(_("Some invoices are not created"))
|
||||
if self.loan_id.line_ids.filtered(
|
||||
lambda r: r.date > self.date and r.invoice_ids
|
||||
lambda r: r.date > self.date and r.move_ids
|
||||
):
|
||||
raise UserError(_("Some future invoices already exists"))
|
||||
if self.loan_id.line_ids.filtered(
|
||||
@@ -63,6 +62,7 @@ class AccountLoan(models.TransientModel):
|
||||
sequence = min(lines.mapped("sequence"))
|
||||
for line in lines:
|
||||
line.sequence += 1
|
||||
line.flush()
|
||||
old_line = lines.filtered(lambda r: r.sequence == sequence + 1)
|
||||
pending = old_line.pending_principal_amount
|
||||
if self.loan_id.currency_id.compare_amounts(self.amount, pending) == 1:
|
||||
|
||||
@@ -10,13 +10,13 @@ class AccountLoanPost(models.TransientModel):
|
||||
|
||||
@api.model
|
||||
def _default_journal_id(self):
|
||||
loan_id = self._context.get("default_loan_id")
|
||||
loan_id = self.env.context.get("default_loan_id")
|
||||
if loan_id:
|
||||
return self.env["account.loan"].browse(loan_id).journal_id.id
|
||||
|
||||
@api.model
|
||||
def _default_account_id(self):
|
||||
loan_id = self._context.get("default_loan_id")
|
||||
loan_id = self.env.context.get("default_loan_id")
|
||||
if loan_id:
|
||||
loan = self.env["account.loan"].browse(loan_id)
|
||||
if loan.is_leasing:
|
||||
@@ -28,10 +28,10 @@ class AccountLoanPost(models.TransientModel):
|
||||
|
||||
loan_id = fields.Many2one("account.loan", required=True, readonly=True,)
|
||||
journal_id = fields.Many2one(
|
||||
"account.journal", required=True, default=_default_journal_id
|
||||
"account.journal", required=True, default=lambda r: r._default_journal_id()
|
||||
)
|
||||
account_id = fields.Many2one(
|
||||
"account.account", required=True, default=_default_account_id
|
||||
"account.account", required=True, default=lambda r: r._default_account_id()
|
||||
)
|
||||
|
||||
def move_line_vals(self):
|
||||
@@ -82,7 +82,6 @@ class AccountLoanPost(models.TransientModel):
|
||||
"line_ids": [(0, 0, vals) for vals in self.move_line_vals()],
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def run(self):
|
||||
self.ensure_one()
|
||||
if self.loan_id.state != "draft":
|
||||
|
||||
Reference in New Issue
Block a user