[IMP] Extend customer_activity_statement to display also payables
parent
06a2ee981d
commit
ebdb5adbc0
|
@ -3,17 +3,17 @@
|
|||
:alt: License: AGPL-3
|
||||
|
||||
=================================
|
||||
Print Customer Activity Statement
|
||||
Print Partner Activity Statement
|
||||
=================================
|
||||
|
||||
The activity statement provides details of all activity on the customer receivables
|
||||
The activity statement provides details of all activity on the partner receivables or 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.
|
||||
|
||||
Aging details can be shown in the report, expressed in aging buckets (30 days
|
||||
due, ...), so the customer can review how much is open, due or overdue.
|
||||
due, ...), so the customer or vendor can review how much is open, due or overdue.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
@ -22,22 +22,28 @@ Users willing to access to this report should have proper Accounting & Finance r
|
|||
|
||||
#. Go to *Settings / Users* and edit your user to add the corresponding access rights as follows.
|
||||
#. In *Application / Accounting & Finance*, select *Billing* or *Billing Manager*
|
||||
#. In *Technical Setting* mark *Show Full Accounting Features* options.
|
||||
#. In *Technical Settings* mark *Show Full Accounting Features* options.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
To use this module, you need to:
|
||||
|
||||
#. Go to Invoicing > Sales > Master Data > Customers and select one or more
|
||||
#. Press 'Action > Customer Activity Statement'
|
||||
#. Indicate if you want to display aging buckets
|
||||
#. Go to Invoicing > Sales > Master Data > Customers or Invoicing > Purchases > Master Data > Vendors and select one or more
|
||||
#. Press 'Action > Partner Activity Statement'
|
||||
#. Indicate if you want to display receivables or payables, and if you want to display aging buckets
|
||||
|
||||
|
||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||
:alt: Try me on Runbot
|
||||
:target: https://runbot.odoo-community.org/runbot/91/11.0
|
||||
|
||||
Roadmap
|
||||
=======
|
||||
|
||||
* In v12, the module should be renamed to `Partner Activity Statement`.
|
||||
Maybe merge this module with the `Partner Outstanding Statement` module.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
{
|
||||
'name': 'Customer Activity Statement',
|
||||
'version': '11.0.1.0.0',
|
||||
'name': 'Partner Activity Statement',
|
||||
'version': '11.0.2.0.0',
|
||||
'category': 'Accounting & Finance',
|
||||
'summary': 'OCA Financial Reports',
|
||||
'author': "Eficent, Odoo Community Association (OCA)",
|
||||
|
|
|
@ -18,7 +18,7 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
date = datetime.strptime(str_date, DEFAULT_SERVER_DATE_FORMAT).date()
|
||||
return date.strftime(lang.date_format)
|
||||
|
||||
def _initial_balance_sql_q1(self, partners, date_start):
|
||||
def _initial_balance_sql_q1(self, partners, date_start, account_type):
|
||||
return """
|
||||
SELECT l.partner_id, l.currency_id, l.company_id,
|
||||
CASE WHEN l.currency_id is not null AND l.amount_currency > 0.0
|
||||
|
@ -32,11 +32,11 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
FROM account_move_line l
|
||||
JOIN account_account_type at ON (at.id = l.user_type_id)
|
||||
JOIN account_move m ON (l.move_id = m.id)
|
||||
WHERE l.partner_id IN (%s) AND at.type = 'receivable'
|
||||
WHERE l.partner_id IN (%s) AND at.type = '%s'
|
||||
AND l.date < '%s' AND not l.blocked
|
||||
GROUP BY l.partner_id, l.currency_id, l.amount_currency,
|
||||
l.company_id
|
||||
""" % (partners, date_start)
|
||||
""" % (partners, account_type, date_start)
|
||||
|
||||
def _initial_balance_sql_q2(self, company_id):
|
||||
return """
|
||||
|
@ -48,7 +48,7 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
""" % company_id
|
||||
|
||||
def _get_account_initial_balance(self, company_id, partner_ids,
|
||||
date_start):
|
||||
date_start, account_type):
|
||||
res = dict(map(lambda x: (x, []), partner_ids))
|
||||
partners = ', '.join([str(i) for i in partner_ids])
|
||||
date_start = datetime.strptime(
|
||||
|
@ -56,13 +56,15 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
# pylint: disable=E8103
|
||||
self.env.cr.execute("""WITH Q1 AS (%s), Q2 AS (%s)
|
||||
SELECT partner_id, currency_id, balance
|
||||
FROM Q2""" % (self._initial_balance_sql_q1(partners, date_start),
|
||||
FROM Q2""" % (self._initial_balance_sql_q1(partners, date_start,
|
||||
account_type),
|
||||
self._initial_balance_sql_q2(company_id)))
|
||||
for row in self.env.cr.dictfetchall():
|
||||
res[row.pop('partner_id')].append(row)
|
||||
return res
|
||||
|
||||
def _display_lines_sql_q1(self, partners, date_start, date_end):
|
||||
def _display_lines_sql_q1(self, partners, date_start, date_end,
|
||||
account_type):
|
||||
return """
|
||||
SELECT m.name AS move_id, l.partner_id, l.date, l.name,
|
||||
l.ref, l.blocked, l.currency_id, l.company_id,
|
||||
|
@ -81,12 +83,12 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
FROM account_move_line l
|
||||
JOIN account_account_type at ON (at.id = l.user_type_id)
|
||||
JOIN account_move m ON (l.move_id = m.id)
|
||||
WHERE l.partner_id IN (%s) AND at.type = 'receivable'
|
||||
WHERE l.partner_id IN (%s) AND at.type = '%s'
|
||||
AND '%s' <= l.date AND l.date <= '%s'
|
||||
GROUP BY l.partner_id, m.name, l.date, l.date_maturity, l.name,
|
||||
l.ref, l.blocked, l.currency_id,
|
||||
l.amount_currency, l.company_id
|
||||
""" % (partners, date_start, date_end)
|
||||
""" % (partners, account_type, date_start, date_end)
|
||||
|
||||
def _display_lines_sql_q2(self, company_id):
|
||||
return """
|
||||
|
@ -99,7 +101,7 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
""" % company_id
|
||||
|
||||
def _get_account_display_lines(self, company_id, partner_ids, date_start,
|
||||
date_end):
|
||||
date_end, account_type):
|
||||
res = dict(map(lambda x: (x, []), partner_ids))
|
||||
partners = ', '.join([str(i) for i in partner_ids])
|
||||
date_start = datetime.strptime(
|
||||
|
@ -112,7 +114,8 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
credit, amount, blocked, currency_id
|
||||
FROM Q2
|
||||
ORDER BY date, date_maturity, move_id""" % (
|
||||
self._display_lines_sql_q1(partners, date_start, date_end),
|
||||
self._display_lines_sql_q1(partners, date_start, date_end,
|
||||
account_type),
|
||||
self._display_lines_sql_q2(company_id)))
|
||||
for row in self.env.cr.dictfetchall():
|
||||
res[row.pop('partner_id')].append(row)
|
||||
|
@ -143,7 +146,7 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
GROUP BY l1.id
|
||||
""" % (date_end, date_end)
|
||||
|
||||
def _show_buckets_sql_q1(self, partners, date_end):
|
||||
def _show_buckets_sql_q1(self, partners, date_end, account_type):
|
||||
return """
|
||||
SELECT l.partner_id, l.currency_id, l.company_id, l.move_id,
|
||||
CASE WHEN l.balance > 0.0
|
||||
|
@ -174,14 +177,14 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
ON pr.debit_move_id = l2.id
|
||||
WHERE l2.date <= '%s'
|
||||
) as pc ON pc.credit_move_id = l.id
|
||||
WHERE l.partner_id IN (%s) AND at.type = 'receivable'
|
||||
WHERE l.partner_id IN (%s) AND at.type = '%s'
|
||||
AND (Q0.reconciled_date is null or
|
||||
Q0.reconciled_date > '%s')
|
||||
AND l.date <= '%s' AND not l.blocked
|
||||
GROUP BY l.partner_id, l.currency_id, l.date, l.date_maturity,
|
||||
l.amount_currency, l.balance, l.move_id,
|
||||
l.company_id
|
||||
""" % (date_end, date_end, partners, date_end, date_end)
|
||||
""" % (date_end, date_end, partners, account_type, date_end, date_end)
|
||||
|
||||
def _show_buckets_sql_q2(self, date_end, minus_30, minus_60, minus_90,
|
||||
minus_120):
|
||||
|
@ -273,7 +276,8 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
'minus_120': date_end - timedelta(days=120),
|
||||
}
|
||||
|
||||
def _get_account_show_buckets(self, company_id, partner_ids, date_end):
|
||||
def _get_account_show_buckets(self, company_id, partner_ids, date_end,
|
||||
account_type):
|
||||
res = dict(map(lambda x: (x, []), partner_ids))
|
||||
partners = ', '.join([str(i) for i in partner_ids])
|
||||
date_end = datetime.strptime(
|
||||
|
@ -290,7 +294,7 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
GROUP BY partner_id, currency_id, current, b_1_30, b_30_60, b_60_90,
|
||||
b_90_120, b_over_120""" % (
|
||||
self._show_buckets_sql_q0(date_end),
|
||||
self._show_buckets_sql_q1(partners, date_end),
|
||||
self._show_buckets_sql_q1(partners, date_end, account_type),
|
||||
self._show_buckets_sql_q2(
|
||||
full_dates['date_end'],
|
||||
full_dates['minus_30'],
|
||||
|
@ -309,6 +313,7 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
partner_ids = data['partner_ids']
|
||||
date_start = data['date_start']
|
||||
date_end = data['date_end']
|
||||
account_type = data['account_type']
|
||||
today = fields.Date.today()
|
||||
|
||||
balance_start_to_display, buckets_to_display = {}, {}
|
||||
|
@ -317,7 +322,7 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
today_display, date_start_display, date_end_display = {}, {}, {}
|
||||
|
||||
balance_start = self._get_account_initial_balance(
|
||||
company_id, partner_ids, date_start)
|
||||
company_id, partner_ids, date_start, account_type)
|
||||
|
||||
for partner_id in partner_ids:
|
||||
balance_start_to_display[partner_id] = {}
|
||||
|
@ -329,7 +334,7 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
line['balance']
|
||||
|
||||
lines = self._get_account_display_lines(
|
||||
company_id, partner_ids, date_start, date_end)
|
||||
company_id, partner_ids, date_start, date_end, account_type)
|
||||
|
||||
for partner_id in partner_ids:
|
||||
lines_to_display[partner_id], amount_due[partner_id] = {}, {}
|
||||
|
@ -361,7 +366,7 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
|
||||
if data['show_aging_buckets']:
|
||||
buckets = self._get_account_show_buckets(
|
||||
company_id, partner_ids, date_end)
|
||||
company_id, partner_ids, date_end, account_type)
|
||||
for partner_id in partner_ids:
|
||||
buckets_to_display[partner_id] = {}
|
||||
for line in buckets[partner_id]:
|
||||
|
@ -385,4 +390,5 @@ class CustomerActivityStatement(models.AbstractModel):
|
|||
'Date_start': date_start_display,
|
||||
'Date_end': date_end_display,
|
||||
'Date': today_display,
|
||||
'account_type': account_type,
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<section class="oe_container">
|
||||
<div class="oe_row oe_spaced">
|
||||
<div class="oe_span12">
|
||||
<h2 class="oe_slogan">Customer Activity Statement</h2>
|
||||
<h2 class="oe_slogan">Partner Activity Statement</h2>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_demo oe_picture oe_screenshot">
|
||||
|
@ -10,12 +10,12 @@
|
|||
</div>
|
||||
<div class="oe_span4">
|
||||
<p class="oe_mt32"><div style="text-align:justify">The activity statement provides
|
||||
details of all activity on the customer receivables between two selected dates. This
|
||||
details of all activity on the receivables or payables of a partner 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.<br><br>Aging
|
||||
details can be shown in the report, expressed in aging buckets (30 days due, ...),
|
||||
so the customer can review how much is open, due or overdue.</div></p>
|
||||
so the customer or vendor can review how much is open, due or overdue.</div></p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -45,8 +45,8 @@ so the customer can review how much is open, due or overdue.</div></p>
|
|||
<div class="oe_span12">
|
||||
<p class="oe_mt32">To use this module, you need to:
|
||||
<ul>
|
||||
<li>Go to <code>Invoicing > Sales > Master Data > Customers</code> and select one or more</li>
|
||||
<li>Press '<code>Action > Customer Activity Statement</code>'</li>
|
||||
<li>Go to <code>Invoicing > Sales > Master Data > Customers</code> or <code>Invoicing > Purchases > Master Data > Vendors</code> and select one or more</li>
|
||||
<li>Press '<code>Action > Partner Activity Statement</code>'</li>
|
||||
<li>Indicate if you want to display aging buckets</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
|
|
@ -23,8 +23,11 @@
|
|||
<br/>
|
||||
<t t-foreach="Lines[o.id]" t-as="currency">
|
||||
<br t-if="not currency_first" />
|
||||
<p>
|
||||
Activity Statement between <span t-esc="Date_start[o.id]" /> and <span t-esc="Date_end[o.id]" /> in <span t-esc="Currencies[o.id][currency].name"/>:
|
||||
<p t-if="account_type == 'receivable'">
|
||||
Customer Activity Statement between <span t-esc="Date_start[o.id]" /> and <span t-esc="Date_end[o.id]" /> in <span t-esc="Currencies[o.id][currency].name"/>:
|
||||
</p>
|
||||
<p t-if="account_type == 'payable'">
|
||||
Supplier Activity Statement between <span t-esc="Date_start[o.id]" /> and <span t-esc="Date_end[o.id]" /> in <span t-esc="Currencies[o.id][currency].name"/>:
|
||||
</p>
|
||||
<table class="table table-condensed" style="border: 1px solid black; border-collapse: collapse;">
|
||||
<thead>
|
||||
|
|
|
@ -30,6 +30,9 @@ class CustomerActivityStatementWizard(models.TransientModel):
|
|||
)
|
||||
filter_partners_non_due = fields.Boolean(
|
||||
string='Don\'t show partners with no due entries', default=True)
|
||||
account_type = fields.Selection(
|
||||
[('receivable', 'Receivable'),
|
||||
('payable', 'Payable')], string='Account type', default='receivable')
|
||||
|
||||
@api.multi
|
||||
def button_export_pdf(self):
|
||||
|
@ -45,6 +48,7 @@ class CustomerActivityStatementWizard(models.TransientModel):
|
|||
'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,
|
||||
}
|
||||
|
||||
def _export(self):
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<odoo>
|
||||
<!-- wizard action on res.partner -->
|
||||
<act_window id="customer_activity_statement_wizard_action"
|
||||
name="Customer Activity Statement"
|
||||
name="Partner Activity Statement"
|
||||
src_model="res.partner"
|
||||
res_model="customer.activity.statement.wizard"
|
||||
view_type="form" view_mode="form"
|
||||
|
@ -19,16 +19,21 @@
|
|||
<form name="Report Options">
|
||||
<div style="text-align:justify">
|
||||
<label string="The activity statement provides details of all activity on
|
||||
the customer receivables between two selected dates. This includes all invoices,
|
||||
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."/><br/><br/>
|
||||
<label string="Aging details can be shown in the report, expressed in aging
|
||||
buckets (30 days due, ...), so the customer can review how much is open, due or overdue."/>
|
||||
buckets (30 days due, ...), so the customer or vendor can review how much is open, due or overdue."/>
|
||||
</div><hr/>
|
||||
<group name="main_info">
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
<group name="account_type">
|
||||
<label for="account_type"/>
|
||||
<field name="account_type" nolabel="1" widget="radio"/>
|
||||
</group>
|
||||
|
||||
<group name="dates">
|
||||
<field name="date_start"/>
|
||||
<field name="date_end"/>
|
||||
|
|
Loading…
Reference in New Issue