Browse Source

Add OCA Open Invoice report

pull/211/head
jcoux 9 years ago
parent
commit
d7b34ccf97
  1. 9
      account_financial_report_qweb/menuitems.xml
  2. 724
      account_financial_report_qweb/report/open_invoice.py
  3. 331
      account_financial_report_qweb/report/templates/open_invoice_report.xml
  4. 34
      account_financial_report_qweb/reports.xml
  5. 123
      account_financial_report_qweb/wizard/open_invoice_wizard.py
  6. 47
      account_financial_report_qweb/wizard/open_invoice_wizard_view.xml

9
account_financial_report_qweb/menuitems.xml

@ -33,9 +33,12 @@
<menuitem icon="STOCK_PRINT" name="Profit &amp; Loss"
parent="menu_oca_reports" action="action_account_profit_loss_wizard_view"
groups="account.group_account_manager,account.group_account_user" id="menu_account_profit_loss_report"/>
<menuitem icon="STOCK_PRINT" name="Open Invoices"
parent="menu_oca_reports" action="action_open_invoice_report"
groups="account.group_account_manager,account.group_account_user" id="menu_invoice_report_wizard"/>
<menuitem
parent="menu_oca_reports"
action='action_open_invoice_wizard'
id='menu_open_invoice_wizard'
/>
</data>
</openerp>

724
account_financial_report_qweb/report/open_invoice.py

@ -1,58 +1,674 @@
# -*- coding: utf-8 -*-
# Author: Andrea andrea4ever Gallina
# Author: Francesco OpenCode Apruzzese
# Author: Ciro CiroBoxHub Urselli
# Copyright 2016 Camptocamp SA
# © 2016 Julien Coux (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields, api
from openerp import models, api
class OpenInvoiceReport(models.AbstractModel):
_name = 'report.account_financial_report_qweb.open_invoice_report_qweb'
def _get_domain(self, data):
account_type = ('payable', 'receivable')
if data['form']['result_selection'] == 'customer':
account_type = ('receivable', )
elif data['form']['result_selection'] == 'supplier':
account_type = ('payable', )
domain = [
('company_id', '=', data['form']['company_id'][0]),
('move_id.date', '<=', data['form']['at_date']),
('account_id.user_type_id.type', 'in', account_type)
]
if data['form']['target_move'] != 'all':
domain.append(('move_id.state', 'in', ('posted', )), )
if data['form']['partner_ids']:
domain.append(('partner_id', 'in',
[p.id for p in data['form']['partner_ids']]), )
return domain
def _query(self, data):
moves = self.env['account.move.line'].search(
self._get_domain(data), order='date asc')
if not moves:
return True # ----- Show a message here
return moves
@api.multi
def render_html(self, data=None):
report_obj = self.env['report']
moves = self._query(data)
docargs = {
'doc_model': 'account.move.line',
'doc_ids': data['ids'],
'docs': moves,
'header': data['header'],
'account_obj': self.env['account.account'],
'partner_obj': self.env['res.partner'],
'currency_obj': self.env['res.currency'],
}
return report_obj.render(
'account_financial_report_qweb.open_invoice_report_qweb',
docargs)
class OpenInvoiceReport(models.TransientModel):
""" Here, we just define class fields.
For methods, go more bottom at this file.
"""
_name = 'report_open_invoice_qweb'
date_at = fields.Date()
only_posted_moves = fields.Boolean()
hide_account_balance_at_0 = fields.Boolean()
company_id = fields.Many2one(comodel_name='res.company')
filter_account_ids = fields.Many2many(comodel_name='account.account')
filter_partner_ids = fields.Many2many(comodel_name='res.partner')
has_second_currency = fields.Boolean()
account_ids = fields.One2many(
comodel_name='report_open_invoice_qweb_account',
inverse_name='report_id'
)
class OpenInvoiceReportAccount(models.TransientModel):
_name = 'report_open_invoice_qweb_account'
_order = 'code ASC'
report_id = fields.Many2one(
comodel_name='report_open_invoice_qweb',
ondelete='cascade',
index=True
)
account_id = fields.Many2one(
'account.account',
index=True
)
code = fields.Char()
name = fields.Char()
final_amount_residual = fields.Float(digits=(16, 2))
partner_ids = fields.One2many(
comodel_name='report_open_invoice_qweb_partner',
inverse_name='report_account_id'
)
class OpenInvoiceReportPartner(models.TransientModel):
_name = 'report_open_invoice_qweb_partner'
report_account_id = fields.Many2one(
comodel_name='report_open_invoice_qweb_account',
ondelete='cascade',
index=True
)
partner_id = fields.Many2one(
'res.partner',
index=True
)
name = fields.Char()
final_amount_residual = fields.Float(digits=(16, 2))
move_line_ids = fields.One2many(
comodel_name='report_open_invoice_qweb_move_line',
inverse_name='report_partner_id'
)
@api.model
def _generate_order_by(self, order_spec, query):
return """
ORDER BY
CASE
WHEN "report_open_invoice_qweb_partner"."partner_id" IS NOT NULL
THEN 0
ELSE 1
END,
"report_open_invoice_qweb_partner"."name"
"""
class OpenInvoiceReportMoveLine(models.TransientModel):
_name = 'report_open_invoice_qweb_move_line'
report_partner_id = fields.Many2one(
comodel_name='report_open_invoice_qweb_partner',
ondelete='cascade',
index=True
)
move_line_id = fields.Many2one('account.move.line')
date = fields.Date()
date_due = fields.Date()
entry = fields.Char()
journal = fields.Char()
account = fields.Char()
partner = fields.Char()
label = fields.Char()
amount_total_due = fields.Float(digits=(16, 2))
amount_residual = fields.Float(digits=(16, 2))
currency_name = fields.Char()
amount_total_due_currency = fields.Float(digits=(16, 2))
amount_residual_currency = fields.Float(digits=(16, 2))
class OpenInvoiceReportCompute(models.TransientModel):
_inherit = 'report_open_invoice_qweb'
@api.model
def print_report(self):
self.ensure_one()
self.compute_data_for_report()
return {
'type': 'ir.actions.report.xml',
'report_name':
'account_financial_report_qweb.report_open_invoice_qweb',
'datas': {'ids': [self.id]},
}
@api.model
def compute_data_for_report(self):
self.ensure_one()
self.inject_account_values()
self.inject_partner_values()
self.inject_line_values()
self.inject_line_values(only_empty_partner_line=True)
self.clean_partners_and_accounts()
self.compute_partners_and_accounts_cumul()
if self.hide_account_balance_at_0:
self.clean_partners_and_accounts(
only_delete_account_balance_at_0=True
)
self.compute_has_second_currency()
def inject_account_values(self):
query_inject_account = """
WITH
accounts AS
(
SELECT
a.id,
a.code,
a.name,
a.user_type_id
FROM
account_account a
INNER JOIN
account_move_line ml ON a.id = ml.account_id AND ml.date <= %s
"""
if self.filter_partner_ids:
query_inject_account += """
INNER JOIN
res_partner p ON ml.partner_id = p.id
"""
if self.only_posted_moves:
query_inject_account += """
INNER JOIN
account_move m ON ml.move_id = m.id AND m.state = 'posted'
"""
query_inject_account += """
WHERE
a.company_id = %s
AND a.internal_type IN ('payable', 'receivable')
"""
if self.filter_account_ids:
query_inject_account += """
AND
a.id IN %s
"""
if self.filter_partner_ids:
query_inject_account += """
AND
p.id IN %s
"""
query_inject_account += """
GROUP BY
a.id
)
INSERT INTO
report_open_invoice_qweb_account
(
report_id,
create_uid,
create_date,
account_id,
code,
name
)
SELECT
%s AS report_id,
%s AS create_uid,
NOW() AS create_date,
a.id AS account_id,
a.code,
a.name
FROM
accounts a
"""
query_inject_account_params = (
self.date_at,
self.company_id.id,
)
if self.filter_account_ids:
query_inject_account_params += (
tuple(self.filter_account_ids.ids),
)
if self.filter_partner_ids:
query_inject_account_params += (
tuple(self.filter_partner_ids.ids),
)
query_inject_account_params += (
self.id,
self.env.uid,
)
self.env.cr.execute(query_inject_account, query_inject_account_params)
def inject_partner_values(self):
query_inject_partner = """
WITH
accounts_partners AS
(
SELECT
ra.id AS report_account_id,
a.id AS account_id,
at.include_initial_balance AS include_initial_balance,
p.id AS partner_id,
COALESCE(
CASE
WHEN
NULLIF(p.name, '') IS NOT NULL
AND NULLIF(p.ref, '') IS NOT NULL
THEN p.name || ' (' || p.ref || ')'
ELSE p.name
END,
'No partner allocated'
) AS partner_name
FROM
report_open_invoice_qweb_account ra
INNER JOIN
account_account a ON ra.account_id = a.id
INNER JOIN
account_account_type at ON a.user_type_id = at.id
INNER JOIN
account_move_line ml ON a.id = ml.account_id AND ml.date <= %s
"""
if self.only_posted_moves:
query_inject_partner += """
INNER JOIN
account_move m ON ml.move_id = m.id AND m.state = 'posted'
"""
query_inject_partner += """
LEFT JOIN
res_partner p ON ml.partner_id = p.id
WHERE
ra.report_id = %s
"""
if self.filter_partner_ids:
query_inject_partner += """
AND
p.id IN %s
"""
query_inject_partner += """
GROUP BY
ra.id,
a.id,
p.id,
at.include_initial_balance
)
INSERT INTO
report_open_invoice_qweb_partner
(
report_account_id,
create_uid,
create_date,
partner_id,
name
)
SELECT
ap.report_account_id,
%s AS create_uid,
NOW() AS create_date,
ap.partner_id,
ap.partner_name
FROM
accounts_partners ap
"""
query_inject_partner_params = (
self.date_at,
self.id,
)
if self.filter_partner_ids:
query_inject_partner_params += (
tuple(self.filter_partner_ids.ids),
)
query_inject_partner_params += (
self.env.uid,
)
self.env.cr.execute(query_inject_partner, query_inject_partner_params)
def inject_line_values(self, only_empty_partner_line=False):
query_inject_move_line = """
WITH
move_lines_amount AS
(
SELECT
ml.id,
ml.balance,
SUM(
CASE
WHEN ml_past.id IS NOT NULL
THEN pr.amount
ELSE NULL
END
) AS partial_amount,
ml.amount_currency,
SUM(
CASE
WHEN ml_past.id IS NOT NULL
THEN pr.amount_currency
ELSE NULL
END
) AS partial_amount_currency
FROM
report_open_invoice_qweb_partner rp
INNER JOIN
report_open_invoice_qweb_account ra
ON rp.report_account_id = ra.id
INNER JOIN
account_move_line ml
ON ra.account_id = ml.account_id
"""
if not only_empty_partner_line:
query_inject_move_line += """
AND rp.partner_id = ml.partner_id
"""
elif only_empty_partner_line:
query_inject_move_line += """
AND ml.partner_id IS NULL
"""
query_inject_move_line += """
LEFT JOIN
account_partial_reconcile pr
ON ml.balance < 0 AND pr.credit_move_id = ml.id
OR ml.balance > 0 AND pr.debit_move_id = ml.id
LEFT JOIN
account_move_line ml_future
ON (
ml.balance < 0 AND pr.debit_move_id = ml_future.id
OR ml.balance > 0 AND pr.credit_move_id = ml_future.id
)
AND ml_future.date >= %s
LEFT JOIN
account_move_line ml_past
ON (
ml.balance < 0 AND pr.debit_move_id = ml_past.id
OR ml.balance > 0 AND pr.credit_move_id = ml_past.id
)
AND ml_past.date < %s
WHERE
ra.report_id = %s
GROUP BY
ml.id,
ml.balance,
ml.amount_currency
HAVING
(
ml.full_reconcile_id IS NULL
OR MAX(ml_future.id) IS NOT NULL
)
),
move_lines AS
(
SELECT
id,
CASE
WHEN SUM(partial_amount) > 0
THEN
CASE
WHEN balance > 0
THEN balance - SUM(partial_amount)
ELSE balance + SUM(partial_amount)
END
ELSE balance
END AS amount_residual,
CASE
WHEN SUM(partial_amount_currency) > 0
THEN
CASE
WHEN amount_currency > 0
THEN amount_currency - SUM(partial_amount_currency)
ELSE amount_currency + SUM(partial_amount_currency)
END
ELSE amount_currency
END AS amount_residual_currency
FROM
move_lines_amount
GROUP BY
id,
balance,
amount_currency
)
INSERT INTO
report_open_invoice_qweb_move_line
(
report_partner_id,
create_uid,
create_date,
move_line_id,
date,
date_due,
entry,
journal,
account,
partner,
label,
amount_total_due,
amount_residual,
currency_name,
amount_total_due_currency,
amount_residual_currency
)
SELECT
rp.id AS report_partner_id,
%s AS create_uid,
NOW() AS create_date,
ml.id AS move_line_id,
ml.date,
ml.date_maturity,
m.name AS entry,
j.code AS journal,
a.code AS account,
"""
if not only_empty_partner_line:
query_inject_move_line += """
CASE
WHEN
NULLIF(p.name, '') IS NOT NULL
AND NULLIF(p.ref, '') IS NOT NULL
THEN p.name || ' (' || p.ref || ')'
ELSE p.name
END AS partner,
"""
elif only_empty_partner_line:
query_inject_move_line += """
'No partner allocated' AS partner,
"""
query_inject_move_line += """
CONCAT_WS(' - ', NULLIF(ml.ref, ''), NULLIF(ml.name, '')) AS label,
ml.balance,
ml2.amount_residual,
c.name AS currency_name,
ml.amount_currency,
ml2.amount_residual_currency
FROM
report_open_invoice_qweb_partner rp
INNER JOIN
report_open_invoice_qweb_account ra ON rp.report_account_id = ra.id
INNER JOIN
account_move_line ml ON ra.account_id = ml.account_id
INNER JOIN
move_lines ml2
ON ml.id = ml2.id
AND ml2.amount_residual IS NOT NULL
AND ml2.amount_residual != 0
INNER JOIN
account_move m ON ml.move_id = m.id
INNER JOIN
account_journal j ON ml.journal_id = j.id
INNER JOIN
account_account a ON ml.account_id = a.id
"""
if not only_empty_partner_line:
query_inject_move_line += """
INNER JOIN
res_partner p
ON ml.partner_id = p.id AND rp.partner_id = p.id
"""
query_inject_move_line += """
LEFT JOIN
account_full_reconcile fr ON ml.full_reconcile_id = fr.id
LEFT JOIN
res_currency c ON a.currency_id = c.id
WHERE
ra.report_id = %s
AND
ml.date <= %s
"""
if self.only_posted_moves:
query_inject_move_line += """
AND
m.state = 'posted'
"""
if only_empty_partner_line:
query_inject_move_line += """
AND
ml.partner_id IS NULL
AND
rp.partner_id IS NULL
"""
if not only_empty_partner_line:
query_inject_move_line += """
ORDER BY
a.code, p.name, ml.date, ml.id
"""
elif only_empty_partner_line:
query_inject_move_line += """
ORDER BY
a.code, ml.date, ml.id
"""
self.env.cr.execute(
query_inject_move_line,
(self.date_at,
self.date_at,
self.id,
self.env.uid,
self.id,
self.date_at,)
)
def compute_partners_and_accounts_cumul(self):
query_compute_partners_cumul = """
UPDATE
report_open_invoice_qweb_partner
SET
final_amount_residual =
(
SELECT
SUM(rml.amount_residual) AS final_amount_residual
FROM
report_open_invoice_qweb_move_line rml
WHERE
rml.report_partner_id = report_open_invoice_qweb_partner.id
)
WHERE
id IN
(
SELECT
rp.id
FROM
report_open_invoice_qweb_account ra
INNER JOIN
report_open_invoice_qweb_partner rp
ON ra.id = rp.report_account_id
WHERE
ra.report_id = %s
)
"""
params_compute_partners_cumul = (self.id,)
self.env.cr.execute(query_compute_partners_cumul,
params_compute_partners_cumul)
query_compute_accounts_cumul = """
UPDATE
report_open_invoice_qweb_account
SET
final_amount_residual =
(
SELECT
SUM(rp.final_amount_residual) AS final_amount_residual
FROM
report_open_invoice_qweb_partner rp
WHERE
rp.report_account_id = report_open_invoice_qweb_account.id
)
WHERE
report_id = %s
"""
params_compute_accounts_cumul = (self.id,)
self.env.cr.execute(query_compute_accounts_cumul,
params_compute_accounts_cumul)
def clean_partners_and_accounts(self,
only_delete_account_balance_at_0=False):
query_clean_partners = """
DELETE FROM
report_open_invoice_qweb_partner
WHERE
id IN
(
SELECT
DISTINCT rp.id
FROM
report_open_invoice_qweb_account ra
INNER JOIN
report_open_invoice_qweb_partner rp
ON ra.id = rp.report_account_id
LEFT JOIN
report_open_invoice_qweb_move_line rml
ON rp.id = rml.report_partner_id
WHERE
ra.report_id = %s
"""
if not only_delete_account_balance_at_0:
query_clean_partners += """
AND rml.id IS NULL
"""
elif only_delete_account_balance_at_0:
query_clean_partners += """
AND (
rp.final_amount_residual IS NULL
OR rp.final_amount_residual = 0
)
"""
query_clean_partners += """
)
"""
params_clean_partners = (self.id,)
self.env.cr.execute(query_clean_partners, params_clean_partners)
query_clean_accounts = """
DELETE FROM
report_open_invoice_qweb_account
WHERE
id IN
(
SELECT
DISTINCT ra.id
FROM
report_open_invoice_qweb_account ra
LEFT JOIN
report_open_invoice_qweb_partner rp
ON ra.id = rp.report_account_id
WHERE
ra.report_id = %s
"""
if not only_delete_account_balance_at_0:
query_clean_accounts += """
AND rp.id IS NULL
"""
elif only_delete_account_balance_at_0:
query_clean_accounts += """
AND (
ra.final_amount_residual IS NULL
OR ra.final_amount_residual = 0
)
"""
query_clean_accounts += """
)
"""
params_clean_accounts = (self.id,)
self.env.cr.execute(query_clean_accounts, params_clean_accounts)
def compute_has_second_currency(self):
query_update_has_second_currency = """
UPDATE
report_open_invoice_qweb
SET
has_second_currency =
(
SELECT
TRUE
FROM
report_open_invoice_qweb_move_line l
INNER JOIN
report_open_invoice_qweb_partner p
ON l.report_partner_id = p.id
INNER JOIN
report_open_invoice_qweb_account a
ON p.report_account_id = a.id
WHERE
a.report_id = %s
AND l.currency_name IS NOT NULL
LIMIT 1
)
WHERE id = %s
"""
params = (self.id,) * 2
self.env.cr.execute(query_update_has_second_currency, params)

331
account_financial_report_qweb/report/templates/open_invoice_report.xml

@ -1,210 +1,163 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<odoo>
<template id="open_invoice_specific" inherit_id="report.assets_common">
<xpath expr="." position="inside">
<link href="/account_financial_report_qweb/static/src/css/report.css" rel="stylesheet"/>
</xpath>
</template>
<template id="open_invoice_report_qweb">
<div class="header">
<div class="row">
<div class="col-xs-4 text-left">
<h6><span t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d %H:%M')"/></h6>
</div>
<div class="col-xs-4 text-center">
<img t-if="res_company.logo" t-att-src="'data:image/png;base64,%s' % res_company.logo" style="max-height: 40px;"/>
</div>
<div class="col-xs-4 text-right">
<npage>
<ul class="list-inline">
<li><span class="page"/></li>
<li>/</li>
<li><span class="topage"/></li>
</ul>
</npage>
</div>
</div>
</div>
<template id="account_financial_report_qweb.report_open_invoice_qweb">
<t t-call="report.html_container">
<t t-call="report.internal_layout">
<div class="page">
<t t-foreach="docs" t-as="o">
<t t-set="has_second_currency" t-value="o.has_second_currency"/>
<!-- Generic information -->
<div class="act_as_table data_table">
<div class="act_as_thead">
<t t-call="account_financial_report_qweb.internal_layout">
<t t-set="title" t-value='"Open Items Report"'/>
<t t-set="company_name" t-value="o.company_id.name"/>
<div class="page">
<div class="act_as_table data_table" style="width: 1140px !important;">
<div class="act_as_row labels">
<div class="act_as_cell first_column">Company</div>
<div class="act_as_cell">At Date</div>
<div class="act_as_cell">Accounts Filter</div>
<div class="act_as_cell">Target Moves</div>
<div class="act_as_cell">Date at filter</div>
<div class="act_as_cell">Target moves filter</div>
<div class="act_as_cell">Account balance at 0 filter</div>
</div>
</div>
<div class="act_as_tbody">
<div class="act_as_row">
<div class="act_as_cell first_column"><span t-esc="header['company']"/></div>
<div class="act_as_cell"><span t-esc="header['at_date']"/></div>
<div class="act_as_cell"><span t-esc="header['account_filters']"/></div>
<div class="act_as_cell"><span t-esc="header['target_moves']"/></div>
<div class="act_as_cell">
<span t-field="o.date_at"/>
</div>
<div class="act_as_cell">
<t t-if="o.only_posted_moves">All posted entries</t>
<t t-if="not o.only_posted_moves">All entries</t>
</div>
<div class="act_as_cell">
<t t-if="o.hide_account_balance_at_0">Hide</t>
<t t-if="not o.hide_account_balance_at_0">Show</t>
</div>
</div>
</div>
</div>
<!-- Group by account -->
<t t-foreach="docs.read_group([('id', 'in', docs.ids)],['account_id'],['account_id'])" t-as="acc">
<t t-set="account"
t-value="account_obj.browse(acc['account_id'][0])"/>
<t t-set="account_debit" t-value="0.0" />
<t t-set="account_credit" t-value="0.0" />
<t t-set="account_balance" t-value="0.0" />
<div class="act_as_caption account_title">
<span t-esc="account.code"/> - <span
t-esc="account.name"/>
</div>
<!-- Group by partner -->
<t t-foreach="docs.read_group([('id', 'in', docs.ids), ('account_id', '=', account.id)],['partner_id'],['partner_id'])" t-as="part">
<t t-set="partner"
t-value="partner_obj.browse(part['partner_id'][0])"/>
<t t-set="partner_debit" t-value="0.0" />
<t t-set="partner_credit" t-value="0.0" />
<t t-set="partner_balance" t-value="0.0" />
<div class="act_as_caption account_title">
<span t-esc="partner.name"/>
</div>
<!-- Group by currency -->
<t t-foreach="docs.read_group([('id', 'in', docs.ids), ('account_id', '=', account.id), ('partner_id', '=', partner.id)],['currency_id'],['currency_id'])" t-as="curr">
<t t-set="currency_id" t-value="False" />
<t t-if="curr['currency_id']">
<t t-set="currency"
t-value="currency_obj.browse(curr['currency_id'][0])"/>
<t t-set="currency_id"
t-value="currency.id"/>
</t>
<t t-set="currency_debit" t-value="0.0" />
<t t-set="currency_credit" t-value="0.0" />
<t t-set="currency_balance" t-value="0.0" />
<t t-set="currency_amount_balance" t-value="0.0"/>
<t t-if="currency_id">
<div class="act_as_caption account_title">
<span t-esc="currency.name"/>
</div>
</t>
<div class="act_as_table data_table">
<div class="act_as_thead">
<div class="act_as_row labels">
<div class="act_as_cell first_column">Date</div>
<div class="act_as_cell">Entry</div>
<div class="act_as_cell">Journal</div>
<div class="act_as_cell">Partner</div>
<div class="act_as_cell">Reference</div>
<div class="act_as_cell">Label</div>
<div class="act_as_cell">Due Date</div>
<div class="act_as_cell">Debit</div>
<div class="act_as_cell">Credit</div>
<div class="act_as_cell">Cum. Balance</div>
<t t-if="curr['currency_id']">
<div class="act_as_cell">Curr. amount</div>
<div class="act_as_cell">Cum. Curr. Bal.</div>
</t>
</div>
</div>
<div class="act_as_tbody">
<t t-set="moves" t-value="docs.search(
[('id', 'in', docs.ids),
('account_id', '=', account.id),
('partner_id', '=', partner.id),
('currency_id', '=', currency_id)])"/>
<t t-foreach="moves" t-as="move">
<div class="act_as_row">
<div class="act_as_cell first_column"><span t-esc="move.date"/></div>
<div
class="act_as_cell"><span t-esc="move.move_id.name"/></div>
<div class="act_as_cell"><span t-esc="move.journal_id.code"/></div>
<div class="act_as_cell"><span t-esc="partner.name"/></div>
<div class="act_as_cell"><span
t-esc="move.ref"/></div>
<div class="act_as_cell"><span
t-esc="move.name"/>
<t t-if="move.invoice_id"> - <span t-esc="move.invoice_id.number"/></t>
</div>
<div class="act_as_cell"><span t-esc="move.date_maturity"/></div>
<t t-set="account_debit" t-value="account_debit + move.debit" />
<t t-set="account_credit" t-value="account_credit + move.credit" />
<t t-set="account_balance" t-value="account_balance - move.credit + move.debit" />
<t t-set="partner_debit" t-value="partner_debit + move.debit" />
<t t-set="partner_credit" t-value="partner_credit + move.credit" />
<t t-set="partner_balance" t-value="partner_balance - move.credit + move.debit" />
<t t-set="currency_balance" t-value="currency_balance + move.amount_currency" />
<div class="act_as_cell amount"><span t-esc="move.debit"/></div>
<div class="act_as_cell amount"><span t-esc="move.credit"/></div>
<div class="act_as_cell amount"><span t-esc="partner_balance"/></div>
<t t-if="currency_id">
<div class="act_as_cell amount"><span t-esc="move.amount_currency"/></div>
<div class="act_as_cell amount"><span t-esc="currency_balance"/></div>
</t>
</div>
</t>
</div>
<t t-foreach="o.account_ids" t-as="account">
<div class="page_break">
<div class="act_as_table list_table" style="margin-top: 10px;"/>
<div class="act_as_caption account_title" style="width: 1141px !important;">
<span t-field="account.code"/> - <span t-field="account.name"/>
</div>
<t t-if="currency_id">
<div class="act_as_table totals_table">
<div class="act_as_row">
<div class="act_as_cell first_column"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell account_title"><span t-esc="currency.name"/> Total</div>
<div class="act_as_cell amount"><strong><span t-esc="currency_balance" /></strong></div>
<t t-foreach="account.partner_ids" t-as="partner">
<div class="page_break">
<div class="act_as_caption account_title">
<span t-field="partner.name"/>
</div>
<t t-call="account_financial_report_qweb.report_open_invoice_qweb_lines"/>
<t t-call="account_financial_report_qweb.report_open_invoice_qweb_ending_cumul">
<t t-set="account_or_partner_object" t-value="partner"/>
<t t-set="type" t-value='"partner_type"'/>
</t>
</div>
</t>
</t>
<div class="act_as_table totals_table">
<div class="act_as_row">
<div class="act_as_cell first_column"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell account_title"><span t-esc="partner.name"/> Total</div>
<div class="act_as_cell amount"><strong><span t-esc="partner_debit" /></strong></div>
<div class="act_as_cell amount"><strong><span t-esc="partner_credit" /></strong></div>
<div class="act_as_cell amount"><strong><span t-esc="partner_balance" /></strong></div>
</div>
<t t-call="account_financial_report_qweb.report_open_invoice_qweb_ending_cumul">
<t t-set="account_or_partner_object" t-value="account"/>
<t t-set="type" t-value='"account_type"'/>
</t>
</div>
</t>
<div class="act_as_table totals_table">
<div class="act_as_row">
<div class="act_as_cell first_column"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell"/>
<div class="act_as_cell account_title"><span t-esc="account.name"/> Total</div>
<div class="act_as_cell amount"><span t-esc="account_debit" /></div>
<div class="act_as_cell amount"><span t-esc="account_credit" /></div>
<div class="act_as_cell amount"><span t-esc="account_balance" /></div>
</div>
</div>
</div>
</t>
</t>
</t>
</template>
<template id="account_financial_report_qweb.report_open_invoice_qweb_lines">
<div class="act_as_table data_table" style="width: 1140px !important;">
<div class="act_as_thead">
<div class="act_as_row labels">
<!--## date-->
<div class="act_as_cell first_column" style="width: 60px;">Date</div>
<!--## move-->
<div class="act_as_cell" style="width: 100px;">Entry</div>
<!--## journal-->
<div class="act_as_cell" style="width: 40px;">Journal</div>
<!--## account code-->
<div class="act_as_cell" style="width: 50px;">Account</div>
<!--## partner-->
<div class="act_as_cell" style="width: 140px;">Partner</div>
<!--## ref - label-->
<div class="act_as_cell" style="width: 290px;">Ref - Label</div>
<!--## date_due-->
<div class="act_as_cell" style="width: 60px;">Due date</div>
<!--## amount_total_due-->
<div class="act_as_cell" style="width: 75px;">Original</div>
<!--## amount_residual-->
<div class="act_as_cell" style="width: 75px;">Residual</div>
<t t-if="has_second_currency">
<!--## currency_name-->
<div class="act_as_cell" style="width: 35px;">Cur.</div>
<!--## amount_total_due_currency-->
<div class="act_as_cell amount" style="width: 75px;">Cur. Original</div>
<!--## amount_residual_currency-->
<div class="act_as_cell amount" style="width: 75px;">Cur. Residual</div>
</t>
</div>
</div>
<t t-foreach="partner.move_line_ids" t-as="line">
<!-- # lines or centralized lines -->
<div class="act_as_row lines">
<!--## date-->
<div class="act_as_cell left"><span t-field="line.date"/></div>
<!--## move-->
<div class="act_as_cell left"><span t-field="line.entry"/></div>
<!--## journal-->
<div class="act_as_cell left"><span t-field="line.journal"/></div>
<!--## account code-->
<div class="act_as_cell left"><span t-field="line.account"/></div>
<!--## partner-->
<div class="act_as_cell left"><span t-field="line.partner"/></div>
<!--## ref - label-->
<div class="act_as_cell left"><span t-field="line.label"/></div>
<!--## date_due-->
<div class="act_as_cell left"><span t-field="line.date_due"/></div>
<!--## amount_total_due-->
<div class="act_as_cell amount"><span t-field="line.amount_total_due"/></div>
<!--## amount_residual-->
<div class="act_as_cell amount"><span t-field="line.amount_residual"/></div>
<t t-if="has_second_currency">
<!--## currency_name-->
<div class="act_as_cell"><span t-field="line.currency_name"/></div>
<t t-if="line.currency_name">
<!--## amount_total_due_currency-->
<div class="act_as_cell amount"><span t-field="line.amount_total_due_currency"/></div>
<!--## amount_residual_currency-->
<div class="act_as_cell amount"><span t-field="line.amount_residual_currency"/></div>
</t>
<t t-if="not line.currency_name">
<!--## amount_total_due_currency-->
<div class="act_as_cell"></div>
<!--## amount_residual_currency-->
<div class="act_as_cell"></div>
</t>
</t>
</div>
</t>
</t>
</div>
</template>
<template id="account_financial_report_qweb.report_open_invoice_qweb_ending_cumul">
<div class="act_as_table list_table" style="width: 1141px !important;">
<div class="act_as_row labels" style="font-weight: bold;">
<!--## date-->
<t t-if='type == "account_type"'>
<div class="act_as_cell first_column" style="width: 380px;"><span t-field="account_or_partner_object.code"/> - <span t-field="account_or_partner_object.name"/></div>
<div class="act_as_cell right" style="width: 290px;">Ending balance</div>
</t>
<t t-if='type == "partner_type"'>
<div class="act_as_cell first_column" style="width: 380px;"></div>
<div class="act_as_cell right" style="width: 290px;">Partner ending balance</div>
</t>
<!--## date_due-->
<div class="act_as_cell" style="width: 60px;"></div>
<!--## amount_total_due-->
<div class="act_as_cell amount" style="width: 75px;"></div>
<!--## amount_currency-->
<div class="act_as_cell amount" style="width: 75px;"><span t-field="account_or_partner_object.final_amount_residual"/></div>
<t t-if="has_second_currency">
<!--## currency_name + amount_total_due_currency + amount_residual_currency -->
<div class="act_as_cell" style="width: 185px;"></div>
</t>
</div>
</div>
</template>
</data>
</openerp>
</odoo>

34
account_financial_report_qweb/reports.xml

@ -11,30 +11,14 @@
file="account_financial_report_qweb.report_general_ledger_qweb"
/>
<!--PaperFormat A4 internal open invoice-->
<record id="open_invoice_report_format_a4_horizontal" model="report.paperformat">
<field name="name">Open Invoice Report Internal A4 Horizontal</field>
<field name="margin_top">30</field>
<field name="margin_bottom">20</field>
<field name="header_spacing">20</field>
<field name="orientation">Landscape</field>
</record>
<!--report open invoice-->
<report
string="Open Invoice Report"
id="report_open_invoice_report"
model="open.invoice.wizard"
report_type="qweb-pdf"
name="account_financial_report_qweb.open_invoice_report_qweb"
file="account_financial_report_qweb.open_invoice_report_qweb"/>
<record id="report_open_invoice_report" model="ir.actions.report.xml">
<field name="paperformat_id" ref="account_financial_report_qweb.open_invoice_report_format_a4_horizontal"/>
</record>
id="action_report_open_invoice_qweb"
model="report_open_invoice_qweb"
string="Open Invoice"
report_type="qweb-pdf"
name="account_financial_report_qweb.report_open_invoice_qweb"
file="account_financial_report_qweb.report_open_invoice_qweb"
/>
<record id="general_ledger_xls_export" model="ir.actions.report.xml">
<field name="name">General Ledger XLSX report</field>
@ -65,5 +49,9 @@
<field name="paperformat_id" ref="report_qweb_paperformat"/>
</record>
<record id="action_report_open_invoice_qweb" model="ir.actions.report.xml">
<field name="paperformat_id" ref="report_qweb_paperformat"/>
</record>
</data>
</openerp>

123
account_financial_report_qweb/wizard/open_invoice_wizard.py

@ -1,72 +1,81 @@
# -*- coding: utf-8 -*-
# Author: Andrea andrea4ever Gallina
# Author: Francesco OpenCode Apruzzese
# Author: Ciro CiroBoxHub Urselli
# Author: Damien Crier
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields, api
from datetime import datetime
from openerp import models, fields, api
class OpenInvoiceWizard(models.TransientModel):
class OpenInvoiceReportWizard(models.TransientModel):
"""Open invoice report wizard."""
_name = 'open.invoice.wizard'
_name = "open.invoice.report.wizard"
_description = "Open Invoice Report Wizard"
company_id = fields.Many2one(
'res.company', required=True,
default=lambda s: s.env.user.company_id)
at_date = fields.Date(
required=True,
default=fields.Date.to_string(datetime.today()))
comodel_name='res.company',
default=lambda self: self.env.user.company_id
)
date_at = fields.Date(required=True,
default=fields.Date.to_string(datetime.today()))
target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries')],
string='Target Moves',
required=True,
default='all')
account_ids = fields.Many2many(
comodel_name='account.account',
string='Filter accounts',
)
hide_account_balance_at_0 = fields.Boolean(
string='Hide account ending balance at 0',
help='Use this filter to hide an account or a partner '
'with an ending balance at 0. '
'If partners are filtered, '
'debits and credits totals will not match the trial balance.',
default=False)
receivable_accounts_only = fields.Boolean()
payable_accounts_only = fields.Boolean()
partner_ids = fields.Many2many(
'res.partner', string='Filter partners')
result_selection = fields.Selection([
('customer', 'Receivable Accounts'),
('supplier', 'Payable Accounts'),
('customer_supplier', 'Receivable and Payable Accounts')],
"Partner's", required=True, default='customer')
target_move = fields.Selection([
('posted', 'All Posted Entries'),
('all', 'All Entries')], 'Target Moves',
required=True, default='all')
@api.onchange('at_date')
def onchange_atdate(self):
self.until_date = self.at_date
def _build_contexts(self, data):
result = {}
return result
comodel_name='res.partner',
string='Filter partners',
)
def _build_header(self):
return {
'company': self.company_id.name,
'fiscal_year': '',
'at_date': self.at_date,
'account_filters': dict(
self._columns['result_selection'].selection)[
self.result_selection],
'target_moves': dict(
self._columns['target_move'].selection)[self.target_move],
}
@api.onchange('date_range_id')
def onchange_date_range_id(self):
"""Handle date range change."""
self.date_at = self.date_range_id.date_end
if self.date_range_id.date_start:
self.fy_start_date = self.env.user.company_id.find_daterange_fy(
fields.Date.from_string(self.date_range_id.date_start)
).date_start
def _get_form_fields(self):
return self.read(['company_id', 'at_date', 'partner_ids',
'result_selection', 'target_move',
'until_date'])[0]
@api.onchange('receivable_accounts_only', 'payable_accounts_only')
def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change."""
if self.receivable_accounts_only or self.payable_accounts_only:
domain = []
if self.receivable_accounts_only and self.payable_accounts_only:
domain += [('internal_type', 'in', ('receivable', 'payable'))]
elif self.receivable_accounts_only:
domain += [('internal_type', '=', 'receivable')]
elif self.payable_accounts_only:
domain += [('internal_type', '=', 'payable')]
self.account_ids = self.env['account.account'].search(domain)
else:
self.account_ids = None
@api.multi
def print_report(self):
self.ensure_one()
data = {}
data['ids'] = self.env.context.get('active_ids', [])
data['model'] = self.env.context.get('active_model', 'ir.ui.menu')
data['form'] = self._get_form_fields()
used_context = self._build_contexts(data)
data['form']['used_context'] = dict(
used_context, lang=self.env.context.get('lang', 'en_US'))
data['header'] = self._build_header()
return self.env['report'].get_action(
self, 'account_financial_report_qweb.open_invoice_report_qweb',
data=data)
def button_export_pdf(self):
model = self.env['report_open_invoice_qweb']
report = model.create({
'date_at': self.date_at,
'only_posted_moves': self.target_move == 'posted',
'hide_account_balance_at_0': self.hide_account_balance_at_0,
'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.account_ids.ids)],
'filter_partner_ids': [(6, 0, self.partner_ids.ids)],
})
return report.print_report()

47
account_financial_report_qweb/wizard/open_invoice_wizard_view.xml

@ -1,45 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<data>
<record id="open_invoice_report_wizard_view" model="ir.ui.view">
<!-- OPEN INVOICE -->
<record id="open_invoice_wizard" model="ir.ui.view">
<field name="name">Open Invoice</field>
<field name="model">open.invoice.wizard</field>
<field name="model">open.invoice.report.wizard</field>
<field name="arch" type="xml">
<form>
<group name="main_info">
<field name="company_id"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group name="date_info">
<field name="at_date"/>
<group name="filters">
<group name="date_ranger">
<field name="date_at"/>
</group>
<group name="other_filters">
<field name="target_move" widget="radio"/>
<field name="hide_account_balance_at_0"/>
</group>
</group>
<group name="partner_info">
<field name="partner_ids" />
</group>
<group name="layout_info">
<field name="result_selection" />
<field name="target_move" />
<label for="partner_ids"/>
<field name="partner_ids" nolabel="1"/>
<group/>
<label for="account_ids"/>
<group col="4">
<field name="receivable_accounts_only"/>
<field name="payable_accounts_only"/>
</group>
<field name="account_ids" nolabel="1"/>
<footer>
<button name="print_report"
string="Print Report"
type="object" class="oe_highlight"/>
<button name="button_export_pdf" string="Export PDF" type="object" default_focus="1" class="oe_highlight"/>
or
<button string="Cancel" special="cancel" />
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_open_invoice_report" model="ir.actions.act_window">
<record id="action_open_invoice_wizard" model="ir.actions.act_window">
<field name="name">Open Invoice</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">open.invoice.wizard</field>
<field name="res_model">open.invoice.report.wizard</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="open_invoice_report_wizard_view"/>
<field name="view_id" ref="open_invoice_wizard"/>
<field name="target">new</field>
</record>
</data>
</data>
</openerp>
Loading…
Cancel
Save