mirror of
https://github.com/bringout/oca-financial.git
synced 2026-04-26 09:21:59 +02:00
Initial commit: OCA Financial packages (186 packages)
This commit is contained in:
commit
3e0e8473fb
8757 changed files with 947473 additions and 0 deletions
|
|
@ -0,0 +1,6 @@
|
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import account_loan_generate_entries
|
||||
from . import account_loan_pay_amount
|
||||
from . import account_loan_post
|
||||
from . import account_loan_increase_amount
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class AccountLoanGenerateWizard(models.TransientModel):
|
||||
_name = "account.loan.generate.wizard"
|
||||
_description = "Loan generate wizard"
|
||||
|
||||
date = fields.Date(
|
||||
"Account Date",
|
||||
required=True,
|
||||
help="Choose the period for which you want to automatically post the "
|
||||
"depreciation lines of running assets",
|
||||
default=fields.Date.context_today,
|
||||
)
|
||||
loan_type = fields.Selection(
|
||||
[("leasing", "Leasings"), ("loan", "Loans")], required=True, default="loan"
|
||||
)
|
||||
|
||||
def _run_leasing(self):
|
||||
created_ids = self.env["account.loan"]._generate_leasing_entries(self.date)
|
||||
result = self.env["ir.actions.act_window"]._for_xml_id(
|
||||
"account.action_move_out_invoice_type"
|
||||
)
|
||||
if len(created_ids) == 0:
|
||||
return
|
||||
result["domain"] = [("id", "in", created_ids)]
|
||||
return result
|
||||
|
||||
def _run_loan(self):
|
||||
created_ids = self.env["account.loan"]._generate_loan_entries(self.date)
|
||||
result = self.env["ir.actions.act_window"]._for_xml_id(
|
||||
"account.action_move_line_form"
|
||||
)
|
||||
if len(created_ids) == 0:
|
||||
return
|
||||
result["domain"] = [("id", "in", created_ids)]
|
||||
return result
|
||||
|
||||
def run(self):
|
||||
self.ensure_one()
|
||||
if self.loan_type == "leasing":
|
||||
return self._run_leasing()
|
||||
return self._run_loan()
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2011 Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
Copyright 2016 Antonio Espinosa <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
<record id="account_loan_generate_wizard_form" model="ir.ui.view">
|
||||
<field name="name">Pay amount</field>
|
||||
<field name="model">account.loan.generate.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Generate moves">
|
||||
<group>
|
||||
<field name="date" />
|
||||
<field name="loan_type" />
|
||||
</group>
|
||||
<footer>
|
||||
<button
|
||||
name="run"
|
||||
string="Run"
|
||||
type="object"
|
||||
class="oe_highlight"
|
||||
/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="account_loan_generate_wizard_action" model="ir.actions.act_window">
|
||||
<field name="name">Generate moves</field>
|
||||
<field name="res_model">account.loan.generate.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Generate Loan Entries"
|
||||
action="account_loan_generate_wizard_action"
|
||||
id="account_loan_generate_wizard_menu"
|
||||
parent="account.menu_finance_entries_generate_entries"
|
||||
sequence="111"
|
||||
groups="account.group_account_manager"
|
||||
/>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
# Copyright 2023 Dixmit
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountLoanIncreaseAmount(models.TransientModel):
|
||||
_name = "account.loan.increase.amount"
|
||||
_description = "Increase the debt of a loan"
|
||||
|
||||
@api.model
|
||||
def _default_journal_id(self):
|
||||
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.env.context.get("default_loan_id")
|
||||
if loan_id:
|
||||
loan = self.env["account.loan"].browse(loan_id)
|
||||
if loan.is_leasing:
|
||||
return loan.leased_asset_account_id.id
|
||||
else:
|
||||
return loan.partner_id.with_company(
|
||||
loan.company_id
|
||||
).property_account_receivable_id.id
|
||||
|
||||
journal_id = fields.Many2one(
|
||||
"account.journal", required=True, default=lambda r: r._default_journal_id()
|
||||
)
|
||||
account_id = fields.Many2one(
|
||||
"account.account", required=True, default=lambda r: r._default_account_id()
|
||||
)
|
||||
loan_id = fields.Many2one(
|
||||
"account.loan",
|
||||
required=True,
|
||||
readonly=True,
|
||||
)
|
||||
currency_id = fields.Many2one(
|
||||
"res.currency", related="loan_id.currency_id", readonly=True
|
||||
)
|
||||
date = fields.Date(required=True, default=fields.Date.today())
|
||||
amount = fields.Monetary(
|
||||
currency_field="currency_id",
|
||||
string="Amount to reduce from Principal",
|
||||
)
|
||||
|
||||
def new_line_vals(self, sequence):
|
||||
return {
|
||||
"loan_id": self.loan_id.id,
|
||||
"sequence": sequence,
|
||||
"payment_amount": -self.amount,
|
||||
"rate": 0,
|
||||
"interests_amount": 0,
|
||||
"date": self.date,
|
||||
}
|
||||
|
||||
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.move_ids
|
||||
):
|
||||
raise UserError(_("Some invoices are not created"))
|
||||
if self.loan_id.line_ids.filtered(
|
||||
lambda r: r.date > self.date and r.move_ids
|
||||
):
|
||||
raise UserError(_("Some future invoices already exists"))
|
||||
else:
|
||||
if self.loan_id.line_ids.filtered(
|
||||
lambda r: r.date < self.date and not r.move_ids
|
||||
):
|
||||
raise UserError(_("Some moves are not created"))
|
||||
if self.loan_id.line_ids.filtered(
|
||||
lambda r: r.date > self.date and r.move_ids
|
||||
):
|
||||
raise UserError(_("Some future moves already exists"))
|
||||
lines = self.loan_id.line_ids.filtered(lambda r: r.date > self.date).sorted(
|
||||
"sequence", reverse=True
|
||||
)
|
||||
sequence = min(lines.mapped("sequence"))
|
||||
for line in lines:
|
||||
line.sequence += 1
|
||||
line.flush_recordset()
|
||||
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, 0) <= 0:
|
||||
raise UserError(_("Amount cannot be less than zero"))
|
||||
self.loan_id.periods += 1
|
||||
self.loan_id.fixed_periods = self.loan_id.periods - sequence
|
||||
self.loan_id.fixed_loan_amount = pending - self.amount
|
||||
new_line = self.env["account.loan.line"].create(self.new_line_vals(sequence))
|
||||
new_line.long_term_pending_principal_amount = (
|
||||
old_line.long_term_pending_principal_amount
|
||||
)
|
||||
amount = self.loan_id.loan_amount
|
||||
for line in self.loan_id.line_ids.sorted("sequence"):
|
||||
if line.move_ids:
|
||||
amount = line.final_pending_principal_amount
|
||||
else:
|
||||
line.pending_principal_amount = amount
|
||||
if line.sequence != sequence:
|
||||
line.rate = self.loan_id.rate_period
|
||||
line._check_amount()
|
||||
amount -= line.payment_amount - line.interests_amount
|
||||
if self.loan_id.long_term_loan_account_id:
|
||||
self.loan_id._check_long_term_principal_amount()
|
||||
if self.loan_id.currency_id.compare_amounts(pending, self.amount) == 0:
|
||||
self.loan_id.write({"state": "cancelled"})
|
||||
new_line._generate_move(journal=self.journal_id, account=self.account_id)
|
||||
return new_line.view_account_values()
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2023 Dixmit
|
||||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="account_loan_increase_amount_form_view">
|
||||
<field name="name">account.loan.increase.amount.form (in account_loan)</field>
|
||||
<field name="model">account.loan.increase.amount</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group>
|
||||
<field name="loan_id" readonly="True" />
|
||||
<field name="date" />
|
||||
<field name="amount" />
|
||||
<field name="currency_id" />
|
||||
</group>
|
||||
<footer>
|
||||
<button
|
||||
name="run"
|
||||
string="Run"
|
||||
type="object"
|
||||
class="oe_highlight"
|
||||
/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="account_loan_increase_amount_act_window">
|
||||
<field name="name">Increase Amount</field>
|
||||
<field name="res_model">account.loan.increase.amount</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="context">{'default_loan_id': active_id}</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
# 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.exceptions import UserError
|
||||
|
||||
|
||||
class AccountLoan(models.TransientModel):
|
||||
_name = "account.loan.pay.amount"
|
||||
_description = "Loan pay amount"
|
||||
|
||||
loan_id = fields.Many2one(
|
||||
"account.loan",
|
||||
required=True,
|
||||
readonly=True,
|
||||
)
|
||||
currency_id = fields.Many2one(
|
||||
"res.currency", related="loan_id.currency_id", readonly=True
|
||||
)
|
||||
cancel_loan = fields.Boolean(
|
||||
default=False,
|
||||
)
|
||||
date = fields.Date(required=True, default=fields.Date.today())
|
||||
amount = fields.Monetary(
|
||||
currency_field="currency_id",
|
||||
string="Amount to reduce from Principal",
|
||||
)
|
||||
fees = fields.Monetary(currency_field="currency_id", string="Bank fees")
|
||||
|
||||
@api.onchange("cancel_loan")
|
||||
def _onchange_cancel_loan(self):
|
||||
if self.cancel_loan:
|
||||
self.amount = max(
|
||||
self.loan_id.line_ids.filtered(lambda r: not r.move_ids).mapped(
|
||||
"pending_principal_amount"
|
||||
)
|
||||
)
|
||||
|
||||
def new_line_vals(self, sequence):
|
||||
return {
|
||||
"loan_id": self.loan_id.id,
|
||||
"sequence": sequence,
|
||||
"payment_amount": self.amount + self.fees,
|
||||
"rate": 0,
|
||||
"interests_amount": self.fees,
|
||||
"date": self.date,
|
||||
}
|
||||
|
||||
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.move_ids
|
||||
):
|
||||
raise UserError(_("Some invoices are not created"))
|
||||
if self.loan_id.line_ids.filtered(
|
||||
lambda r: r.date > self.date and r.move_ids
|
||||
):
|
||||
raise UserError(_("Some future invoices already exists"))
|
||||
else:
|
||||
if self.loan_id.line_ids.filtered(
|
||||
lambda r: r.date < self.date and not r.move_ids
|
||||
):
|
||||
raise UserError(_("Some moves are not created"))
|
||||
if self.loan_id.line_ids.filtered(
|
||||
lambda r: r.date > self.date and r.move_ids
|
||||
):
|
||||
raise UserError(_("Some future moves already exists"))
|
||||
lines = self.loan_id.line_ids.filtered(lambda r: r.date > self.date).sorted(
|
||||
"sequence", reverse=True
|
||||
)
|
||||
sequence = min(lines.mapped("sequence"))
|
||||
for line in lines:
|
||||
line.sequence += 1
|
||||
line.flush_recordset()
|
||||
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:
|
||||
raise UserError(_("Amount cannot be bigger than debt"))
|
||||
if self.loan_id.currency_id.compare_amounts(self.amount, 0) <= 0:
|
||||
raise UserError(_("Amount cannot be less than zero"))
|
||||
self.loan_id.periods += 1
|
||||
self.loan_id.fixed_periods = self.loan_id.periods - sequence
|
||||
self.loan_id.fixed_loan_amount = pending - self.amount
|
||||
new_line = self.env["account.loan.line"].create(self.new_line_vals(sequence))
|
||||
new_line.long_term_pending_principal_amount = (
|
||||
old_line.long_term_pending_principal_amount
|
||||
)
|
||||
amount = self.loan_id.loan_amount
|
||||
for line in self.loan_id.line_ids.sorted("sequence"):
|
||||
if line.move_ids:
|
||||
amount = line.final_pending_principal_amount
|
||||
else:
|
||||
line.pending_principal_amount = amount
|
||||
if line.sequence != sequence:
|
||||
line.rate = self.loan_id.rate_period
|
||||
line._check_amount()
|
||||
amount -= line.payment_amount - line.interests_amount
|
||||
if self.loan_id.long_term_loan_account_id:
|
||||
self.loan_id._check_long_term_principal_amount()
|
||||
if self.loan_id.currency_id.compare_amounts(pending, self.amount) == 0:
|
||||
self.loan_id.write({"state": "cancelled"})
|
||||
return new_line.view_process_values()
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2011 Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
Copyright 2016 Antonio Espinosa <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
<record id="account_loan_pay_amount_form" model="ir.ui.view">
|
||||
<field name="name">Pay amount</field>
|
||||
<field name="model">account.loan.pay.amount</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Pay amount">
|
||||
<group>
|
||||
<field name="loan_id" readonly="True" />
|
||||
<field name="date" />
|
||||
<field name="cancel_loan" />
|
||||
<field name="amount" />
|
||||
<field name="fees" />
|
||||
<field name="currency_id" />
|
||||
</group>
|
||||
<footer>
|
||||
<button
|
||||
name="run"
|
||||
string="Run"
|
||||
type="object"
|
||||
class="oe_highlight"
|
||||
/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="account_loan_pay_amount_action" model="ir.actions.act_window">
|
||||
<field name="name">Pay amount</field>
|
||||
<field name="res_model">account.loan.pay.amount</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'default_loan_id': active_id}</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import Command, _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountLoanPost(models.TransientModel):
|
||||
_name = "account.loan.post"
|
||||
_description = "Loan post"
|
||||
|
||||
@api.model
|
||||
def _default_journal_id(self):
|
||||
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.env.context.get("default_loan_id")
|
||||
if loan_id:
|
||||
loan = self.env["account.loan"].browse(loan_id)
|
||||
if loan.is_leasing:
|
||||
return loan.leased_asset_account_id.id
|
||||
else:
|
||||
return loan.partner_id.with_company(
|
||||
loan.company_id
|
||||
).property_account_receivable_id.id
|
||||
|
||||
loan_id = fields.Many2one(
|
||||
"account.loan",
|
||||
required=True,
|
||||
readonly=True,
|
||||
)
|
||||
journal_id = fields.Many2one(
|
||||
"account.journal", required=True, default=lambda r: r._default_journal_id()
|
||||
)
|
||||
account_id = fields.Many2one(
|
||||
"account.account", required=True, default=lambda r: r._default_account_id()
|
||||
)
|
||||
|
||||
def move_line_vals(self):
|
||||
res = list()
|
||||
partner = self.loan_id.partner_id.with_company(self.loan_id.company_id)
|
||||
line = self.loan_id.line_ids.filtered(lambda r: r.sequence == 1)
|
||||
res.append(
|
||||
{
|
||||
"account_id": self.account_id.id,
|
||||
"name": self.loan_id.name,
|
||||
"partner_id": partner.id,
|
||||
"credit": 0,
|
||||
"debit": line.pending_principal_amount,
|
||||
}
|
||||
)
|
||||
if line.pending_principal_amount - line.long_term_pending_principal_amount > 0:
|
||||
res.append(
|
||||
{
|
||||
"account_id": self.loan_id.short_term_loan_account_id.id,
|
||||
"credit": (
|
||||
line.pending_principal_amount
|
||||
- line.long_term_pending_principal_amount
|
||||
),
|
||||
"debit": 0,
|
||||
}
|
||||
)
|
||||
if (
|
||||
line.long_term_pending_principal_amount > 0
|
||||
and self.loan_id.long_term_loan_account_id
|
||||
):
|
||||
res.append(
|
||||
{
|
||||
"account_id": self.loan_id.long_term_loan_account_id.id,
|
||||
"credit": line.long_term_pending_principal_amount,
|
||||
"debit": 0,
|
||||
}
|
||||
)
|
||||
|
||||
return res
|
||||
|
||||
def move_vals(self):
|
||||
return {
|
||||
"loan_id": self.loan_id.id,
|
||||
"date": self.loan_id.start_date,
|
||||
"ref": self.loan_id.name,
|
||||
"journal_id": self.journal_id.id,
|
||||
"line_ids": [Command.create(vals) for vals in self.move_line_vals()],
|
||||
}
|
||||
|
||||
def run(self):
|
||||
self.ensure_one()
|
||||
if self.loan_id.state != "draft":
|
||||
raise UserError(_("Only loans in draft state can be posted"))
|
||||
self.loan_id.post()
|
||||
move = self.env["account.move"].create(self.move_vals())
|
||||
move.action_post()
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2011 Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
Copyright 2016 Antonio Espinosa <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
<record id="account_loan_post_form" model="ir.ui.view">
|
||||
<field name="name">Post loan</field>
|
||||
<field name="model">account.loan.post</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Pay amount">
|
||||
<group>
|
||||
<field name="loan_id" readonly="True" />
|
||||
<field name="account_id" />
|
||||
<field name="journal_id" />
|
||||
</group>
|
||||
<footer>
|
||||
<button
|
||||
name="run"
|
||||
string="Run"
|
||||
type="object"
|
||||
class="oe_highlight"
|
||||
/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="account_loan_post_action" model="ir.actions.act_window">
|
||||
<field name="name">Post loan</field>
|
||||
<field name="res_model">account.loan.post</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'default_loan_id': active_id}</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue