jcoux
8 years ago
17 changed files with 1238 additions and 1031 deletions
-
7account_financial_report_qweb/__openerp__.py
-
11account_financial_report_qweb/menuitems.xml
-
1account_financial_report_qweb/report/__init__.py
-
101account_financial_report_qweb/report/common.py
-
894account_financial_report_qweb/report/general_ledger.py
-
344account_financial_report_qweb/report/templates/general_ledger.xml
-
38account_financial_report_qweb/report/templates/layouts.xml
-
26account_financial_report_qweb/reports.xml
-
20account_financial_report_qweb/static/src/css/report.css
-
17account_financial_report_qweb/view/account_view.xml
-
2account_financial_report_qweb/wizard/__init__.py
-
96account_financial_report_qweb/wizard/general_ledger_wizard.py
-
97account_financial_report_qweb/wizard/general_ledger_wizard.xml
-
60account_financial_report_qweb/wizard/general_ledger_wizard_view.xml
-
54account_financial_report_qweb/wizard/ledger.sql
-
337account_financial_report_qweb/wizard/ledger_report_wizard.py
-
54account_financial_report_qweb/wizard/partner_ledger_wizard.xml
@ -1,101 +0,0 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
# © 2015 Yannick Vaucher |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from openerp import models, fields, api |
|||
|
|||
|
|||
class FinancialReportLine(models.AbstractModel): |
|||
"""Rappresentation of a report line.""" |
|||
|
|||
_name = 'financial.report.line' |
|||
_description = "Financial report line" |
|||
|
|||
_order = 'account_id, date' |
|||
# TODO order by account_id.code |
|||
|
|||
name = fields.Char() |
|||
ref = fields.Char() |
|||
date = fields.Date() |
|||
month = fields.Char() |
|||
partner_name = fields.Char() |
|||
partner_ref = fields.Char() |
|||
account_id = fields.Many2one('account.account') |
|||
account_code = fields.Char() |
|||
journal_id = fields.Many2one('account.journal') |
|||
|
|||
currency_id = fields.Many2one('res.currency') |
|||
currency_code = fields.Char() |
|||
init_credit = fields.Float() |
|||
init_debit = fields.Float() |
|||
debit = fields.Float() |
|||
credit = fields.Float() |
|||
balance = fields.Float() |
|||
amount_currency = fields.Float() |
|||
|
|||
cumul_credit = fields.Float() |
|||
cumul_debit = fields.Float() |
|||
cumul_balance = fields.Float() |
|||
cumul_balance_curr = fields.Float() |
|||
|
|||
init_credit = fields.Float() |
|||
init_debit = fields.Float() |
|||
init_balance = fields.Float() |
|||
init_balance_curr = fields.Float() |
|||
|
|||
debit_centralized = fields.Float() |
|||
credit_centralized = fields.Float() |
|||
balance_centralized = fields.Float() |
|||
balance_curr_centralized = fields.Float() |
|||
|
|||
init_credit_centralized = fields.Float() |
|||
init_debit_centralized = fields.Float() |
|||
init_balance_centralized = fields.Float() |
|||
init_balance_curr_centralized = fields.Float() |
|||
|
|||
move_name = fields.Char() |
|||
move_state = fields.Char() |
|||
invoice_number = fields.Char() |
|||
|
|||
centralized = fields.Boolean() |
|||
|
|||
|
|||
class CommonFinancialReport(models.AbstractModel): |
|||
_name = 'account.report.common' |
|||
|
|||
start_date = fields.Date() |
|||
end_date = fields.Date() |
|||
|
|||
centralize = fields.Boolean() |
|||
target_move = fields.Char() |
|||
|
|||
filter = fields.Selection( |
|||
[('filter_no', 'No Filters'), |
|||
('filter_date', 'Date'), |
|||
('filter_opening', 'Opening Only')], |
|||
"Filter by", |
|||
required=False, |
|||
help='Filter by date: no opening balance will be displayed. ' |
|||
'(opening balance can only be computed based on period to be ' |
|||
'correct).' |
|||
) |
|||
|
|||
@api.multi |
|||
def _get_moves_from_dates_domain(self): |
|||
""" Prepare domain for `_get_moves_from_dates` """ |
|||
domain = [] |
|||
if self.centralize: |
|||
domain = [('centralized', '=', False)] |
|||
start_date = self.start_date |
|||
end_date = self.end_date |
|||
if start_date: |
|||
domain += [('date', '>=', start_date)] |
|||
if end_date: |
|||
domain += [('date', '<=', end_date)] |
|||
|
|||
if self.target_move == 'posted': |
|||
domain += [('move_state', '=', 'posted')] |
|||
|
|||
if self.account_ids: |
|||
domain += [('account_id', 'in', self.account_ids.ids)] |
|||
|
|||
return domain |
@ -1,130 +1,802 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# © 2015 Yannick Vaucher (Camptocamp) |
|||
# © 2016 Julien Coux (Camptocamp) |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from openerp import models, fields, api |
|||
|
|||
|
|||
class FinancialReportLine(models.Model): |
|||
_inherit = 'financial.report.line' |
|||
_name = 'general.ledger.line' |
|||
_description = "General Ledger report line" |
|||
class GeneralLedgerReport(models.TransientModel): |
|||
""" Here, we just define class fields. |
|||
For methods, go more bottom at this file. |
|||
""" |
|||
|
|||
_auto = False |
|||
_order = 'account_id, date' |
|||
_name = 'report_general_ledger_qweb' |
|||
|
|||
@api.depends('invoice_number', 'name') |
|||
def _get_label(self): |
|||
for rec in self: |
|||
label = rec.name |
|||
if rec.invoice_number: |
|||
label += u' ({})'.format(rec.invoice_number) |
|||
rec.label = label |
|||
date_from = fields.Date() |
|||
date_to = fields.Date() |
|||
fy_start_date = 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() |
|||
centralize = fields.Boolean() |
|||
show_cost_center = fields.Boolean( |
|||
default=lambda self: self.env.user.has_group( |
|||
'analytic.group_analytic_accounting' |
|||
) |
|||
) |
|||
|
|||
label = fields.Char(compute='_get_label', readonly=True, store=False) |
|||
account_ids = fields.One2many( |
|||
comodel_name='report_general_ledger_qweb_account', |
|||
inverse_name='report_id' |
|||
) |
|||
|
|||
|
|||
class GeneralLedgerReport(models.TransientModel): |
|||
class GeneralLedgerReportAccount(models.TransientModel): |
|||
|
|||
_name = 'report.account.report_generalledger_qweb' |
|||
_inherit = 'account.report.common' |
|||
_name = 'report_general_ledger_qweb_account' |
|||
_order = 'code ASC' |
|||
|
|||
@api.multi |
|||
def _get_account_ids(self): |
|||
res = False |
|||
context = self.env.context |
|||
if (context.get('active_model') == 'account.account' and |
|||
context.get('active_ids')): |
|||
res = context['active_ids'] |
|||
return res |
|||
report_id = fields.Many2one( |
|||
comodel_name='report_general_ledger_qweb', |
|||
ondelete='cascade', |
|||
index=True |
|||
) |
|||
account_id = fields.Many2one( |
|||
'account.account', |
|||
index=True |
|||
) |
|||
code = fields.Char() |
|||
name = fields.Char() |
|||
initial_debit = fields.Float(digits=(16, 2)) |
|||
initial_credit = fields.Float(digits=(16, 2)) |
|||
initial_balance = fields.Float(digits=(16, 2)) |
|||
final_debit = fields.Float(digits=(16, 2)) |
|||
final_credit = fields.Float(digits=(16, 2)) |
|||
final_balance = fields.Float(digits=(16, 2)) |
|||
is_partner_account = fields.Boolean() |
|||
|
|||
move_line_ids = fields.One2many( |
|||
comodel_name='report_general_ledger_qweb_move_line', |
|||
inverse_name='report_account_id' |
|||
) |
|||
partner_ids = fields.One2many( |
|||
comodel_name='report_general_ledger_qweb_partner', |
|||
inverse_name='report_account_id' |
|||
) |
|||
|
|||
|
|||
class GeneralLedgerReportPartner(models.TransientModel): |
|||
|
|||
_name = 'report_general_ledger_qweb_partner' |
|||
|
|||
report_account_id = fields.Many2one( |
|||
comodel_name='report_general_ledger_qweb_account', |
|||
ondelete='cascade', |
|||
index=True |
|||
) |
|||
partner_id = fields.Many2one( |
|||
'res.partner', |
|||
index=True |
|||
) |
|||
name = fields.Char() |
|||
initial_balance = fields.Integer() |
|||
account_ids = fields.Many2many( |
|||
'account.account', |
|||
string='Filter on accounts', |
|||
default=_get_account_ids, |
|||
help="Only selected accounts will be printed. Leave empty to " |
|||
"print all accounts.") |
|||
journal_ids = fields.Many2many( |
|||
'account.journal', |
|||
string='Filter on jourvals', |
|||
help="Only selected journals will be printed. Leave empty to " |
|||
"print all journals.") |
|||
balance_mode = fields.Selection( |
|||
[('initial_balance', 'Initial balance'), |
|||
('opening_balance', 'Opening balance')] |
|||
) |
|||
display_account = fields.Char() |
|||
display_ledger_lines = fields.Boolean() |
|||
display_initial_balance = fields.Boolean() |
|||
|
|||
MAPPING = { |
|||
'date_from': 'start_date', |
|||
'date_to': 'end_date', |
|||
initial_debit = fields.Float(digits=(16, 2)) |
|||
initial_credit = fields.Float(digits=(16, 2)) |
|||
initial_balance = fields.Float(digits=(16, 2)) |
|||
final_debit = fields.Float(digits=(16, 2)) |
|||
final_credit = fields.Float(digits=(16, 2)) |
|||
final_balance = fields.Float(digits=(16, 2)) |
|||
|
|||
move_line_ids = fields.One2many( |
|||
comodel_name='report_general_ledger_qweb_move_line', |
|||
inverse_name='report_partner_id' |
|||
) |
|||
|
|||
@api.model |
|||
def _generate_order_by(self, order_spec, query): |
|||
return """ |
|||
ORDER BY |
|||
CASE |
|||
WHEN "report_general_ledger_qweb_partner"."partner_id" IS NOT NULL |
|||
THEN 0 |
|||
ELSE 1 |
|||
END, |
|||
"report_general_ledger_qweb_partner"."name" |
|||
""" |
|||
|
|||
|
|||
class GeneralLedgerReportMoveLine(models.TransientModel): |
|||
|
|||
_name = 'report_general_ledger_qweb_move_line' |
|||
|
|||
report_account_id = fields.Many2one( |
|||
comodel_name='report_general_ledger_qweb_account', |
|||
ondelete='cascade', |
|||
index=True |
|||
) |
|||
report_partner_id = fields.Many2one( |
|||
comodel_name='report_general_ledger_qweb_partner', |
|||
ondelete='cascade', |
|||
index=True |
|||
) |
|||
move_line_id = fields.Many2one('account.move.line') |
|||
date = fields.Date() |
|||
entry = fields.Char() |
|||
journal = fields.Char() |
|||
account = fields.Char() |
|||
partner = fields.Char() |
|||
label = fields.Char() |
|||
cost_center = fields.Char() |
|||
matching_number = fields.Char() |
|||
debit = fields.Float(digits=(16, 2)) |
|||
credit = fields.Float(digits=(16, 2)) |
|||
cumul_balance = fields.Float(digits=(16, 2)) |
|||
currency_name = fields.Char() |
|||
amount_currency = fields.Float(digits=(16, 2)) |
|||
|
|||
|
|||
class GeneralLedgerReportCompute(models.TransientModel): |
|||
|
|||
_inherit = 'report_general_ledger_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_general_ledger_qweb', |
|||
'datas': {'ids': [self.id]}, |
|||
} |
|||
|
|||
@api.model |
|||
def _get_values_from_wizard(self, data): |
|||
""" Get values from wizard """ |
|||
values = {} |
|||
for key, val in data.iteritems(): |
|||
if key in self.MAPPING: |
|||
values[self.MAPPING[key]] = val |
|||
elif key == 'journal_ids': |
|||
if val: |
|||
values[key] = [(6, 0, val)] |
|||
else: |
|||
values[key] = val |
|||
return values |
|||
|
|||
@api.multi |
|||
def _get_centralized_move_ids(self, domain): |
|||
""" Get last line of each selected centralized accounts """ |
|||
# inverse search on centralized boolean to finish the search to get the |
|||
# ids of last lines of centralized accounts |
|||
# XXX USE DISTINCT to speed up ? |
|||
domain = domain[:] |
|||
centralize_index = domain.index(('centralized', '=', False)) |
|||
domain[centralize_index] = ('centralized', '=', True) |
|||
|
|||
gl_lines = self.env['general.ledger.line'].search(domain) |
|||
accounts = gl_lines.mapped('account_id') |
|||
|
|||
line_ids = [] |
|||
for acc in accounts: |
|||
acc_lines = gl_lines.filtered(lambda rec: rec.account_id == acc) |
|||
line_ids.append(acc_lines[-1].id) |
|||
return line_ids |
|||
|
|||
@api.multi |
|||
def _get_moves_from_dates(self): |
|||
domain = self._get_moves_from_dates_domain() |
|||
def compute_data_for_report(self): |
|||
self.ensure_one() |
|||
|
|||
self.inject_account_values() |
|||
self.inject_partner_values() |
|||
self.inject_line_not_centralized_values() |
|||
self.inject_line_not_centralized_values(is_account_line=False, |
|||
is_partner_line=True) |
|||
self.inject_line_not_centralized_values(is_account_line=False, |
|||
is_partner_line=True, |
|||
only_empty_partner_line=True) |
|||
if self.centralize: |
|||
centralized_ids = self._get_centralized_move_ids(domain) |
|||
if centralized_ids: |
|||
domain.insert(0, '|') |
|||
domain.append(('id', 'in', centralized_ids)) |
|||
return self.env['general.ledger.line'].search(domain) |
|||
|
|||
@api.multi |
|||
def render_html(self, data=None): |
|||
report_name = 'account.report_generalledger_qweb' |
|||
if data is None: |
|||
return |
|||
values = self._get_values_from_wizard(data['form']) |
|||
report = self.create(values) |
|||
|
|||
report_lines = report._get_moves_from_dates() |
|||
# TODO warning if no report_lines |
|||
self.env['report']._get_report_from_name(report_name) |
|||
|
|||
docargs = { |
|||
'doc_ids': report.ids, |
|||
'doc_model': self._name, |
|||
'report_lines': report_lines, |
|||
'docs': report, |
|||
# XXX |
|||
'has_currency': True |
|||
} |
|||
return self.env['report'].render(report_name, docargs) |
|||
self.inject_line_centralized_values() |
|||
self.compute_has_second_currency() |
|||
|
|||
def inject_account_values(self): |
|||
subquery_sum_amounts = """ |
|||
SELECT |
|||
a.id AS account_id, |
|||
SUM(ml.debit) AS debit, |
|||
SUM(ml.credit) AS credit, |
|||
SUM(ml.balance) AS balance |
|||
FROM |
|||
accounts a |
|||
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 |
|||
AND |
|||
( |
|||
at.include_initial_balance != TRUE AND ml.date >= %s |
|||
OR at.include_initial_balance = TRUE |
|||
) |
|||
""" |
|||
if self.only_posted_moves: |
|||
subquery_sum_amounts += """ |
|||
INNER JOIN |
|||
account_move m ON ml.move_id = m.id AND m.state = 'posted' |
|||
""" |
|||
subquery_sum_amounts += """ |
|||
GROUP BY |
|||
a.id |
|||
""" |
|||
query_inject_account = """ |
|||
WITH |
|||
accounts AS |
|||
( |
|||
SELECT |
|||
a.id, |
|||
a.code, |
|||
a.name, |
|||
a.internal_type IN ('payable', 'receivable') |
|||
AS is_partner_account, |
|||
a.user_type_id |
|||
FROM |
|||
account_account a |
|||
""" |
|||
if self.filter_partner_ids: |
|||
query_inject_account += """ |
|||
INNER JOIN |
|||
account_move_line ml ON a.id = ml.account_id |
|||
INNER JOIN |
|||
res_partner p ON ml.partner_id = p.id |
|||
""" |
|||
query_inject_account += """ |
|||
WHERE |
|||
a.company_id = %s |
|||
""" |
|||
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 |
|||
GROUP BY |
|||
a.id |
|||
""" |
|||
query_inject_account += """ |
|||
), |
|||
initial_sum_amounts AS ( """ + subquery_sum_amounts + """ ), |
|||
final_sum_amounts AS ( """ + subquery_sum_amounts + """ ) |
|||
INSERT INTO |
|||
report_general_ledger_qweb_account |
|||
( |
|||
report_id, |
|||
create_uid, |
|||
create_date, |
|||
account_id, |
|||
code, |
|||
name, |
|||
initial_debit, |
|||
initial_credit, |
|||
initial_balance, |
|||
final_debit, |
|||
final_credit, |
|||
final_balance, |
|||
is_partner_account |
|||
) |
|||
SELECT |
|||
%s AS report_id, |
|||
%s AS create_uid, |
|||
NOW() AS create_date, |
|||
a.id AS account_id, |
|||
a.code, |
|||
a.name, |
|||
COALESCE(i.debit, 0.0) AS initial_debit, |
|||
COALESCE(i.credit, 0.0) AS initial_credit, |
|||
COALESCE(i.balance, 0.0) AS initial_balance, |
|||
COALESCE(f.debit, 0.0) AS final_debit, |
|||
COALESCE(f.credit, 0.0) AS final_credit, |
|||
COALESCE(f.balance, 0.0) AS final_balance, |
|||
a.is_partner_account |
|||
FROM |
|||
accounts a |
|||
LEFT JOIN |
|||
initial_sum_amounts i ON a.id = i.account_id |
|||
LEFT JOIN |
|||
final_sum_amounts f ON a.id = f.account_id |
|||
WHERE |
|||
( |
|||
i.debit IS NOT NULL AND i.debit != 0 |
|||
OR i.credit IS NOT NULL AND i.credit != 0 |
|||
OR i.balance IS NOT NULL AND i.balance != 0 |
|||
OR f.debit IS NOT NULL AND f.debit != 0 |
|||
OR f.credit IS NOT NULL AND f.credit != 0 |
|||
OR f.balance IS NOT NULL AND f.balance != 0 |
|||
) |
|||
""" |
|||
if self.hide_account_balance_at_0: |
|||
query_inject_account += """ |
|||
AND |
|||
f.balance IS NOT NULL AND f.balance != 0 |
|||
""" |
|||
query_inject_account_params = ( |
|||
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.date_from, |
|||
self.fy_start_date, |
|||
self.date_to, |
|||
self.fy_start_date, |
|||
self.id, |
|||
self.env.uid, |
|||
) |
|||
self.env.cr.execute(query_inject_account, query_inject_account_params) |
|||
|
|||
def inject_partner_values(self): |
|||
subquery_sum_amounts = """ |
|||
SELECT |
|||
ap.account_id AS account_id, |
|||
ap.partner_id AS partner_id, |
|||
SUM(ml.debit) AS debit, |
|||
SUM(ml.credit) AS credit, |
|||
SUM(ml.balance) AS balance |
|||
FROM |
|||
accounts_partners ap |
|||
INNER JOIN |
|||
account_move_line ml |
|||
ON ap.account_id = ml.account_id |
|||
AND ( |
|||
ap.partner_id = ml.partner_id |
|||
OR ap.partner_id IS NULL AND ml.partner_id IS NULL |
|||
) |
|||
AND ml.date <= %s |
|||
AND ( |
|||
ap.include_initial_balance != TRUE AND ml.date >= %s |
|||
OR ap.include_initial_balance = TRUE |
|||
) |
|||
""" |
|||
if self.only_posted_moves: |
|||
subquery_sum_amounts += """ |
|||
INNER JOIN |
|||
account_move m ON ml.move_id = m.id AND m.state = 'posted' |
|||
""" |
|||
subquery_sum_amounts += """ |
|||
GROUP BY |
|||
ap.account_id, ap.partner_id |
|||
""" |
|||
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_general_ledger_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 |
|||
LEFT JOIN |
|||
res_partner p ON ml.partner_id = p.id |
|||
WHERE |
|||
ra.report_id = %s |
|||
AND |
|||
ra.is_partner_account = TRUE |
|||
""" |
|||
if self.centralize: |
|||
query_inject_partner += """ |
|||
AND |
|||
(a.centralized IS NULL OR a.centralized != TRUE) |
|||
""" |
|||
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 |
|||
), |
|||
initial_sum_amounts AS ( """ + subquery_sum_amounts + """ ), |
|||
final_sum_amounts AS ( """ + subquery_sum_amounts + """ ) |
|||
INSERT INTO |
|||
report_general_ledger_qweb_partner |
|||
( |
|||
report_account_id, |
|||
create_uid, |
|||
create_date, |
|||
partner_id, |
|||
name, |
|||
initial_debit, |
|||
initial_credit, |
|||
initial_balance, |
|||
final_debit, |
|||
final_credit, |
|||
final_balance |
|||
) |
|||
SELECT |
|||
ap.report_account_id, |
|||
%s AS create_uid, |
|||
NOW() AS create_date, |
|||
ap.partner_id, |
|||
ap.partner_name, |
|||
COALESCE(i.debit, 0.0) AS initial_debit, |
|||
COALESCE(i.credit, 0.0) AS initial_credit, |
|||
COALESCE(i.balance, 0.0) AS initial_balance, |
|||
COALESCE(f.debit, 0.0) AS final_debit, |
|||
COALESCE(f.credit, 0.0) AS final_credit, |
|||
COALESCE(f.balance, 0.0) AS final_balance |
|||
FROM |
|||
accounts_partners ap |
|||
LEFT JOIN |
|||
initial_sum_amounts i |
|||
ON |
|||
( |
|||
ap.partner_id = i.partner_id |
|||
OR ap.partner_id IS NULL AND i.partner_id IS NULL |
|||
) |
|||
AND ap.account_id = i.account_id |
|||
LEFT JOIN |
|||
final_sum_amounts f |
|||
ON |
|||
( |
|||
ap.partner_id = f.partner_id |
|||
OR ap.partner_id IS NULL AND f.partner_id IS NULL |
|||
) |
|||
AND ap.account_id = f.account_id |
|||
WHERE |
|||
( |
|||
i.debit IS NOT NULL AND i.debit != 0 |
|||
OR i.credit IS NOT NULL AND i.credit != 0 |
|||
OR i.balance IS NOT NULL AND i.balance != 0 |
|||
OR f.debit IS NOT NULL AND f.debit != 0 |
|||
OR f.credit IS NOT NULL AND f.credit != 0 |
|||
OR f.balance IS NOT NULL AND f.balance != 0 |
|||
) |
|||
""" |
|||
if self.hide_account_balance_at_0: |
|||
query_inject_partner += """ |
|||
AND |
|||
f.balance IS NOT NULL AND f.balance != 0 |
|||
""" |
|||
query_inject_partner_params = ( |
|||
self.id, |
|||
) |
|||
if self.filter_partner_ids: |
|||
query_inject_partner_params += ( |
|||
tuple(self.filter_partner_ids.ids), |
|||
) |
|||
query_inject_partner_params += ( |
|||
self.date_from, |
|||
self.fy_start_date, |
|||
self.date_to, |
|||
self.fy_start_date, |
|||
self.env.uid, |
|||
) |
|||
print query_inject_partner_params |
|||
self.env.cr.execute(query_inject_partner, query_inject_partner_params) |
|||
|
|||
def inject_line_not_centralized_values(self, |
|||
is_account_line=True, |
|||
is_partner_line=False, |
|||
only_empty_partner_line=False): |
|||
query_inject_move_line = """ |
|||
INSERT INTO |
|||
report_general_ledger_qweb_move_line |
|||
( |
|||
""" |
|||
if is_account_line: |
|||
query_inject_move_line += """ |
|||
report_account_id, |
|||
""" |
|||
elif is_partner_line: |
|||
query_inject_move_line += """ |
|||
report_partner_id, |
|||
""" |
|||
query_inject_move_line += """ |
|||
create_uid, |
|||
create_date, |
|||
move_line_id, |
|||
date, |
|||
entry, |
|||
journal, |
|||
account, |
|||
partner, |
|||
label, |
|||
cost_center, |
|||
matching_number, |
|||
debit, |
|||
credit, |
|||
cumul_balance, |
|||
currency_name, |
|||
amount_currency |
|||
) |
|||
SELECT |
|||
""" |
|||
if is_account_line: |
|||
query_inject_move_line += """ |
|||
ra.id AS report_account_id, |
|||
""" |
|||
elif is_partner_line: |
|||
query_inject_move_line += """ |
|||
rp.id AS report_partner_id, |
|||
""" |
|||
query_inject_move_line += """ |
|||
%s AS create_uid, |
|||
NOW() AS create_date, |
|||
ml.id AS move_line_id, |
|||
ml.date, |
|||
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, |
|||
aa.name AS cost_center, |
|||
fr.name AS matching_number, |
|||
ml.debit, |
|||
ml.credit, |
|||
""" |
|||
if is_account_line: |
|||
query_inject_move_line += """ |
|||
ra.initial_balance + ( |
|||
SUM(ml.balance) |
|||
OVER (PARTITION BY a.code |
|||
ORDER BY a.code, ml.date, ml.id) |
|||
) AS cumul_balance, |
|||
""" |
|||
elif is_partner_line and not only_empty_partner_line: |
|||
query_inject_move_line += """ |
|||
rp.initial_balance + ( |
|||
SUM(ml.balance) |
|||
OVER (PARTITION BY a.code, p.name |
|||
ORDER BY a.code, p.name, ml.date, ml.id) |
|||
) AS cumul_balance, |
|||
""" |
|||
elif is_partner_line and only_empty_partner_line: |
|||
query_inject_move_line += """ |
|||
rp.initial_balance + ( |
|||
SUM(ml.balance) |
|||
OVER (PARTITION BY a.code |
|||
ORDER BY a.code, ml.date, ml.id) |
|||
) AS cumul_balance, |
|||
""" |
|||
query_inject_move_line += """ |
|||
c.name AS currency_name, |
|||
ml.amount_currency |
|||
FROM |
|||
""" |
|||
if is_account_line: |
|||
query_inject_move_line += """ |
|||
report_general_ledger_qweb_account ra |
|||
""" |
|||
elif is_partner_line: |
|||
query_inject_move_line += """ |
|||
report_general_ledger_qweb_partner rp |
|||
INNER JOIN |
|||
report_general_ledger_qweb_account ra ON rp.report_account_id = ra.id |
|||
""" |
|||
query_inject_move_line += """ |
|||
INNER JOIN |
|||
account_move_line ml ON ra.account_id = ml.account_id |
|||
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 is_account_line: |
|||
query_inject_move_line += """ |
|||
LEFT JOIN |
|||
res_partner p ON ml.partner_id = p.id |
|||
""" |
|||
elif is_partner_line and 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 |
|||
LEFT JOIN |
|||
account_analytic_account aa ON ml.analytic_account_id = aa.id |
|||
WHERE |
|||
ra.report_id = %s |
|||
AND |
|||
""" |
|||
if is_account_line: |
|||
query_inject_move_line += """ |
|||
(ra.is_partner_account IS NULL OR ra.is_partner_account != TRUE) |
|||
""" |
|||
elif is_partner_line: |
|||
query_inject_move_line += """ |
|||
ra.is_partner_account = TRUE |
|||
""" |
|||
if self.centralize: |
|||
query_inject_move_line += """ |
|||
AND |
|||
(a.centralized IS NULL OR a.centralized != TRUE) |
|||
""" |
|||
query_inject_move_line += """ |
|||
AND |
|||
ml.date BETWEEN %s AND %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 is_account_line: |
|||
query_inject_move_line += """ |
|||
ORDER BY |
|||
a.code, ml.date, ml.id |
|||
""" |
|||
elif is_partner_line and not only_empty_partner_line: |
|||
query_inject_move_line += """ |
|||
ORDER BY |
|||
a.code, p.name, ml.date, ml.id |
|||
""" |
|||
elif is_partner_line and 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.env.uid, |
|||
self.id, |
|||
self.date_from, |
|||
self.date_to,) |
|||
) |
|||
|
|||
def inject_line_centralized_values(self): |
|||
query_inject_move_line_centralized = """ |
|||
WITH |
|||
move_lines AS |
|||
( |
|||
SELECT |
|||
ml.account_id, |
|||
( |
|||
DATE_TRUNC('month', ml.date) + interval '1 month' |
|||
- interval '1 day' |
|||
)::date AS date, |
|||
SUM(ml.debit) AS debit, |
|||
SUM(ml.credit) AS credit, |
|||
SUM(ml.balance) AS balance |
|||
FROM |
|||
report_general_ledger_qweb_account ra |
|||
INNER JOIN |
|||
account_move_line ml ON ra.account_id = ml.account_id |
|||
INNER JOIN |
|||
account_move m ON ml.move_id = m.id |
|||
INNER JOIN |
|||
account_account a ON ml.account_id = a.id |
|||
WHERE |
|||
ra.report_id = %s |
|||
AND |
|||
a.centralized = TRUE |
|||
AND |
|||
ml.date BETWEEN %s AND %s |
|||
""" |
|||
if self.only_posted_moves: |
|||
query_inject_move_line_centralized += """ |
|||
AND |
|||
m.state = 'posted' |
|||
""" |
|||
query_inject_move_line_centralized += """ |
|||
GROUP BY |
|||
ra.id, ml.account_id, a.code, 2 |
|||
) |
|||
INSERT INTO |
|||
report_general_ledger_qweb_move_line |
|||
( |
|||
report_account_id, |
|||
create_uid, |
|||
create_date, |
|||
date, |
|||
account, |
|||
label, |
|||
debit, |
|||
credit, |
|||
cumul_balance |
|||
) |
|||
SELECT |
|||
ra.id AS report_account_id, |
|||
%s AS create_uid, |
|||
NOW() AS create_date, |
|||
ml.date, |
|||
a.code AS account, |
|||
'Centralized Entries' AS label, |
|||
ml.debit AS debit, |
|||
ml.credit AS credit, |
|||
ra.initial_balance + ( |
|||
SUM(ml.balance) |
|||
OVER (PARTITION BY a.code ORDER BY ml.date) |
|||
) AS cumul_balance |
|||
FROM |
|||
report_general_ledger_qweb_account ra |
|||
INNER JOIN |
|||
move_lines ml ON ra.account_id = ml.account_id |
|||
INNER JOIN |
|||
account_account a ON ml.account_id = a.id |
|||
LEFT JOIN |
|||
res_currency c ON a.currency_id = c.id |
|||
WHERE |
|||
ra.report_id = %s |
|||
AND |
|||
(a.centralized IS NOT NULL AND a.centralized = TRUE) |
|||
ORDER BY |
|||
a.code, ml.date |
|||
""" |
|||
self.env.cr.execute( |
|||
query_inject_move_line_centralized, |
|||
(self.id, |
|||
self.date_from, |
|||
self.date_to, |
|||
self.env.uid, |
|||
self.id,) |
|||
) |
|||
|
|||
def compute_has_second_currency(self): |
|||
query_update_has_second_currency = """ |
|||
UPDATE |
|||
report_general_ledger_qweb |
|||
SET |
|||
has_second_currency = |
|||
( |
|||
SELECT |
|||
TRUE |
|||
FROM |
|||
report_general_ledger_qweb_move_line l |
|||
INNER JOIN |
|||
report_general_ledger_qweb_account a |
|||
ON l.report_account_id = a.id |
|||
WHERE |
|||
a.report_id = %s |
|||
AND l.currency_name IS NOT NULL |
|||
LIMIT 1 |
|||
) |
|||
OR |
|||
( |
|||
SELECT |
|||
TRUE |
|||
FROM |
|||
report_general_ledger_qweb_move_line l |
|||
INNER JOIN |
|||
report_general_ledger_qweb_partner p |
|||
ON l.report_partner_id = p.id |
|||
INNER JOIN |
|||
report_general_ledger_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,) * 3 |
|||
self.env.cr.execute(query_update_has_second_currency, params) |
@ -0,0 +1,38 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
|
|||
<template id="assets_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="account_financial_report_qweb.internal_layout"> |
|||
<div class="header"> |
|||
<div class="row"> |
|||
<div class="col-xs-6"> |
|||
<span t-esc="title"/> |
|||
</div> |
|||
<div class="col-xs-6 text-right"> |
|||
<span t-esc="company_name"/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<t t-raw="0" /> |
|||
<div class="footer"> |
|||
<div class="row"> |
|||
<div class="col-xs-6 custom_footer"> |
|||
<span t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d %H:%M')"/> |
|||
</div> |
|||
<div class="col-xs-6 text-right custom_footer"> |
|||
<ul class="list-inline"> |
|||
<li><span class="page"/></li> |
|||
<li>/</li> |
|||
<li><span class="topage"/></li> |
|||
</ul> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
</odoo> |
@ -0,0 +1,17 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
<record model="ir.ui.view" id="view_account_specific_form"> |
|||
<field name="name">account.account.form.inherit</field> |
|||
<field name="inherit_id" ref="account.view_account_form"/> |
|||
<field name="model">account.account</field> |
|||
<field name="type">form</field> |
|||
<field name="arch" type="xml"> |
|||
<field name="deprecated" position="after"> |
|||
<field name="centralized"/> |
|||
</field> |
|||
</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</openerp> |
@ -0,0 +1,96 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# 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 |
|||
|
|||
|
|||
class GeneralLedgerReportWizard(models.TransientModel): |
|||
"""General ledger report wizard.""" |
|||
|
|||
_name = "general.ledger.report.wizard" |
|||
_description = "General Ledger Report Wizard" |
|||
|
|||
company_id = fields.Many2one( |
|||
comodel_name='res.company', |
|||
default=lambda self: self.env.user.company_id |
|||
) |
|||
date_range_id = fields.Many2one(comodel_name='date.range', required=True) |
|||
date_from = fields.Date(required=True) |
|||
date_to = fields.Date(required=True) |
|||
fy_start_date = fields.Date(required=True) |
|||
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', |
|||
) |
|||
centralize = fields.Boolean(string='Activate centralization', |
|||
default=True) |
|||
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( |
|||
comodel_name='res.partner', |
|||
string='Filter partners', |
|||
) |
|||
|
|||
@api.onchange('date_range_id') |
|||
def onchange_date_range_id(self): |
|||
"""Handle date range change.""" |
|||
self.date_from = self.date_range_id.date_start |
|||
self.date_to = self.date_range_id.date_end |
|||
if self.date_from: |
|||
self.fy_start_date = self.env.user.company_id.find_daterange_fy( |
|||
fields.Date.from_string(self.date_range_id.date_start) |
|||
).date_start |
|||
|
|||
@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.onchange('partner_ids') |
|||
def onchange_partner_ids(self): |
|||
"""Handle partners change.""" |
|||
if self.partner_ids: |
|||
self.receivable_accounts_only = self.payable_accounts_only = True |
|||
else: |
|||
self.receivable_accounts_only = self.payable_accounts_only = False |
|||
|
|||
@api.multi |
|||
def button_export_pdf(self): |
|||
model = self.env['report_general_ledger_qweb'] |
|||
report = model.create({ |
|||
'date_from': self.date_from, |
|||
'date_to': self.date_to, |
|||
'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)], |
|||
'centralize': self.centralize, |
|||
'fy_start_date': self.fy_start_date, |
|||
}) |
|||
return report.print_report() |
@ -1,97 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
|
|||
<!-- GENERAL LEDGER --> |
|||
<record id="ledger_general_wizard" model="ir.ui.view"> |
|||
<field name="name">General Ledger</field> |
|||
<field name="model">ledger.report.wizard</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<group name="main_info"> |
|||
<field name="company_id"/> |
|||
</group> |
|||
<group name="date_currency_filter"> |
|||
<group name="date_ranger"> |
|||
<field name="date_range_id"/> |
|||
<field name="date_from"/> |
|||
<field name="date_to"/> |
|||
<field name="fy_start_date" invisible="1"/> |
|||
</group> |
|||
<group name="extra_info"> |
|||
<field name="amount_currency"/> |
|||
<field name="centralize"/> |
|||
</group> |
|||
</group> |
|||
<group name="other_filters"> |
|||
<group name="moves"> |
|||
<field name="target_move" widget="radio"/> |
|||
</group> |
|||
</group> |
|||
<label for="account_ids"/> |
|||
<field name="account_ids" nolabel="1"/> |
|||
<footer> |
|||
<button name="button_view" string="View" type="object" default_focus="1" class="oe_highlight"/> |
|||
or |
|||
<button name="check_report_xlsx" string="Export XLSX" type="object"/> |
|||
or |
|||
<button string="Cancel" class="oe_link" special="cancel" /> |
|||
</footer> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="ledger_report_wizard_line_tree_view" |
|||
model="ir.ui.view"> |
|||
<field name="name">General Ledger Line tree</field> |
|||
<field name="model">ledger.report.wizard.line</field> |
|||
<field name="type">tree</field> |
|||
<field name="arch" type="xml"> |
|||
<tree string="General Ledger"> |
|||
<field name="date"/> |
|||
<field name="account_id"/> |
|||
<field name="move_name"/> |
|||
<field name="init_balance"/> |
|||
<field name="debit"/> |
|||
<field name="credit"/> |
|||
<field name="cumul_balance"/> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="ledger_report_wizard_line_search_view" |
|||
model="ir.ui.view"> |
|||
<field name="name">General Ledger Line search</field> |
|||
<field name="model">ledger.report.wizard.line</field> |
|||
<field name="arch" type="xml"> |
|||
<search string="Line search"> |
|||
<group expand="1" string="Group By"> |
|||
<filter |
|||
name="group_by_account_id" |
|||
string="Account" |
|||
domain="[]" |
|||
context="{'group_by' : 'account_id'}" |
|||
/> |
|||
<filter |
|||
name="group_by_date" |
|||
string="Month" |
|||
domain="[]" |
|||
context="{'group_by' : 'date:month'}" |
|||
/> |
|||
</group> |
|||
</search> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="action_ledger_report_wizard" model="ir.actions.act_window"> |
|||
<field name="name">General Ledger</field> |
|||
<field name="type">ir.actions.act_window</field> |
|||
<field name="res_model">ledger.report.wizard</field> |
|||
<field name="view_type">form</field> |
|||
<field name="view_mode">form</field> |
|||
<field name="view_id" ref="ledger_general_wizard"/> |
|||
<field name="target">new</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</openerp> |
@ -0,0 +1,60 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
|
|||
<!-- GENERAL LEDGER --> |
|||
<record id="general_ledger_wizard" model="ir.ui.view"> |
|||
<field name="name">General Ledger</field> |
|||
<field name="model">general.ledger.report.wizard</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<group name="main_info"> |
|||
<field name="company_id" groups="base.group_multi_company"/> |
|||
</group> |
|||
<group name="filters"> |
|||
<group name="date_ranger"> |
|||
<field name="date_range_id" domain="[('company_id','=',company_id)]"/> |
|||
<field name="date_from"/> |
|||
<field name="date_to"/> |
|||
<field name="fy_start_date" invisible="1"/> |
|||
</group> |
|||
<group name="other_filters"> |
|||
<field name="target_move" widget="radio"/> |
|||
<field name="centralize"/> |
|||
<field name="hide_account_balance_at_0"/> |
|||
</group> |
|||
</group> |
|||
<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="button_export_pdf" string="Export PDF" type="object" default_focus="1" class="oe_highlight"/> |
|||
<!-- |
|||
or |
|||
<button name="check_report_xlsx" string="Export XLSX" type="object"/> |
|||
--> |
|||
or |
|||
<button string="Cancel" class="oe_link" special="cancel" /> |
|||
</footer> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="action_general_ledger_wizard" model="ir.actions.act_window"> |
|||
<field name="name">General Ledger</field> |
|||
<field name="type">ir.actions.act_window</field> |
|||
<field name="res_model">general.ledger.report.wizard</field> |
|||
<field name="view_type">form</field> |
|||
<field name="view_mode">form</field> |
|||
<field name="view_id" ref="general_ledger_wizard"/> |
|||
<field name="target">new</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</openerp> |
@ -1,54 +0,0 @@ |
|||
WITH view_q as ( |
|||
SELECT |
|||
ml.date, |
|||
acc.id AS account_id, |
|||
ml.debit, |
|||
ml.credit, |
|||
ml.name AS name, |
|||
ml.ref, |
|||
ml.journal_id, |
|||
ml.partner_id, |
|||
SUM(debit - credit) OVER w_account - (debit - credit) AS init_balance, |
|||
SUM(debit - credit) OVER w_account AS cumul_balance |
|||
FROM account_account AS acc |
|||
LEFT JOIN account_move_line AS ml ON (ml.account_id = acc.id) |
|||
INNER JOIN account_move AS m ON (ml.move_id = m.id) |
|||
INNER JOIN account_account_type aat ON (acc.user_type_id = aat.id) |
|||
WHERE ml.date >= %(fy_date)s OR aat.include_initial_balance IS TRUE |
|||
WINDOW w_account AS ( |
|||
PARTITION BY acc.code |
|||
ORDER BY ml.date, ml.id |
|||
) |
|||
ORDER BY acc.id, ml.date |
|||
) |
|||
INSERT INTO ledger_report_wizard_line ( |
|||
date, |
|||
name, |
|||
journal_id, |
|||
account_id, |
|||
partner_id, |
|||
ref, |
|||
label, |
|||
--counterpart |
|||
init_balance, |
|||
debit, |
|||
credit, |
|||
cumul_balance, |
|||
wizard_id |
|||
) |
|||
SELECT |
|||
date, |
|||
name, |
|||
journal_id, |
|||
account_id, |
|||
partner_id, |
|||
ref, |
|||
' TODO label ' AS label, |
|||
--counterpart |
|||
init_balance, |
|||
debit, |
|||
credit, |
|||
cumul_balance, |
|||
%(wizard_id)s AS wizard_id |
|||
FROM view_q |
|||
WHERE date BETWEEN %(date_from)s AND %(date_to)s; |
@ -1,337 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Author: Damien Crier |
|||
# Copyright 2016 Camptocamp SA |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
from operator import itemgetter |
|||
from pkg_resources import resource_string |
|||
|
|||
from openerp import models, fields, api, _ |
|||
|
|||
# order to be placed on the report: field |
|||
FIELDS_TO_READ = {1: 'date', |
|||
0: 'account_id', |
|||
4: 'account_code', |
|||
2: 'move_name', |
|||
3: 'journal_id', |
|||
5: 'partner_name', |
|||
6: 'ref', |
|||
7: 'label', |
|||
8: 'debit', |
|||
9: 'credit', |
|||
30: 'amount_currency', |
|||
40: 'currency_code', |
|||
50: 'month', |
|||
60: 'partner_ref', |
|||
10: 'cumul_balance', |
|||
70: 'init_balance', |
|||
} |
|||
|
|||
|
|||
class LedgerReportWizard(models.TransientModel): |
|||
"""Base ledger report wizard.""" |
|||
|
|||
_name = "ledger.report.wizard" |
|||
_description = "Ledger Report Wizard" |
|||
|
|||
company_id = fields.Many2one(comodel_name='res.company') |
|||
date_range_id = fields.Many2one(comodel_name='date.range', required=True) |
|||
date_from = fields.Date(required=True) |
|||
date_to = fields.Date(required=True) |
|||
fy_start_date = fields.Date(required=True) |
|||
target_move = fields.Selection([('posted', 'All Posted Entries'), |
|||
('all', 'All Entries')], |
|||
string='Target Moves', |
|||
required=True, |
|||
default='posted') |
|||
account_ids = fields.Many2many( |
|||
comodel_name='account.account', |
|||
string='Filter accounts', |
|||
) |
|||
amount_currency = fields.Boolean(string='With currency', |
|||
default=False) |
|||
centralize = fields.Boolean(string='Activate centralization', |
|||
default=False) |
|||
result_selection = fields.Selection( |
|||
[ |
|||
('customer', 'Receivable Accounts'), |
|||
('supplier', 'Payable Accounts'), |
|||
('customer_supplier', 'Receivable and Payable Accounts'), |
|||
], |
|||
string="Partner's", |
|||
default='customer') |
|||
partner_ids = fields.Many2many( |
|||
comodel_name='res.partner', |
|||
string='Filter partners', |
|||
) |
|||
line_ids = fields.One2many(comodel_name='ledger.report.wizard.line', |
|||
inverse_name='wizard_id') |
|||
|
|||
def _query(self): |
|||
"""Execute query. |
|||
|
|||
Short summary: |
|||
Prepare all lines for report |
|||
by calculating debit/credit amounts |
|||
plus the cumulative one. |
|||
|
|||
Narrow the search by using PG windows. |
|||
|
|||
Insert all the rows in `ledger_report_wizard_line` |
|||
at once, so that we have real model objects |
|||
and we can filter/group them in the tree view. |
|||
|
|||
""" |
|||
query = resource_string(__name__, 'ledger.sql') |
|||
params = dict(fy_date=self.fy_start_date, wizard_id=self.id, |
|||
date_from=self.date_from, date_to=self.date_to) |
|||
self.env.cr.execute(query, params) |
|||
return True |
|||
|
|||
@api.multi |
|||
def _print_report(self, data): |
|||
# we update form with display account value |
|||
data = self.pre_print_report(data) |
|||
Report = self.env['report'].with_context(landscape=True) |
|||
return Report.get_action( |
|||
self, 'account.report_generalledger_qweb', |
|||
data=data) |
|||
|
|||
def _build_contexts(self, data): |
|||
result = {} |
|||
result['journal_ids'] = ( |
|||
'journal_ids' in data['form'] and |
|||
data['form']['journal_ids'] or False |
|||
) |
|||
result['state'] = ( |
|||
'target_move' in data['form'] and |
|||
data['form']['target_move'] or '' |
|||
) |
|||
result['date_from'] = data['form']['date_from'] or False |
|||
result['date_to'] = data['form']['date_to'] or False |
|||
result['strict_range'] = True if result['date_from'] else False |
|||
return result |
|||
|
|||
@api.multi |
|||
def button_view(self): |
|||
"""Open tree view w/ results.""" |
|||
return self.process() |
|||
|
|||
@api.multi |
|||
def process(self): |
|||
"""Process data and return window action.""" |
|||
self._query() |
|||
|
|||
return { |
|||
'domain': [('wizard_id', '=', self.id)], |
|||
'name': _('Ledger lines'), |
|||
'view_type': 'form', |
|||
'view_mode': 'tree', |
|||
'res_model': 'ledger.report.wizard.line', |
|||
'view_id': False, |
|||
'context': { |
|||
'search_default_group_by_account_id': True, |
|||
'search_default_group_by_date': True, |
|||
}, |
|||
'type': 'ir.actions.act_window' |
|||
} |
|||
|
|||
@api.onchange('date_range_id') |
|||
def onchange_date_range_id(self): |
|||
"""Handle date range change.""" |
|||
self.date_from = self.date_range_id.date_start |
|||
self.date_to = self.date_range_id.date_end |
|||
if self.date_from: |
|||
self.fy_start_date = self.env.user.company_id.find_daterange_fy( |
|||
fields.Date.from_string(self.date_range_id.date_start) |
|||
).date_start |
|||
|
|||
|
|||
class LedgerReportWizardLine(models.TransientModel): |
|||
"""A wizard line. |
|||
|
|||
Lines are populated on the fly when submitting the wizard. |
|||
""" |
|||
_name = 'ledger.report.wizard.line' |
|||
|
|||
wizard_id = fields.Many2one(comodel_name='ledger.report.wizard') |
|||
|
|||
name = fields.Char() |
|||
label = fields.Char() |
|||
ref = fields.Char() |
|||
date = fields.Date() |
|||
month = fields.Char() |
|||
partner_name = fields.Char() |
|||
partner_ref = fields.Char() |
|||
account_id = fields.Many2one('account.account') |
|||
account_code = fields.Char() |
|||
journal_id = fields.Many2one('account.journal') |
|||
partner_id = fields.Many2one('res.partner') |
|||
|
|||
init_credit = fields.Float() |
|||
init_debit = fields.Float() |
|||
debit = fields.Float() |
|||
credit = fields.Float() |
|||
balance = fields.Float() |
|||
|
|||
cumul_credit = fields.Float() |
|||
cumul_debit = fields.Float() |
|||
cumul_balance = fields.Float() |
|||
|
|||
init_balance = fields.Float() |
|||
|
|||
move_name = fields.Char() |
|||
move_state = fields.Char() |
|||
invoice_number = fields.Char() |
|||
|
|||
centralized = fields.Boolean() |
|||
|
|||
@api.multi |
|||
def check_report_xlsx(self): |
|||
self.ensure_one() |
|||
data = {} |
|||
data['ids'] = self.env.context.get('active_ids', []) |
|||
# data['model'] = 'general.ledger.line' |
|||
data['model'] = self.env.context.get('active_model', 'ir.ui.menu') |
|||
data['form'] = self.read(['date_from', 'date_to', |
|||
'journal_ids', 'target_move'])[0] |
|||
used_context = self._build_contexts(data) |
|||
data['form']['used_context'] = dict( |
|||
used_context, |
|||
lang=self.env.context.get('lang', 'en_US')) |
|||
return self._print_report_xlsx(data) |
|||
|
|||
@api.multi |
|||
def _print_report_xlsx(self, data): |
|||
return { |
|||
'name': 'export xlsx general ledger', |
|||
'model': 'ledger.report.wizard', |
|||
'type': 'ir.actions.report.xml', |
|||
'report_name': 'ledger.report.wizard.xlsx', |
|||
'report_type': 'xlsx', |
|||
'context': self.env.context, |
|||
} |
|||
|
|||
@api.multi |
|||
def _get_centralized_move_ids(self, domain): |
|||
""" Get last line of each selected centralized accounts """ |
|||
# inverse search on centralized boolean to finish the search to get the |
|||
# ids of last lines of centralized accounts |
|||
# XXX USE DISTINCT to speed up ? |
|||
domain = domain[:] |
|||
centralize_index = domain.index(('centralized', '=', False)) |
|||
domain[centralize_index] = ('centralized', '=', True) |
|||
|
|||
gl_lines = self.env['general.ledger.line'].search(domain) |
|||
accounts = gl_lines.mapped('account_id') |
|||
|
|||
line_ids = [] |
|||
for acc in accounts: |
|||
acc_lines = gl_lines.filtered(lambda rec: rec.account_id == acc) |
|||
line_ids.append(acc_lines[-1].id) |
|||
return line_ids |
|||
|
|||
@api.multi |
|||
def _get_moves_from_dates_domain(self): |
|||
""" Prepare domain for `_get_moves_from_dates` """ |
|||
domain = [] |
|||
if self.centralize: |
|||
domain = [('centralized', '=', False)] |
|||
start_date = self.date_from |
|||
end_date = self.date_to |
|||
if start_date: |
|||
domain += [('date', '>=', start_date)] |
|||
if end_date: |
|||
domain += [('date', '<=', end_date)] |
|||
|
|||
if self.target_move == 'posted': |
|||
domain += [('move_state', '=', 'posted')] |
|||
|
|||
if self.account_ids: |
|||
domain += [('account_id', 'in', self.account_ids.ids)] |
|||
|
|||
return domain |
|||
|
|||
def compute_domain(self): |
|||
ret = self._get_moves_from_dates_domain() |
|||
if self.centralize: |
|||
centralized_ids = self._get_centralized_move_ids(ret) |
|||
if centralized_ids: |
|||
ret.insert(0, '|') |
|||
ret.append(('id', 'in', centralized_ids)) |
|||
return ret |
|||
|
|||
def initial_balance_line(self, amount, account_name, account_code, date): |
|||
return {'date': date, |
|||
'account_id': account_name, |
|||
'account_code': account_code, |
|||
'move_name': '', |
|||
'journal_id': '', |
|||
'partner_name': '', |
|||
'ref': '', |
|||
'label': _('Initial Balance'), |
|||
'debit': '', |
|||
'credit': '', |
|||
'amount_currency': '', |
|||
'currency_code': '', |
|||
'month': '', |
|||
'partner_ref': '', |
|||
'cumul_balance': amount, |
|||
'init_balance': ''} |
|||
|
|||
def group_general_ledger(self, report_lines, date_start): |
|||
""" |
|||
group lines by account and order by account then date |
|||
""" |
|||
result = {} |
|||
accounts = report_lines.mapped('account_id') |
|||
for account in accounts: |
|||
lines = report_lines.filtered( |
|||
lambda a: a.account_id.id == account.id) |
|||
acc_full_name = account.name_get()[0][1] |
|||
sorted_lines = sorted(lines.read(FIELDS_TO_READ.values()), |
|||
key=itemgetter('date')) |
|||
initial_balance = sorted_lines[0]['init_balance'] |
|||
sorted_lines.insert(0, self.initial_balance_line(initial_balance, |
|||
acc_full_name, |
|||
account.code, |
|||
date_start)) |
|||
result[acc_full_name] = sorted_lines |
|||
|
|||
return result |
|||
|
|||
def construct_header(self): |
|||
result = {} |
|||
|
|||
result['title'] = _('General Ledger') |
|||
filters = {} |
|||
|
|||
filters['centralized'] = _('%s' % self.centralize) |
|||
filters['start_date'] = self.date_from |
|||
filters['end_date'] = self.date_to |
|||
|
|||
filters['target_moves'] = self.target_move |
|||
|
|||
filters['accounts'] = _('All') |
|||
if self.account_ids: |
|||
filters['accounts'] = ', '.join([a.code for a in self.account_ids]) |
|||
|
|||
result['filters'] = filters |
|||
|
|||
return result |
|||
|
|||
@api.multi |
|||
def compute(self): |
|||
self.ensure_one() |
|||
# header filled with a dict |
|||
header = [] |
|||
header.append(self.construct_header()) |
|||
# content filled with dicts |
|||
content = [] |
|||
|
|||
domain = self.compute_domain() |
|||
report_lines = self.env['general.ledger.line'].search(domain) |
|||
lines_general_ledger = self.group_general_ledger(report_lines, |
|||
self.date_from) |
|||
content.append(lines_general_ledger) |
|||
return {'header': header, |
|||
'content': content} |
@ -1,54 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
|
|||
<!-- PARTNER LEDGER --> |
|||
<record id="partner_ledger_report_wizard_view_form" model="ir.ui.view"> |
|||
<field name="name">Partner Ledger</field> |
|||
<field name="model">ledger.report.wizard</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<group name="main_info"> |
|||
<field name="company_id"/> |
|||
</group> |
|||
<group name="date_currency_filter"> |
|||
<group name="date_ranger"> |
|||
<field name="date_range_id"/> |
|||
<field name="date_from"/> |
|||
<field name="date_to"/> |
|||
</group> |
|||
<group name="extra_info"> |
|||
<field name="amount_currency"/> |
|||
</group> |
|||
</group> |
|||
<group name="other_filters"> |
|||
<group name="moves"> |
|||
<field name="target_move" widget="radio"/> |
|||
</group> |
|||
<group name="result_select"> |
|||
<field name="result_selection" widget="radio"/> |
|||
</group> |
|||
</group> |
|||
<label for="partner_ids"/> |
|||
<field name="partner_ids" nolabel="1"/> |
|||
<footer> |
|||
<button name="check_report" string="Print" type="object" default_focus="1" class="oe_highlight"/> |
|||
or |
|||
<button string="Cancel" class="oe_link" special="cancel" /> |
|||
</footer> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="action_partner_ledger_report_wizard" model="ir.actions.act_window"> |
|||
<field name="name">Partner Ledger</field> |
|||
<field name="type">ir.actions.act_window</field> |
|||
<field name="res_model">ledger.report.wizard</field> |
|||
<field name="view_type">form</field> |
|||
<field name="view_mode">form</field> |
|||
<field name="view_id" ref="partner_ledger_report_wizard_view_form"/> |
|||
<field name="target">new</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue