Add OCA General/Partner Ledger PDF
parent
7b88a742ba
commit
af306bab1f
|
@ -21,9 +21,8 @@
|
|||
],
|
||||
'data': [
|
||||
'wizard/aged_partner_balance_wizard_view.xml',
|
||||
'wizard/general_ledger_wizard.xml',
|
||||
'wizard/general_ledger_wizard_view.xml',
|
||||
'wizard/open_invoice_wizard_view.xml',
|
||||
'wizard/partner_ledger_wizard.xml',
|
||||
'wizard/balance_common_wizard_view.xml',
|
||||
'wizard/partner_balance_wizard_view.xml',
|
||||
'wizard/trial_balance_wizard_view.xml',
|
||||
|
@ -31,7 +30,9 @@
|
|||
'menuitems.xml',
|
||||
'reports.xml',
|
||||
'report/templates/general_ledger.xml',
|
||||
'report/templates/open_invoice_report.xml'
|
||||
'report/templates/layouts.xml',
|
||||
'report/templates/open_invoice_report.xml',
|
||||
'view/account_view.xml'
|
||||
],
|
||||
'test': [
|
||||
],
|
||||
|
|
|
@ -6,18 +6,13 @@
|
|||
parent="account.menu_finance_reports"
|
||||
id="menu_oca_reports"
|
||||
name="OCA reports"
|
||||
groups="account.group_account_manager,account.group_account_user"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
parent="menu_oca_reports"
|
||||
action="action_ledger_report_wizard"
|
||||
id="menu_ledger_report_wizard"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
parent="menu_oca_reports"
|
||||
action="action_partner_ledger_report_wizard"
|
||||
id="menu_partner_ledger_report_wizard"
|
||||
action="action_general_ledger_wizard"
|
||||
id="menu_general_ledger_wizard"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
# © 2015 Yannick Vaucher (Camptocamp)
|
||||
# © 2016 Damien Crier (Camptocamp)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).-
|
||||
from . import common
|
||||
from . import general_ledger
|
||||
from . import open_invoice
|
||||
from . import general_ledger_xlsx
|
||||
|
|
|
@ -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"
|
||||
|
||||
_auto = False
|
||||
_order = 'account_id, date'
|
||||
|
||||
@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
|
||||
|
||||
label = fields.Char(compute='_get_label', readonly=True, store=False)
|
||||
|
||||
|
||||
class GeneralLedgerReport(models.TransientModel):
|
||||
""" Here, we just define class fields.
|
||||
For methods, go more bottom at this file.
|
||||
"""
|
||||
|
||||
_name = 'report.account.report_generalledger_qweb'
|
||||
_inherit = 'account.report.common'
|
||||
_name = 'report_general_ledger_qweb'
|
||||
|
||||
@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
|
||||
|
||||
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')]
|
||||
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'
|
||||
)
|
||||
)
|
||||
display_account = fields.Char()
|
||||
display_ledger_lines = fields.Boolean()
|
||||
display_initial_balance = fields.Boolean()
|
||||
|
||||
MAPPING = {
|
||||
'date_from': 'start_date',
|
||||
'date_to': 'end_date',
|
||||
}
|
||||
account_ids = fields.One2many(
|
||||
comodel_name='report_general_ledger_qweb_account',
|
||||
inverse_name='report_id'
|
||||
)
|
||||
|
||||
|
||||
class GeneralLedgerReportAccount(models.TransientModel):
|
||||
|
||||
_name = 'report_general_ledger_qweb_account'
|
||||
_order = 'code ASC'
|
||||
|
||||
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_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 _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
|
||||
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"
|
||||
"""
|
||||
|
||||
@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')
|
||||
class GeneralLedgerReportMoveLine(models.TransientModel):
|
||||
|
||||
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
|
||||
_name = 'report_general_ledger_qweb_move_line'
|
||||
|
||||
@api.multi
|
||||
def _get_moves_from_dates(self):
|
||||
domain = self._get_moves_from_dates_domain()
|
||||
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)
|
||||
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))
|
||||
|
||||
@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)
|
||||
class GeneralLedgerReportCompute(models.TransientModel):
|
||||
|
||||
docargs = {
|
||||
'doc_ids': report.ids,
|
||||
'doc_model': self._name,
|
||||
'report_lines': report_lines,
|
||||
'docs': report,
|
||||
# XXX
|
||||
'has_currency': True
|
||||
_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]},
|
||||
}
|
||||
return self.env['report'].render(report_name, docargs)
|
||||
|
||||
@api.model
|
||||
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:
|
||||
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)
|
||||
|
|
|
@ -1,287 +1,225 @@
|
|||
<?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.report_generalledger_qweb">
|
||||
<t t-call="report.html_container">
|
||||
<t t-set="data_report_margin_top" t-value="12"/>
|
||||
<t t-set="data_report_header_spacing" t-value="9"/>
|
||||
<t t-set="data_report_dpi" t-value="110"/>
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<template id="account_financial_report_qweb.report_general_ledger_qweb">
|
||||
<t t-call="report.html_container">
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<t t-set="show_cost_center" t-value="o.show_cost_center"/>
|
||||
<t t-set="has_second_currency" t-value="o.has_second_currency"/>
|
||||
|
||||
<t t-call="report.internal_layout">
|
||||
<div class="page">
|
||||
<div class="act_as_table data_table" style="width: 1205px">
|
||||
<div class="act_as_row labels">
|
||||
<!--<div class="act_as_cell">Chart of Account</div>-->
|
||||
<div class="act_as_cell">Fiscal Year</div>
|
||||
<t t-if="o.start_date or o.end_date">
|
||||
<div class="act_as_cell">
|
||||
Dates Filter
|
||||
</div>
|
||||
</t>
|
||||
<div class="act_as_cell">Accounts Filter</div>
|
||||
<div class="act_as_cell">Journal Filter</div>
|
||||
<div class="act_as_cell">Target Moves</div>
|
||||
</div>
|
||||
<div class="act_as_row">
|
||||
<t t-if="o.start_date or o.end_date">
|
||||
<div class="act_as_cell">
|
||||
From:
|
||||
<span t-field="o.start_date"/>
|
||||
To:
|
||||
<span t-field="o.end_date"/>
|
||||
</div>
|
||||
</t>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.account_ids">
|
||||
<t t-raw="', '.join(o.account_ids.mapped('code'))"/>
|
||||
</t>
|
||||
<t t-if="not o.account_ids">
|
||||
All
|
||||
</t>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.journal_ids">
|
||||
<t t-raw="', '.join(o.journal_ids.mapped('code'))"/>
|
||||
</t>
|
||||
<t t-if="not o.journal_ids">
|
||||
All
|
||||
</t>
|
||||
</div>
|
||||
<div class="act_as_cell"><span t-field="o.target_move"/></div>
|
||||
</div>
|
||||
<t t-set="account" t-value="False"/>
|
||||
<!-- we use div with css instead of table for tabular data because div do not cut rows at half at page breaks -->
|
||||
<t t-foreach="report_lines" t-as="line">
|
||||
<t t-if="account != line.account_id">
|
||||
<t t-set="account" t-value="line.account_id"/>
|
||||
<div class="act_as_table list_table" style="margin-top: 10px;">
|
||||
<div class="act_as_caption account_title">
|
||||
<span t-field="account.code"/> - <span t-field="account.name"/>
|
||||
</div>
|
||||
<div class="act_as_thead">
|
||||
<div class="act_as_row labels">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell first_column" style="width: 50px;">Date</div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell" style="width: 100px;">Entry</div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell" style="width: 70px;">Journal</div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell" style="width: 65px;">Account</div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell" style="width: 140px;">Partner</div>
|
||||
<!--## move reference-->
|
||||
<div class="act_as_cell" style="width: 140px;">Reference</div>
|
||||
<!--## label-->
|
||||
<div class="act_as_cell" style="width: 160px;">Label</div>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Debit</div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Credit</div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Cumul. Bal.</div>
|
||||
<t t-if="has_currency">
|
||||
<!--## currency balance-->
|
||||
<div class="act_as_cell amount sep_left" style="width: 75px;">Curr. Balance</div>
|
||||
<!--## curency code-->
|
||||
<div class="act_as_cell amount" style="width: 30px; text-align: right;">Curr.</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<t t-if="not account.user_type_id.include_initial_balance">
|
||||
<t t-set="cumul_debit" t-value="0"/>
|
||||
<t t-set="cumul_credit" t-value="0"/>
|
||||
<t t-set="cumul_balance" t-value="0"/>
|
||||
</t>
|
||||
<!-- # init balance -->
|
||||
<t t-if="account.user_type_id.include_initial_balance">
|
||||
<div class="act_as_tbody">
|
||||
<div class="act_as_row initial_balance">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell first_column"></div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## move reference-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## label-->
|
||||
<div class="act_as_cell">Initial Balance</div>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount">
|
||||
<t t-if="not line.centralized">
|
||||
<span t-field="line.init_debit"/>
|
||||
</t>
|
||||
<t t-if="line.centralized">
|
||||
<span t-field="line.init_debit_centralized"/>
|
||||
</t>
|
||||
<t t-call="account_financial_report_qweb.internal_layout">
|
||||
<t t-set="title" t-value='"General Ledger"'/>
|
||||
<t t-set="company_name" t-value="o.company_id.name"/>
|
||||
<div class="page">
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
<div class="act_as_row labels">
|
||||
<div class="act_as_cell">Date range filter</div>
|
||||
<div class="act_as_cell">Target moves filter</div>
|
||||
<div class="act_as_cell">Account balance at 0 filter</div>
|
||||
<div class="act_as_cell">Centralize filter</div>
|
||||
</div>
|
||||
<div class="act_as_row">
|
||||
<div class="act_as_cell">
|
||||
From: <span t-field="o.date_from"/> To: <span t-field="o.date_to"/>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.only_posted_moves">All posted entries</t>
|
||||
<t t-if="not o.only_posted_moves">All entries</t>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.hide_account_balance_at_0">Hide</t>
|
||||
<t t-if="not o.hide_account_balance_at_0">Show</t>
|
||||
</div>
|
||||
<div class="act_as_cell">
|
||||
<t t-if="o.centralize">Yes</t>
|
||||
<t t-if="not o.centralize">No</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount">
|
||||
<t t-if="not line.centralized">
|
||||
<span t-field="line.init_credit"/>
|
||||
</t>
|
||||
<t t-if="line.centralized">
|
||||
<span t-field="line.init_credit_centralized"/>
|
||||
</t>
|
||||
</div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount" style="padding-right: 1px;">
|
||||
<t t-if="not line.centralized">
|
||||
<span t-field="line.init_balance"/>
|
||||
</t>
|
||||
<t t-if="line.centralized">
|
||||
<span t-field="line.init_balance"/>
|
||||
</t>
|
||||
</div>
|
||||
<t t-if="has_currency">
|
||||
<!--## currency balance-->
|
||||
<div class="act_as_cell amount sep_left">
|
||||
<t t-if="not line.centralized and account.currency_id">
|
||||
<span t-field="line.init_balance_curr"/>
|
||||
</t>
|
||||
<t t-if="line.centralized and account.currency_id">
|
||||
<span t-raw="line.init_balance_curr_centralized"/>
|
||||
</t>
|
||||
</div>
|
||||
<!--## curency code-->
|
||||
<div class="act_as_cell amount"></div>
|
||||
<t t-foreach="o.account_ids" t-as="account">
|
||||
<div class="page_break">
|
||||
<div class="act_as_table list_table" style="margin-top: 10px;"/>
|
||||
<div class="act_as_caption account_title" style="width: 1141px !important;">
|
||||
<span t-field="account.code"/> - <span t-field="account.name"/>
|
||||
</div>
|
||||
<t t-if="account.move_line_ids">
|
||||
<t t-call="account_financial_report_qweb.report_general_ledger_qweb_lines">
|
||||
<t t-set="account_or_partner_object" t-value="account"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="not account.move_line_ids">
|
||||
<t t-if="account.is_partner_account">
|
||||
<t t-foreach="account.partner_ids" t-as="partner">
|
||||
<div class="page_break">
|
||||
<div class="act_as_caption account_title">
|
||||
<span t-field="partner.name"/>
|
||||
</div>
|
||||
<t t-call="account_financial_report_qweb.report_general_ledger_qweb_lines">
|
||||
<t t-set="account_or_partner_object" t-value="partner"/>
|
||||
</t>
|
||||
<t t-call="account_financial_report_qweb.report_general_ledger_qweb_ending_cumul">
|
||||
<t t-set="account_or_partner_object" t-value="partner"/>
|
||||
<t t-set="type" t-value='"partner_type"'/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
<t t-call="account_financial_report_qweb.report_general_ledger_qweb_ending_cumul">
|
||||
<t t-set="account_or_partner_object" t-value="account"/>
|
||||
<t t-set="type" t-value='"account_type"'/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="account_financial_report_qweb.report_general_ledger_qweb_lines">
|
||||
<div class="act_as_table data_table" style="width: 1140px !important;">
|
||||
<div class="act_as_thead">
|
||||
<div class="act_as_row labels">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell first_column" style="width: 60px;">Date</div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell" style="width: 100px;">Entry</div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell" style="width: 40px;">Journal</div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell" style="width: 50px;">Account</div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell" style="width: 140px;">Partner</div>
|
||||
<!--## ref - label-->
|
||||
<div class="act_as_cell" style="width: 290px;">Ref - Label</div>
|
||||
<t t-if="show_cost_center">
|
||||
<!--## cost_center-->
|
||||
<div class="act_as_cell" style="width: 100px;">Cost center</div>
|
||||
</t>
|
||||
<!--## matching_number-->
|
||||
<div class="act_as_cell" style="width: 25px;">Rec.</div>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Debit</div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Credit</div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Cumul. Bal.</div>
|
||||
<t t-if="has_second_currency">
|
||||
<!--## currency_name-->
|
||||
<div class="act_as_cell" style="width: 35px;">Cur.</div>
|
||||
<!--## amount_currency-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">Amount cur.</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<!-- # initial_balance line -->
|
||||
<div class="act_as_row lines">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## ref - label-->
|
||||
<div class="act_as_cell amount">Initial balance</div>
|
||||
<t t-if="show_cost_center">
|
||||
<!--## cost_center-->
|
||||
<div class="act_as_cell"></div>
|
||||
</t>
|
||||
<!--## matching_number-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount"><span t-field="account_or_partner_object.initial_debit"/></div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount"><span t-field="account_or_partner_object.initial_credit"/></div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount"><span t-field="account_or_partner_object.initial_balance"/></div>
|
||||
<t t-if="has_second_currency">
|
||||
<!--## currency_name-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## amount_currency-->
|
||||
<div class="act_as_cell"></div>
|
||||
</t>
|
||||
</div>
|
||||
<t t-foreach="account_or_partner_object.move_line_ids" t-as="line">
|
||||
<!-- # lines or centralized lines -->
|
||||
<div class="act_as_row lines">
|
||||
<t t-if="not line.centralized">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell first_column"><span t-field="line.date"/></div>
|
||||
<div class="act_as_cell left"><span t-field="line.date"/></div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell"><span t-raw="line.move_name or ''"/></div>
|
||||
<div class="act_as_cell left"><span t-field="line.entry"/></div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell"><span t-field="line.journal_id.code"/></div>
|
||||
<div class="act_as_cell left"><span t-field="line.journal"/></div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell"><span t-field="account.code"/></div>
|
||||
<div class="act_as_cell left"><span t-field="line.account"/></div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell overflow_ellipsis"><span t-field="line.partner_name"/></div>
|
||||
<!--## move reference-->
|
||||
<div class="act_as_cell"><span t-field="line.ref"/></div>
|
||||
<!--## label-->
|
||||
<div class="act_as_cell"><span t-field="line.label"/></div>
|
||||
<div class="act_as_cell left"><span t-field="line.partner"/></div>
|
||||
<!--## ref - label-->
|
||||
<div class="act_as_cell left"><span t-field="line.label"/></div>
|
||||
<t t-if="show_cost_center">
|
||||
<!--## cost_center-->
|
||||
<div class="act_as_cell left"><span t-field="line.cost_center"/></div>
|
||||
</t>
|
||||
<!--## matching_number-->
|
||||
<div class="act_as_cell"><span t-field="line.matching_number"/></div>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount"><span t-field="line.debit"/></div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount"><span t-field="line.credit"/></div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount" style="padding-right: 1px;">
|
||||
<t t-if="not account.user_type_id.include_initial_balance">
|
||||
<t t-set="cumul_debit" t-value="cumul_debit + line.debit"/>
|
||||
<t t-set="cumul_credit" t-value="cumul_credit + line.credit"/>
|
||||
<t t-set="cumul_balance" t-value="cumul_balance + line.balance"/>
|
||||
<span t-raw="cumul_balance"/>
|
||||
</t>
|
||||
<t t-if="account.user_type_id.include_initial_balance">
|
||||
<span t-field="line.cumul_balance"/>
|
||||
</t>
|
||||
</div>
|
||||
<t t-if="has_currency">
|
||||
<!--## currency balance-->
|
||||
<div class="act_as_cell amount" style="padding-right: 1px;">
|
||||
<span t-field="line.amount_currency"/>
|
||||
</div>
|
||||
<!--## curency code-->
|
||||
<div class="act_as_cell amount" style="text-align: right;"><span t-field="line.currency_code"/></div>
|
||||
<div class="act_as_cell amount"><span t-field="line.cumul_balance"/></div>
|
||||
<t t-if="has_second_currency">
|
||||
<!--## currency_name-->
|
||||
<div class="act_as_cell"><span t-field="line.currency_name"/></div>
|
||||
<t t-if="line.currency_name">
|
||||
<!--## amount_currency-->
|
||||
<div class="act_as_cell amount"><span t-field="line.amount_currency"/></div>
|
||||
</t>
|
||||
<t t-if="not line.currency_name">
|
||||
<!--## amount_currency-->
|
||||
<div class="act_as_cell"></div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="line.centralized and line.period_last">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell first_column"><span t-field="line.month"/></div>
|
||||
<!--## move-->
|
||||
<div class="act_as_cell">Month centralization</div>
|
||||
<!--## journal-->
|
||||
<div class="act_as_cell"><span t-field="line.journal_id.code"/></div>
|
||||
<!--## account code-->
|
||||
<div class="act_as_cell"><span t-field="account.code"/></div>
|
||||
<!--## partner-->
|
||||
<div class="act_as_cell overflow_ellipsis"><span t-field="line.partner_name"/> <span t-if="line.partner_ref" t-field="line.partner_ref"/></div>
|
||||
<!--## move reference-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## label-->
|
||||
<div class="act_as_cell"></div>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount"><span t-field="line.debit_centralized"/></div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount"><span t-field="line.credit_centralized"/></div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount" style="padding-right: 1px;"><span t-field="line.cumul_balance"/></div>
|
||||
<t t-if="has_currency">
|
||||
<!--## currency balance-->
|
||||
<div class="act_as_cell amount sep_left"><span t-if="account.currency_id" t-field="line.balance_curr_centralized"/></div>
|
||||
<!--## curency code-->
|
||||
<div class="act_as_cell amount" style="text-align: right;"><span t-field="line.currency_code"/></div>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<!-- # Total -->
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<t t-if="(line_index + 1) == len(report_lines) or line.account_id != report_lines[line_index + 1].account_id">
|
||||
<div class="act_as_table list_table">
|
||||
<div class="act_as_row labels" style="font-weight: bold;">
|
||||
<!--## date-->
|
||||
<div class="act_as_cell first_column" style="width: 425;"><span t-field="account.code"/> - <span t-field="account.name"/></div>
|
||||
<div class="act_as_cell" style="width: 300px;">Cumulated Balance on Account</div>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">
|
||||
<t t-if="account.user_type_id.include_initial_balance">
|
||||
<span t-field="line.cumul_debit"/>
|
||||
</t>
|
||||
<t t-if="not account.user_type_id.include_initial_balance">
|
||||
<span t-raw="cumul_debit"/>
|
||||
</t>
|
||||
</div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;">
|
||||
<t t-if="account.user_type_id.include_initial_balance">
|
||||
<span t-field="line.cumul_credit"/>
|
||||
</t>
|
||||
<t t-if="not account.user_type_id.include_initial_balance">
|
||||
<span t-raw="cumul_credit"/>
|
||||
</t>
|
||||
</div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount" style="width: 75px; padding-right: 1px;">
|
||||
<t t-if="account.user_type_id.include_initial_balance">
|
||||
<span t-field="line.cumul_balance"/>
|
||||
</t>
|
||||
<t t-if="not account.user_type_id.include_initial_balance">
|
||||
<span t-raw="cumul_balance"/>
|
||||
</t>
|
||||
</div>
|
||||
<t t-if="has_currency">
|
||||
<!--## currency balance-->
|
||||
<div class="act_as_cell amount sep_left" style="width: 75px;"><t t-if="account.currency_id"><span t-field="line.cumul_balance_curr"/></t></div>
|
||||
<!--## curency code-->
|
||||
<div class="act_as_cell amount" style="width: 30px; text-align: right;"></div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template id="account_financial_report_qweb.report_general_ledger_qweb_ending_cumul">
|
||||
<div class="act_as_table list_table" style="width: 1141px !important;">
|
||||
<div class="act_as_row labels" style="font-weight: bold;">
|
||||
<!--## date-->
|
||||
<t t-if='type == "account_type"'>
|
||||
<div class="act_as_cell first_column" style="width: 380px;"><span t-field="account_or_partner_object.code"/> - <span t-field="account_or_partner_object.name"/></div>
|
||||
<div class="act_as_cell right" style="width: 290px;">Ending balance</div>
|
||||
</t>
|
||||
<t t-if='type == "partner_type"'>
|
||||
<div class="act_as_cell first_column" style="width: 380px;"></div>
|
||||
<div class="act_as_cell right" style="width: 290px;">Partner ending balance</div>
|
||||
</t>
|
||||
<t t-if="show_cost_center">
|
||||
<!--## cost_center-->
|
||||
<div class="act_as_cell" style="width: 100px;"></div>
|
||||
</t>
|
||||
<!--## matching_number-->
|
||||
<div class="act_as_cell" style="width: 25px;"></div>
|
||||
<!--## debit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;"><span t-field="account_or_partner_object.final_debit"/></div>
|
||||
<!--## credit-->
|
||||
<div class="act_as_cell amount" style="width: 75px;"><span t-field="account_or_partner_object.final_credit"/></div>
|
||||
<!--## balance cumulated-->
|
||||
<div class="act_as_cell amount" style="width: 75px; padding-right: 1px;"><span t-field="account_or_partner_object.final_balance"/></div>
|
||||
<t t-if="has_second_currency">
|
||||
<!--## currency_name + amount_currency-->
|
||||
<div class="act_as_cell" style="width: 110px;"></div>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
|
@ -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>
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
<report
|
||||
id="action_report_general_ledger_qweb"
|
||||
model="report.account.report_generalledger_qweb"
|
||||
model="report_general_ledger_qweb"
|
||||
string="General Ledger"
|
||||
report_type="qweb-pdf"
|
||||
name="account.report_generalledger_qweb"
|
||||
file="account.report_generalledger_qweb"
|
||||
name="account_financial_report_qweb.report_general_ledger_qweb"
|
||||
file="account_financial_report_qweb.report_general_ledger_qweb"
|
||||
/>
|
||||
|
||||
<!--PaperFormat A4 internal open invoice-->
|
||||
|
@ -45,5 +45,25 @@
|
|||
<field name="auto" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="report_qweb_paperformat" model="report.paperformat">
|
||||
<field name="name">Account financial report qweb paperformat</field>
|
||||
<field name="default" eval="True"/>
|
||||
<field name="format">custom</field>
|
||||
<field name="page_height">297</field>
|
||||
<field name="page_width">210</field>
|
||||
<field name="orientation">Portrait</field>
|
||||
<field name="margin_top">12</field>
|
||||
<field name="margin_bottom">8</field>
|
||||
<field name="margin_left">5</field>
|
||||
<field name="margin_right">5</field>
|
||||
<field name="header_line" eval="False"/>
|
||||
<field name="header_spacing">10</field>
|
||||
<field name="dpi">110</field>
|
||||
</record>
|
||||
|
||||
<record id="action_report_general_ledger_qweb" model="ir.actions.report.xml">
|
||||
<field name="paperformat_id" ref="report_qweb_paperformat"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -29,7 +29,7 @@ body, table, td, span, div {
|
|||
border-left:0px;
|
||||
border-right:0px;
|
||||
text-align:left;
|
||||
font-size:9px;
|
||||
font-size:10px;
|
||||
padding-right:3px;
|
||||
padding-left:3px;
|
||||
padding-top:2px;
|
||||
|
@ -58,14 +58,22 @@ body, table, td, span, div {
|
|||
font-style:italic;
|
||||
}
|
||||
.account_title {
|
||||
font-size:10px;
|
||||
font-size:11px;
|
||||
font-weight:bold;
|
||||
page-break-after: avoid;
|
||||
}
|
||||
.account_title.labels {
|
||||
background-color:#F0F0F0 !important;
|
||||
}
|
||||
.act_as_cell.amount {
|
||||
word-wrap:normal;
|
||||
text-align:right;
|
||||
}
|
||||
.act_as_cell.left {
|
||||
text-align:left;
|
||||
}
|
||||
.act_as_cell.right {
|
||||
text-align:right;
|
||||
}
|
||||
.list_table .act_as_cell{
|
||||
padding-left: 5px;
|
||||
/* border-right:1px solid lightGrey; uncomment to active column lines */
|
||||
|
@ -79,3 +87,9 @@ body, table, td, span, div {
|
|||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.custom_footer {
|
||||
font-size:7px !important;
|
||||
}
|
||||
.page_break {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -3,6 +3,6 @@
|
|||
# Copyright 2016 Camptocamp SA
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
from . import aged_partner_balance_wizard
|
||||
from . import ledger_report_wizard
|
||||
from . import balance_common_wizard
|
||||
from . import general_ledger_wizard
|
||||
from . import open_invoice_wizard
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue