Initial Port of customer statements

This commit is contained in:
Graeme Gellatly
2018-11-01 15:27:25 +13:00
committed by Miquel Raïch
parent 1ffec3d4ee
commit ad482b33d0
42 changed files with 4657 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
from . import statement_common
from . import activity_statement_wizard
from . import outstanding_statement_wizard
from . import res_config_settings

View File

@@ -0,0 +1,44 @@
# Copyright 2018 Eficent Business and IT Consulting Services S.L.
# (http://www.eficent.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):
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(days=30)
def _export(self):
"""Export to PDF."""
data = self._prepare_statement()
return self.env.ref(
'partner_statement'
'.action_print_activity_statement').report_action(
self, data=data)
def _prepare_statement(self):
res = super()._prepare_statement()
res.update({'date_start': self.date_start})
return res

View File

@@ -0,0 +1,21 @@
# Copyright 2018 Eficent Business and IT Consulting Services S.L.
# (http://www.eficent.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 _export(self):
"""Export to PDF."""
data = self._prepare_statement()
return self.env.ref(
'partner_statement'
'.action_print_outstanding_statement').report_action(
self, data=data)

View File

@@ -0,0 +1,57 @@
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
group_activity_statement = fields.Boolean(
"Enable OCA 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_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)
return super().set_values()

View File

@@ -0,0 +1,70 @@
# 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
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.user.company_id,
string='Company'
)
date_end = fields.Date(required=True, default=fields.Date.context_today)
show_aging_buckets = fields.Boolean(default=True)
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(
[('receivable', 'Receivable'),
('payable', 'Payable')], string='Account type', default='receivable')
@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)
@api.multi
def button_export_pdf(self):
self.ensure_one()
return self._export()
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,
'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,
}
def _export(self):
raise NotImplementedError

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 Eficent Business and IT Consulting Services S.L.
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<!-- wizard action on res.partner -->
<act_window id="activity_statement_wizard_action"
name="Partner Activity Statement"
src_model="res.partner"
res_model="activity.statement.wizard"
view_type="form" view_mode="form"
key2="client_action_multi" target="new"
groups="partner_statement.group_activity_statement"/>
<act_window id="outstanding_statement_wizard_action"
name="Partner Outstanding Statement"
src_model="res.partner"
res_model="outstanding.statement.wizard"
view_type="form" view_mode="form"
key2="client_action_multi" target="new"
groups="partner_statement.group_outstanding_statement"/>
<!-- 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">
<label string="Aging details can be shown in the report, expressed in aging
buckets, so the partner can review how much is open, due or overdue." for=""/>
</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"/>
</group>
<group name="aging_report">
<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_pdf" string="Export PDF" type="object" default_focus="1" class="oe_highlight"/>
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']/label" position="before" >
<label string="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." for=""/>
<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']/label" position="before" >
<label string="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." for=""/>
<br/><br/>
</xpath>
<xpath expr="//field[@name='date_end']" position="before">
<field name="date_start"/>
</xpath>
</field>
</record>
</odoo>