jcoux
9 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 -*- |
# -*- coding: utf-8 -*- |
||||
# © 2015 Yannick Vaucher (Camptocamp) |
|
||||
|
# © 2016 Julien Coux (Camptocamp) |
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
from openerp import models, fields, api |
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() |
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 |
@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: |
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