mirror of
https://github.com/bringout/oca-financial.git
synced 2026-04-22 06:41: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,5 @@
|
|||
from . import statement_common
|
||||
from . import activity_statement_wizard
|
||||
from . import detailed_activity_statement_wizard
|
||||
from . import outstanding_statement_wizard
|
||||
from . import res_config_settings
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# Copyright 2018 ForgeFlow, S.L. (http://www.forgeflow.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class ActivityStatementWizard(models.TransientModel):
|
||||
"""Activity Statement wizard."""
|
||||
|
||||
_inherit = "statement.common.wizard"
|
||||
_name = "activity.statement.wizard"
|
||||
_description = "Activity Statement Wizard"
|
||||
|
||||
@api.model
|
||||
def _get_date_start(self):
|
||||
return (
|
||||
fields.Date.context_today(self).replace(day=1) - relativedelta(days=1)
|
||||
).replace(day=1)
|
||||
|
||||
date_start = fields.Date(required=True, default=_get_date_start)
|
||||
|
||||
@api.onchange("aging_type")
|
||||
def onchange_aging_type(self):
|
||||
res = super().onchange_aging_type()
|
||||
if self.aging_type == "months":
|
||||
self.date_start = self.date_end.replace(day=1)
|
||||
else:
|
||||
self.date_start = self.date_end - relativedelta(months=1)
|
||||
return res
|
||||
|
||||
def _prepare_statement(self):
|
||||
res = super()._prepare_statement()
|
||||
res.update(
|
||||
{
|
||||
"date_start": self.date_start,
|
||||
"is_activity": True,
|
||||
}
|
||||
)
|
||||
return res
|
||||
|
||||
def _print_report(self, report_type):
|
||||
self.ensure_one()
|
||||
data = self._prepare_statement()
|
||||
if report_type == "xlsx":
|
||||
report_name = "p_s.report_activity_statement_xlsx"
|
||||
else:
|
||||
report_name = "partner_statement.activity_statement"
|
||||
partners = self.env["res.partner"].browse(data["partner_ids"])
|
||||
return (
|
||||
self.env["ir.actions.report"]
|
||||
.search(
|
||||
[("report_name", "=", report_name), ("report_type", "=", report_type)],
|
||||
limit=1,
|
||||
)
|
||||
.report_action(partners, data=data)
|
||||
)
|
||||
|
||||
def _export(self, report_type):
|
||||
"""Default export is PDF."""
|
||||
return self._print_report(report_type)
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# Copyright 2018 ForgeFlow, S.L. (http://www.forgeflow.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class DetailedActivityStatementWizard(models.TransientModel):
|
||||
"""Detailed Activity Statement wizard."""
|
||||
|
||||
_inherit = "activity.statement.wizard"
|
||||
_name = "detailed.activity.statement.wizard"
|
||||
_description = "Detailed Activity Statement Wizard"
|
||||
|
||||
show_aging_buckets = fields.Boolean(default=False)
|
||||
show_balance = fields.Boolean(string="Show Balance column")
|
||||
|
||||
def _prepare_statement(self):
|
||||
res = super()._prepare_statement()
|
||||
res.update(
|
||||
{
|
||||
"is_detailed": True,
|
||||
}
|
||||
)
|
||||
return res
|
||||
|
||||
def _print_report(self, report_type):
|
||||
self.ensure_one()
|
||||
data = self._prepare_statement()
|
||||
if report_type == "xlsx":
|
||||
report_name = "p_s.report_detailed_activity_statement_xlsx"
|
||||
else:
|
||||
report_name = "partner_statement.detailed_activity_statement"
|
||||
partners = self.env["res.partner"].browse(data["partner_ids"])
|
||||
return (
|
||||
self.env["ir.actions.report"]
|
||||
.search(
|
||||
[("report_name", "=", report_name), ("report_type", "=", report_type)],
|
||||
limit=1,
|
||||
)
|
||||
.report_action(partners, data=data)
|
||||
)
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright 2018 ForgeFlow, S.L. (http://www.forgeflow.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class OutstandingStatementWizard(models.TransientModel):
|
||||
"""Outstanding Statement wizard."""
|
||||
|
||||
_name = "outstanding.statement.wizard"
|
||||
_inherit = "statement.common.wizard"
|
||||
_description = "Outstanding Statement Wizard"
|
||||
|
||||
def _prepare_statement(self):
|
||||
res = super()._prepare_statement()
|
||||
res.update(
|
||||
{
|
||||
"is_outstanding": True,
|
||||
}
|
||||
)
|
||||
return res
|
||||
|
||||
def _print_report(self, report_type):
|
||||
self.ensure_one()
|
||||
data = self._prepare_statement()
|
||||
if report_type == "xlsx":
|
||||
report_name = "p_s.report_outstanding_statement_xlsx"
|
||||
else:
|
||||
report_name = "partner_statement.outstanding_statement"
|
||||
partners = self.env["res.partner"].browse(data["partner_ids"])
|
||||
return (
|
||||
self.env["ir.actions.report"]
|
||||
.search(
|
||||
[("report_name", "=", report_name), ("report_type", "=", report_type)],
|
||||
limit=1,
|
||||
)
|
||||
.report_action(partners, data=data)
|
||||
)
|
||||
|
||||
def _export(self, report_type):
|
||||
"""Default export is PDF."""
|
||||
return self._print_report(report_type)
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = "res.config.settings"
|
||||
|
||||
group_activity_statement = fields.Boolean(
|
||||
"Enable OCA Activity & Detailed Activity Statements",
|
||||
group="account.group_account_invoice",
|
||||
implied_group="partner_statement.group_activity_statement",
|
||||
)
|
||||
|
||||
default_aging_type = fields.Selection(
|
||||
[("days", "Age by Days"), ("months", "Age by Months")],
|
||||
string="Aging Method",
|
||||
required=True,
|
||||
default="days",
|
||||
default_model="statement.common.wizard",
|
||||
)
|
||||
|
||||
default_show_aging_buckets = fields.Boolean(
|
||||
string="Show Aging Buckets", default_model="statement.common.wizard"
|
||||
)
|
||||
|
||||
default_filter_partners_non_due = fields.Boolean(
|
||||
string="Exclude partners with no due entries",
|
||||
default_model="statement.common.wizard",
|
||||
)
|
||||
|
||||
default_filter_negative_balances = fields.Boolean(
|
||||
"Exclude Negative Balances", default_model="statement.common.wizard"
|
||||
)
|
||||
|
||||
group_outstanding_statement = fields.Boolean(
|
||||
"Enable OCA Outstanding Statements",
|
||||
group="account.group_account_invoice",
|
||||
implied_group="partner_statement.group_outstanding_statement",
|
||||
)
|
||||
|
||||
def set_values(self):
|
||||
self = self.with_context(active_test=False)
|
||||
# default values fields
|
||||
IrDefault = self.env["ir.default"].sudo()
|
||||
for name, field in self._fields.items():
|
||||
if (
|
||||
name.startswith("default_")
|
||||
and field.default_model == "statement.common.wizard"
|
||||
):
|
||||
if isinstance(self[name], models.BaseModel):
|
||||
if self._fields[name].type == "many2one":
|
||||
value = self[name].id
|
||||
else:
|
||||
value = self[name].ids
|
||||
else:
|
||||
value = self[name]
|
||||
IrDefault.set("activity.statement.wizard", name[8:], value)
|
||||
IrDefault.set("outstanding.statement.wizard", name[8:], value)
|
||||
IrDefault.set("detailed.activity.statement.wizard", name[8:], value)
|
||||
return super().set_values()
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
# Copyright 2018 Graeme Gellatly
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.osv import expression
|
||||
|
||||
|
||||
class StatementCommon(models.AbstractModel):
|
||||
|
||||
_name = "statement.common.wizard"
|
||||
_description = "Statement Reports Common Wizard"
|
||||
|
||||
name = fields.Char()
|
||||
company_id = fields.Many2one(
|
||||
comodel_name="res.company",
|
||||
default=lambda self: self.env.company,
|
||||
string="Company",
|
||||
required=True,
|
||||
)
|
||||
date_end = fields.Date(required=True, default=fields.Date.context_today)
|
||||
show_aging_buckets = fields.Boolean(default=True)
|
||||
show_only_overdue = fields.Boolean(
|
||||
help="Show only lines due before the selected date",
|
||||
)
|
||||
number_partner_ids = fields.Integer(
|
||||
default=lambda self: len(self._context["active_ids"])
|
||||
)
|
||||
filter_partners_non_due = fields.Boolean(
|
||||
string="Don't show partners with no due entries", default=True
|
||||
)
|
||||
filter_negative_balances = fields.Boolean("Exclude Negative Balances", default=True)
|
||||
|
||||
aging_type = fields.Selection(
|
||||
[("days", "Age by Days"), ("months", "Age by Months")],
|
||||
string="Aging Method",
|
||||
default="days",
|
||||
required=True,
|
||||
)
|
||||
|
||||
account_type = fields.Selection(
|
||||
[("asset_receivable", "Receivable"), ("liability_payable", "Payable")],
|
||||
default="asset_receivable",
|
||||
)
|
||||
excluded_accounts_selector = fields.Char(
|
||||
string="Accounts to exclude",
|
||||
help="Select account codes to be excluded "
|
||||
"with a comma-separated list of expressions like 70%.",
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _get_excluded_accounts_domain(self, selector):
|
||||
"""Convert an account codes selector to a domain to search accounts.
|
||||
|
||||
The selector is a comma-separated list of expressions like 70%.
|
||||
The algorithm is the same as
|
||||
AccountingExpressionProcessor._account_codes_to_domain
|
||||
of `mis_builder` module.
|
||||
"""
|
||||
if not selector:
|
||||
selector = ""
|
||||
domains = []
|
||||
for account_code in selector.split(","):
|
||||
account_code = account_code.strip()
|
||||
if "%" in account_code:
|
||||
domains.append(
|
||||
[
|
||||
("code", "=like", account_code),
|
||||
]
|
||||
)
|
||||
else:
|
||||
domains.append(
|
||||
[
|
||||
("code", "=", account_code),
|
||||
]
|
||||
)
|
||||
return expression.OR(domains)
|
||||
|
||||
def _get_excluded_accounts(self):
|
||||
self.ensure_one()
|
||||
domain = self._get_excluded_accounts_domain(self.excluded_accounts_selector)
|
||||
return self.env["account.account"].search(domain)
|
||||
|
||||
@api.onchange("aging_type")
|
||||
def onchange_aging_type(self):
|
||||
if self.aging_type == "months":
|
||||
self.date_end = fields.Date.context_today(self).replace(
|
||||
day=1
|
||||
) - relativedelta(days=1)
|
||||
else:
|
||||
self.date_end = fields.Date.context_today(self)
|
||||
|
||||
def _prepare_statement(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
"date_end": self.date_end,
|
||||
"company_id": self.company_id.id,
|
||||
"partner_ids": self._context["active_ids"],
|
||||
"show_aging_buckets": self.show_aging_buckets,
|
||||
"show_only_overdue": self.show_only_overdue,
|
||||
"filter_non_due_partners": self.filter_partners_non_due,
|
||||
"account_type": self.account_type,
|
||||
"aging_type": self.aging_type,
|
||||
"filter_negative_balances": self.filter_negative_balances,
|
||||
"excluded_accounts_ids": self._get_excluded_accounts().ids,
|
||||
}
|
||||
|
||||
def button_export_html(self):
|
||||
self.ensure_one()
|
||||
report_type = "qweb-html"
|
||||
return self._export(report_type)
|
||||
|
||||
def button_export_pdf(self):
|
||||
self.ensure_one()
|
||||
report_type = "qweb-pdf"
|
||||
return self._export(report_type)
|
||||
|
||||
def button_export_xlsx(self):
|
||||
self.ensure_one()
|
||||
report_type = "xlsx"
|
||||
return self._export(report_type)
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2018 ForgeFlow, S.L. (https://www.forgeflow.com)
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
<odoo>
|
||||
<!-- wizard action on res.partner -->
|
||||
<record id="activity_statement_wizard_action" model="ir.actions.act_window">
|
||||
<field name="name">Partner Activity Statement</field>
|
||||
<field name="binding_model_id" ref="base.model_res_partner" />
|
||||
<field name="res_model">activity.statement.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field
|
||||
name="groups_id"
|
||||
eval="[(4, ref('partner_statement.group_activity_statement'))]"
|
||||
/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
<record id="outstanding_statement_wizard_action" model="ir.actions.act_window">
|
||||
<field name="name">Partner Outstanding Statement</field>
|
||||
<field name="binding_model_id" ref="base.model_res_partner" />
|
||||
<field name="res_model">outstanding.statement.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field
|
||||
name="groups_id"
|
||||
eval="[(4, ref('partner_statement.group_outstanding_statement'))]"
|
||||
/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
<record
|
||||
id="detailed_activity_statement_wizard_action"
|
||||
model="ir.actions.act_window"
|
||||
>
|
||||
<field name="name">Partner Detailed Activity Statement</field>
|
||||
<field name="binding_model_id" ref="base.model_res_partner" />
|
||||
<field name="res_model">detailed.activity.statement.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field
|
||||
name="groups_id"
|
||||
eval="[(4, ref('partner_statement.group_activity_statement'))]"
|
||||
/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
<!-- wizard view -->
|
||||
<record id="statement_common_view" model="ir.ui.view">
|
||||
<field name="name">Statement Common Wizard View</field>
|
||||
<field name="model">statement.common.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form name="Report Options">
|
||||
<div style="text-align:justify" name="info">
|
||||
<span
|
||||
class="o_form_label"
|
||||
>Aging details can be shown in the report, expressed in aging
|
||||
buckets, so the partner can review how much is open, due or overdue.
|
||||
</span>
|
||||
</div>
|
||||
<hr />
|
||||
<group>
|
||||
<group name="main_info">
|
||||
<field
|
||||
name="company_id"
|
||||
options="{'no_create': True}"
|
||||
groups="base.group_multi_company"
|
||||
/>
|
||||
<label for="account_type" />
|
||||
<field name="account_type" nolabel="1" widget="radio" />
|
||||
<field name="excluded_accounts_selector" />
|
||||
</group>
|
||||
<group name="aging_report">
|
||||
<field name="show_only_overdue" />
|
||||
<field name="show_aging_buckets" />
|
||||
<field name="aging_type" />
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<group name="dates">
|
||||
<field name="date_end" />
|
||||
</group>
|
||||
<group name="multiple_partners">
|
||||
<field name="number_partner_ids" readonly="1" invisible="1" />
|
||||
<field
|
||||
name="filter_partners_non_due"
|
||||
attrs="{'invisible': [('number_partner_ids', '=', 1)]}"
|
||||
/>
|
||||
<field
|
||||
name="filter_negative_balances"
|
||||
attrs="{'invisible': [('number_partner_ids', '=', 1)]}"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button
|
||||
name="button_export_html"
|
||||
string="View"
|
||||
type="object"
|
||||
default_focus="1"
|
||||
class="oe_highlight"
|
||||
/>
|
||||
or
|
||||
<button
|
||||
name="button_export_pdf"
|
||||
string="Export PDF"
|
||||
type="object"
|
||||
/>
|
||||
or
|
||||
<button
|
||||
name="button_export_xlsx"
|
||||
string="Export XLSX"
|
||||
type="object"
|
||||
/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="outstanding_statement_wizard_view" model="ir.ui.view">
|
||||
<field name="name">Outstanding Statement Wizard</field>
|
||||
<field name="model">outstanding.statement.wizard</field>
|
||||
<field name="inherit_id" ref="partner_statement.statement_common_view" />
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='info']/span" position="before">
|
||||
<span
|
||||
class="o_form_label"
|
||||
>The outstanding statement provides details of all partner's outstanding
|
||||
receivables and payables up to a particular date. This includes all unpaid invoices, unclaimed
|
||||
refunds and outstanding payments. The list is displayed in chronological order and is
|
||||
split by currencies.
|
||||
</span>
|
||||
<br />
|
||||
<br />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="activity_statement_wizard_view" model="ir.ui.view">
|
||||
<field name="name">Activity Statement Wizard</field>
|
||||
<field name="model">activity.statement.wizard</field>
|
||||
<field name="inherit_id" ref="partner_statement.statement_common_view" />
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='info']/span" position="before">
|
||||
<span
|
||||
class="o_form_label"
|
||||
>The activity statement provides details of all activity on
|
||||
a partner's receivables and payables between two selected dates. This includes all invoices,
|
||||
refunds and payments. Any outstanding balance dated prior to the chosen statement
|
||||
period will appear as a forward balance at the top of the statement. The list is
|
||||
displayed in chronological order and is split by currencies.
|
||||
</span>
|
||||
<br />
|
||||
<br />
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='date_end']" position="before">
|
||||
<field name="date_start" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="detailed_activity_statement_wizard_view" model="ir.ui.view">
|
||||
<field name="name">Detailed Activity Statement Wizard</field>
|
||||
<field name="model">detailed.activity.statement.wizard</field>
|
||||
<field name="inherit_id" ref="partner_statement.statement_common_view" />
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='info']/span" position="before">
|
||||
<span
|
||||
class="o_form_label"
|
||||
>The detailed activity statement is an extension of the activity statement, and intends to explain the transactions
|
||||
that have happened during the period, also providing with a Prior Balance section and an Ending Balance section.
|
||||
</span>
|
||||
<br />
|
||||
<br />
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='date_end']" position="before">
|
||||
<field name="date_start" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue