jcoux
9 years ago
committed by
Jordi Ballester
6 changed files with 922 additions and 346 deletions
-
9account_financial_report_qweb/menuitems.xml
-
720account_financial_report_qweb/report/open_invoice.py
-
309account_financial_report_qweb/report/templates/open_invoice_report.xml
-
32account_financial_report_qweb/reports.xml
-
121account_financial_report_qweb/wizard/open_invoice_wizard.py
-
41account_financial_report_qweb/wizard/open_invoice_wizard_view.xml
@ -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'], |
|||
|
|||
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]}, |
|||
} |
|||
|
|||
return report_obj.render( |
|||
'account_financial_report_qweb.open_invoice_report_qweb', |
|||
docargs) |
|||
@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) |
@ -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"> |
|||
<template id="account_financial_report_qweb.report_open_invoice_qweb"> |
|||
<t t-call="report.html_container"> |
|||
<t t-foreach="docs" t-as="o"> |
|||
<t t-set="has_second_currency" t-value="o.has_second_currency"/> |
|||
|
|||
<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> |
|||
<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">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 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 class="act_as_row"> |
|||
<div class="act_as_cell"> |
|||
<span t-field="o.date_at"/> |
|||
</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 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> |
|||
|
|||
<t t-call="report.html_container"> |
|||
<t t-call="report.internal_layout"> |
|||
<div class="page"> |
|||
|
|||
<!-- Generic information --> |
|||
<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">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> |
|||
<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> |
|||
<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> |
|||
<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 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> |
|||
|
|||
<!-- 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"> |
|||
</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"> |
|||
<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> |
|||
<!--## 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> |
|||
<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 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> |
|||
</div> |
|||
</t> |
|||
</div> |
|||
</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> |
|||
</div> |
|||
</div> |
|||
<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 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> |
|||
</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> |
|||
</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> |
|||
</div> |
|||
<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> |
@ -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, |
|||
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() |
Write
Preview
Loading…
Cancel
Save
Reference in new issue