Browse Source
Merge pull request #366 from acsone/10.0-add_afr_qweb_journal_report-bwi
Merge pull request #366 from acsone/10.0-add_afr_qweb_journal_report-bwi
[10.0] afr qweb journal reportpull/408/head
Pedro M. Baeza
7 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 2016 additions and 4 deletions
-
1account_financial_report_qweb/README.rst
-
3account_financial_report_qweb/__manifest__.py
-
8account_financial_report_qweb/menuitems.xml
-
2account_financial_report_qweb/report/__init__.py
-
22account_financial_report_qweb/report/abstract_report_xlsx.py
-
764account_financial_report_qweb/report/journal_report.py
-
274account_financial_report_qweb/report/journal_report_xlsx.py
-
445account_financial_report_qweb/report/templates/journal.xml
-
22account_financial_report_qweb/reports.xml
-
1account_financial_report_qweb/tests/__init__.py
-
292account_financial_report_qweb/tests/test_journal.py
-
1account_financial_report_qweb/wizard/__init__.py
-
119account_financial_report_qweb/wizard/journal_report_wizard.py
-
66account_financial_report_qweb/wizard/journal_report_wizard.xml
@ -0,0 +1,764 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 ACSONE SA/NV |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from odoo import models, fields, api |
|||
|
|||
DIGITS = (16, 2) |
|||
|
|||
|
|||
class ReportJournalQweb(models.TransientModel): |
|||
|
|||
_name = 'report_journal_qweb' |
|||
|
|||
date_from = fields.Date( |
|||
required=True |
|||
) |
|||
date_to = fields.Date( |
|||
required=True |
|||
) |
|||
company_id = fields.Many2one( |
|||
comodel_name='res.company', |
|||
required=True, |
|||
ondelete='cascade' |
|||
) |
|||
move_target = fields.Selection( |
|||
selection='_get_move_targets', |
|||
default='all', |
|||
required=True, |
|||
) |
|||
sort_option = fields.Selection( |
|||
selection='_get_sort_options', |
|||
default='move_name', |
|||
required=True, |
|||
) |
|||
group_option = fields.Selection( |
|||
selection='_get_group_options', |
|||
default='journal', |
|||
required=True, |
|||
) |
|||
journal_ids = fields.Many2many( |
|||
comodel_name='account.journal', |
|||
required=True, |
|||
) |
|||
report_journal_ids = fields.One2many( |
|||
comodel_name='report_journal_qweb_journal', |
|||
inverse_name='report_id', |
|||
) |
|||
report_move_ids = fields.One2many( |
|||
comodel_name='report_journal_qweb_move', |
|||
inverse_name='report_id', |
|||
) |
|||
report_move_line_ids = fields.One2many( |
|||
comodel_name='report_journal_qweb_move_line', |
|||
inverse_name='report_id', |
|||
) |
|||
report_journal_tax_line_ids = fields.One2many( |
|||
comodel_name='report_journal_qweb_journal_tax_line', |
|||
inverse_name='report_id', |
|||
) |
|||
report_tax_line_ids = fields.One2many( |
|||
comodel_name='report_journal_qweb_report_tax_line', |
|||
inverse_name='report_id', |
|||
) |
|||
with_currency = fields.Boolean() |
|||
with_account_name = fields.Boolean() |
|||
|
|||
@api.model |
|||
def _get_move_targets(self): |
|||
return self.env['journal.report.wizard']._get_move_targets() |
|||
|
|||
@api.model |
|||
def _get_sort_options(self): |
|||
return self.env['journal.report.wizard']._get_sort_options() |
|||
|
|||
@api.model |
|||
def _get_group_options(self): |
|||
return self.env['journal.report.wizard']._get_group_options() |
|||
|
|||
@api.multi |
|||
def compute_data_for_report(self): |
|||
self.ensure_one() |
|||
self._inject_journal_values() |
|||
self._inject_move_values() |
|||
self._inject_move_line_values() |
|||
self._inject_journal_tax_values() |
|||
self._update_journal_report_total_values() |
|||
|
|||
if self.group_option == 'none': |
|||
self._inject_report_tax_values() |
|||
|
|||
@api.multi |
|||
def refresh(self): |
|||
self.ensure_one() |
|||
self.report_journal_ids.unlink() |
|||
self.compute_data_for_report() |
|||
|
|||
@api.multi |
|||
def _inject_journal_values(self): |
|||
self.ensure_one() |
|||
sql = """ |
|||
INSERT INTO report_journal_qweb_journal ( |
|||
create_uid, |
|||
create_date, |
|||
report_id, |
|||
journal_id, |
|||
name, |
|||
code, |
|||
company_id, |
|||
currency_id |
|||
) |
|||
SELECT |
|||
%s as create_uid, |
|||
NOW() as create_date, |
|||
%s as report_id, |
|||
aj.id as journal_id, |
|||
aj.name as name, |
|||
aj.code as code, |
|||
aj.company_id as company_id, |
|||
COALESCE(aj.currency_id, company.currency_id) as currency_id |
|||
FROM |
|||
account_journal aj |
|||
LEFT JOIN |
|||
res_company company on (company.id = aj.company_id) |
|||
WHERE |
|||
aj.id in %s |
|||
AND |
|||
aj.company_id = %s |
|||
ORDER BY |
|||
aj.name |
|||
""" |
|||
params = ( |
|||
self.env.uid, |
|||
self.id, |
|||
tuple(self.journal_ids.ids), |
|||
self.company_id.id, |
|||
) |
|||
self.env.cr.execute(sql, params) |
|||
|
|||
@api.multi |
|||
def _inject_move_values(self): |
|||
self.ensure_one() |
|||
sql = self._get_inject_move_insert() |
|||
sql += self._get_inject_move_select() |
|||
sql += self._get_inject_move_where_clause() |
|||
sql += self._get_inject_move_order_by() |
|||
params = self._get_inject_move_params() |
|||
self.env.cr.execute(sql, params) |
|||
|
|||
@api.multi |
|||
def _get_inject_move_insert(self): |
|||
return """ |
|||
INSERT INTO report_journal_qweb_move ( |
|||
create_uid, |
|||
create_date, |
|||
report_id, |
|||
report_journal_id, |
|||
move_id, |
|||
name, |
|||
company_id |
|||
) |
|||
""" |
|||
|
|||
@api.multi |
|||
def _get_inject_move_select(self): |
|||
return """ |
|||
SELECT |
|||
%s as create_uid, |
|||
NOW() as create_date, |
|||
rjqj.report_id as report_id, |
|||
rjqj.id as report_journal_id, |
|||
am.id as move_id, |
|||
am.name as name, |
|||
am.company_id as company_id |
|||
FROM |
|||
account_move am |
|||
INNER JOIN |
|||
report_journal_qweb_journal rjqj |
|||
on (rjqj.journal_id = am.journal_id) |
|||
""" |
|||
|
|||
@api.multi |
|||
def _get_inject_move_where_clause(self): |
|||
self.ensure_one() |
|||
where_clause = """ |
|||
WHERE |
|||
rjqj.report_id = %s |
|||
AND |
|||
am.date >= %s |
|||
AND |
|||
am.date <= %s |
|||
""" |
|||
if self.move_target != 'all': |
|||
where_clause += """ |
|||
AND |
|||
am.state = %s |
|||
""" |
|||
return where_clause |
|||
|
|||
@api.multi |
|||
def _get_inject_move_order_by(self): |
|||
self.ensure_one() |
|||
order_by = """ |
|||
ORDER BY |
|||
""" |
|||
if self.sort_option == 'move_name': |
|||
order_by += " am.name" |
|||
elif self.sort_option == 'date': |
|||
order_by += " am.date, am.name" |
|||
return order_by |
|||
|
|||
@api.multi |
|||
def _get_inject_move_params(self): |
|||
params = [ |
|||
self.env.uid, |
|||
self.id, |
|||
self.date_from, |
|||
self.date_to |
|||
] |
|||
|
|||
if self.move_target != 'all': |
|||
params.append(self.move_target) |
|||
|
|||
return tuple(params) |
|||
|
|||
@api.multi |
|||
def _inject_move_line_values(self): |
|||
self.ensure_one() |
|||
sql = """ |
|||
INSERT INTO report_journal_qweb_move_line ( |
|||
create_uid, |
|||
create_date, |
|||
report_id, |
|||
report_journal_id, |
|||
report_move_id, |
|||
move_line_id, |
|||
account_id, |
|||
account, |
|||
account_code, |
|||
account_type, |
|||
partner_id, |
|||
partner, |
|||
date, |
|||
entry, |
|||
label, |
|||
debit, |
|||
credit, |
|||
company_currency_id, |
|||
amount_currency, |
|||
currency_id, |
|||
currency_name, |
|||
tax_id, |
|||
taxes_description, |
|||
company_id |
|||
) |
|||
SELECT |
|||
%s as create_uid, |
|||
NOW() as create_date, |
|||
rjqm.report_id as report_id, |
|||
rjqm.report_journal_id as report_journal_id, |
|||
rjqm.id as report_move_id, |
|||
aml.id as move_line_id, |
|||
aml.account_id as account_id, |
|||
aa.name as account, |
|||
aa.code as account_code, |
|||
aa.internal_type as account_type, |
|||
aml.partner_id as partner_id, |
|||
p.name as partner, |
|||
aml.date as date, |
|||
rjqm.name as entry, |
|||
aml.name as label, |
|||
aml.debit as debit, |
|||
aml.credit as credit, |
|||
aml.company_currency_id as currency_id, |
|||
aml.amount_currency as amount_currency, |
|||
aml.currency_id as currency_id, |
|||
currency.name as currency_name, |
|||
aml.tax_line_id as tax_id, |
|||
CASE |
|||
WHEN |
|||
aml.tax_line_id is not null |
|||
THEN |
|||
COALESCE(at.description, at.name) |
|||
WHEN |
|||
aml.tax_line_id is null |
|||
THEN |
|||
(SELECT |
|||
array_to_string( |
|||
array_agg(COALESCE(at.description, at.name) |
|||
), ', ') |
|||
FROM |
|||
account_move_line_account_tax_rel aml_at_rel |
|||
LEFT JOIN |
|||
account_tax at on (at.id = aml_at_rel.account_tax_id) |
|||
WHERE |
|||
aml_at_rel.account_move_line_id = aml.id) |
|||
ELSE |
|||
'' |
|||
END as taxes_description, |
|||
aml.company_id as company_id |
|||
FROM |
|||
account_move_line aml |
|||
INNER JOIN |
|||
report_journal_qweb_move rjqm |
|||
on (rjqm.move_id = aml.move_id) |
|||
LEFT JOIN |
|||
account_account aa |
|||
on (aa.id = aml.account_id) |
|||
LEFT JOIN |
|||
res_partner p |
|||
on (p.id = aml.partner_id) |
|||
LEFT JOIN |
|||
account_tax at |
|||
on (at.id = aml.tax_line_id) |
|||
LEFT JOIN |
|||
res_currency currency |
|||
on (currency.id = aml.currency_id) |
|||
WHERE |
|||
rjqm.report_id = %s |
|||
""" |
|||
params = ( |
|||
self.env.uid, |
|||
self.id, |
|||
) |
|||
self.env.cr.execute(sql, params) |
|||
|
|||
@api.multi |
|||
def _inject_report_tax_values(self): |
|||
self.ensure_one() |
|||
sql_distinct_tax_id = """ |
|||
SELECT |
|||
distinct(jrqjtl.tax_id) |
|||
FROM |
|||
report_journal_qweb_journal_tax_line jrqjtl |
|||
WHERE |
|||
jrqjtl.report_id = %s |
|||
""" |
|||
self.env.cr.execute(sql_distinct_tax_id, (self.id,)) |
|||
rows = self.env.cr.fetchall() |
|||
tax_ids = set([row[0] for row in rows]) |
|||
|
|||
sql = """ |
|||
INSERT INTO report_journal_qweb_report_tax_line ( |
|||
create_uid, |
|||
create_date, |
|||
report_id, |
|||
tax_id, |
|||
tax_name, |
|||
tax_code, |
|||
base_debit, |
|||
base_credit, |
|||
tax_debit, |
|||
tax_credit |
|||
) |
|||
SELECT |
|||
%s as create_uid, |
|||
NOW() as create_date, |
|||
%s as report_id, |
|||
%s as tax_id, |
|||
at.name as tax_name, |
|||
at.description as tax_code, |
|||
( |
|||
SELECT sum(base_debit) |
|||
FROM report_journal_qweb_journal_tax_line jrqjtl2 |
|||
WHERE jrqjtl2.report_id = %s |
|||
AND jrqjtl2.tax_id = %s |
|||
) as base_debit, |
|||
( |
|||
SELECT sum(base_credit) |
|||
FROM report_journal_qweb_journal_tax_line jrqjtl2 |
|||
WHERE jrqjtl2.report_id = %s |
|||
AND jrqjtl2.tax_id = %s |
|||
) as base_credit, |
|||
( |
|||
SELECT sum(tax_debit) |
|||
FROM report_journal_qweb_journal_tax_line jrqjtl2 |
|||
WHERE jrqjtl2.report_id = %s |
|||
AND jrqjtl2.tax_id = %s |
|||
) as tax_debit, |
|||
( |
|||
SELECT sum(tax_credit) |
|||
FROM report_journal_qweb_journal_tax_line jrqjtl2 |
|||
WHERE jrqjtl2.report_id = %s |
|||
AND jrqjtl2.tax_id = %s |
|||
) as tax_credit |
|||
FROM |
|||
report_journal_qweb_journal_tax_line jrqjtl |
|||
LEFT JOIN |
|||
account_tax at |
|||
on (at.id = jrqjtl.tax_id) |
|||
WHERE |
|||
jrqjtl.report_id = %s |
|||
AND |
|||
jrqjtl.tax_id = %s |
|||
""" |
|||
|
|||
for tax_id in tax_ids: |
|||
params = ( |
|||
self.env.uid, |
|||
self.id, |
|||
tax_id, |
|||
self.id, |
|||
tax_id, |
|||
self.id, |
|||
tax_id, |
|||
self.id, |
|||
tax_id, |
|||
self.id, |
|||
tax_id, |
|||
self.id, |
|||
tax_id, |
|||
) |
|||
self.env.cr.execute(sql, params) |
|||
|
|||
@api.multi |
|||
def _inject_journal_tax_values(self): |
|||
self.ensure_one() |
|||
|
|||
sql_distinct_tax_id = """ |
|||
SELECT |
|||
distinct(jrqml.tax_id) |
|||
FROM |
|||
report_journal_qweb_move_line jrqml |
|||
WHERE |
|||
jrqml.report_journal_id = %s |
|||
""" |
|||
|
|||
tax_ids_by_journal_id = {} |
|||
for report_journal in self.report_journal_ids: |
|||
if report_journal.id not in tax_ids_by_journal_id: |
|||
tax_ids_by_journal_id[report_journal.id] = [] |
|||
self.env.cr.execute(sql_distinct_tax_id, (report_journal.id,)) |
|||
rows = self.env.cr.fetchall() |
|||
tax_ids_by_journal_id[report_journal.id].extend([ |
|||
row[0] for row in rows if row[0] |
|||
]) |
|||
|
|||
sql = """ |
|||
INSERT INTO report_journal_qweb_journal_tax_line ( |
|||
create_uid, |
|||
create_date, |
|||
report_id, |
|||
report_journal_id, |
|||
tax_id, |
|||
tax_name, |
|||
tax_code, |
|||
base_debit, |
|||
base_credit, |
|||
tax_debit, |
|||
tax_credit |
|||
) |
|||
SELECT |
|||
%s as create_uid, |
|||
NOW() as create_date, |
|||
%s as report_id, |
|||
%s as report_journal_id, |
|||
%s as tax_id, |
|||
at.name as tax_name, |
|||
at.description as tax_code, |
|||
( |
|||
SELECT sum(debit) |
|||
FROM report_journal_qweb_move_line jrqml2 |
|||
WHERE jrqml2.report_journal_id = %s |
|||
AND ( |
|||
SELECT |
|||
count(*) |
|||
FROM |
|||
account_move_line_account_tax_rel aml_at_rel |
|||
WHERE |
|||
aml_at_rel.account_move_line_id = |
|||
jrqml2.move_line_id |
|||
AND |
|||
aml_at_rel.account_tax_id = %s |
|||
) > 0 |
|||
) as base_debit, |
|||
( |
|||
SELECT sum(credit) |
|||
FROM report_journal_qweb_move_line jrqml2 |
|||
WHERE jrqml2.report_journal_id = %s |
|||
AND ( |
|||
SELECT |
|||
count(*) |
|||
FROM |
|||
account_move_line_account_tax_rel aml_at_rel |
|||
WHERE |
|||
aml_at_rel.account_move_line_id = |
|||
jrqml2.move_line_id |
|||
AND |
|||
aml_at_rel.account_tax_id = %s |
|||
) > 0 |
|||
) as base_credit, |
|||
( |
|||
SELECT sum(debit) |
|||
FROM report_journal_qweb_move_line jrqml2 |
|||
WHERE jrqml2.report_journal_id = %s |
|||
AND jrqml2.tax_id = %s |
|||
) as tax_debit, |
|||
( |
|||
SELECT sum(credit) |
|||
FROM report_journal_qweb_move_line jrqml2 |
|||
WHERE jrqml2.report_journal_id = %s |
|||
AND jrqml2.tax_id = %s |
|||
) as tax_credit |
|||
FROM |
|||
report_journal_qweb_journal rjqj |
|||
LEFT JOIN |
|||
account_tax at |
|||
on (at.id = %s) |
|||
WHERE |
|||
rjqj.id = %s |
|||
""" |
|||
|
|||
for report_journal_id in tax_ids_by_journal_id: |
|||
tax_ids = tax_ids_by_journal_id[report_journal_id] |
|||
for tax_id in tax_ids: |
|||
params = ( |
|||
self.env.uid, |
|||
self.id, |
|||
report_journal_id, |
|||
tax_id, |
|||
report_journal_id, |
|||
tax_id, |
|||
report_journal_id, |
|||
tax_id, |
|||
report_journal_id, |
|||
tax_id, |
|||
report_journal_id, |
|||
tax_id, |
|||
tax_id, |
|||
report_journal_id, |
|||
) |
|||
self.env.cr.execute(sql, params) |
|||
|
|||
@api.multi |
|||
def _update_journal_report_total_values(self): |
|||
self.ensure_one() |
|||
sql = """ |
|||
UPDATE |
|||
report_journal_qweb_journal rjqj |
|||
SET |
|||
debit = ( |
|||
SELECT sum(rjqml.debit) |
|||
FROM report_journal_qweb_move_line rjqml |
|||
WHERE rjqml.report_journal_id = rjqj.id |
|||
), |
|||
credit = ( |
|||
SELECT sum(rjqml.credit) |
|||
FROM report_journal_qweb_move_line rjqml |
|||
WHERE rjqml.report_journal_id = rjqj.id |
|||
) |
|||
WHERE |
|||
rjqj.report_id = %s |
|||
""" |
|||
self.env.cr.execute(sql, (self.id,)) |
|||
|
|||
@api.multi |
|||
def print_report(self, xlsx_report=False): |
|||
self.ensure_one() |
|||
self.compute_data_for_report() |
|||
if xlsx_report: |
|||
report_name = 'account_financial_report_qweb.' \ |
|||
'report_journal_xlsx' |
|||
else: |
|||
report_name = 'account_financial_report_qweb.' \ |
|||
'report_journal_qweb' |
|||
return self.env['report'].get_action( |
|||
docids=self.ids, report_name=report_name) |
|||
|
|||
|
|||
class ReportJournalQwebJournal(models.TransientModel): |
|||
|
|||
_name = 'report_journal_qweb_journal' |
|||
|
|||
name = fields.Char( |
|||
required=True, |
|||
) |
|||
code = fields.Char() |
|||
report_id = fields.Many2one( |
|||
comodel_name='report_journal_qweb', |
|||
required=True, |
|||
ondelete='cascade' |
|||
) |
|||
journal_id = fields.Many2one( |
|||
comodel_name='account.journal', |
|||
required=True, |
|||
ondelete='cascade', |
|||
) |
|||
report_move_ids = fields.One2many( |
|||
comodel_name='report_journal_qweb_move', |
|||
inverse_name='report_journal_id', |
|||
) |
|||
report_tax_line_ids = fields.One2many( |
|||
comodel_name='report_journal_qweb_journal_tax_line', |
|||
inverse_name='report_journal_id', |
|||
) |
|||
debit = fields.Float( |
|||
digits=DIGITS, |
|||
) |
|||
credit = fields.Float( |
|||
digits=DIGITS, |
|||
) |
|||
company_id = fields.Many2one( |
|||
comodel_name='res.company', |
|||
required=True, |
|||
ondelete='cascade' |
|||
) |
|||
currency_id = fields.Many2one( |
|||
comodel_name='res.currency', |
|||
) |
|||
|
|||
|
|||
class ReportJournalQwebMove(models.TransientModel): |
|||
|
|||
_name = 'report_journal_qweb_move' |
|||
|
|||
report_id = fields.Many2one( |
|||
comodel_name='report_journal_qweb', |
|||
required=True, |
|||
ondelete='cascade' |
|||
) |
|||
report_journal_id = fields.Many2one( |
|||
comodel_name='report_journal_qweb_journal', |
|||
required=True, |
|||
ondelete='cascade', |
|||
) |
|||
move_id = fields.Many2one( |
|||
comodel_name='account.move', |
|||
required=True, |
|||
ondelete='cascade', |
|||
) |
|||
report_move_line_ids = fields.One2many( |
|||
comodel_name='report_journal_qweb_move_line', |
|||
inverse_name='report_move_id', |
|||
) |
|||
name = fields.Char() |
|||
company_id = fields.Many2one( |
|||
comodel_name='res.company', |
|||
required=True, |
|||
ondelete='cascade' |
|||
) |
|||
|
|||
|
|||
class ReportJournalQwebMoveLine(models.TransientModel): |
|||
|
|||
_name = 'report_journal_qweb_move_line' |
|||
_order = 'partner_id desc, account_id desc' |
|||
|
|||
report_id = fields.Many2one( |
|||
comodel_name='report_journal_qweb', |
|||
required=True, |
|||
ondelete='cascade' |
|||
) |
|||
report_journal_id = fields.Many2one( |
|||
comodel_name='report_journal_qweb_journal', |
|||
required=True, |
|||
ondelete='cascade', |
|||
) |
|||
report_move_id = fields.Many2one( |
|||
comodel_name='report_journal_qweb_move', |
|||
required=True, |
|||
ondelete='cascade', |
|||
) |
|||
move_line_id = fields.Many2one( |
|||
comodel_name='account.move.line', |
|||
required=True, |
|||
ondelete='cascade', |
|||
) |
|||
account_id = fields.Many2one( |
|||
comodel_name='account.account' |
|||
) |
|||
account = fields.Char() |
|||
account_code = fields.Char() |
|||
account_type = fields.Char() |
|||
partner = fields.Char() |
|||
partner_id = fields.Many2one( |
|||
comodel_name='res.partner', |
|||
) |
|||
date = fields.Date() |
|||
entry = fields.Char() |
|||
label = fields.Char() |
|||
debit = fields.Float( |
|||
digits=DIGITS, |
|||
) |
|||
credit = fields.Float( |
|||
digits=DIGITS, |
|||
) |
|||
company_currency_id = fields.Many2one( |
|||
comodel_name='res.currency', |
|||
) |
|||
amount_currency = fields.Monetary( |
|||
currency_field='currency_id', |
|||
) |
|||
currency_id = fields.Many2one( |
|||
comodel_name='res.currency', |
|||
) |
|||
currency_name = fields.Char() |
|||
taxes_description = fields.Char() |
|||
tax_id = fields.Many2one( |
|||
comodel_name='account.tax' |
|||
) |
|||
company_id = fields.Many2one( |
|||
comodel_name='res.company', |
|||
required=True, |
|||
ondelete='cascade' |
|||
) |
|||
|
|||
|
|||
class ReportJournalQwebReportTaxLine(models.TransientModel): |
|||
|
|||
_name = 'report_journal_qweb_report_tax_line' |
|||
_order = 'tax_code' |
|||
|
|||
report_id = fields.Many2one( |
|||
comodel_name='report_journal_qweb', |
|||
required=True, |
|||
ondelete='cascade' |
|||
) |
|||
tax_id = fields.Many2one( |
|||
comodel_name='account.tax' |
|||
) |
|||
tax_name = fields.Char() |
|||
tax_code = fields.Char() |
|||
base_debit = fields.Float( |
|||
digits=DIGITS, |
|||
) |
|||
base_credit = fields.Float( |
|||
digits=DIGITS, |
|||
) |
|||
base_balance = fields.Float( |
|||
digits=DIGITS, |
|||
compute='_compute_base_balance', |
|||
) |
|||
tax_debit = fields.Float( |
|||
digits=DIGITS, |
|||
) |
|||
tax_credit = fields.Float( |
|||
digits=DIGITS, |
|||
) |
|||
tax_balance = fields.Float( |
|||
digits=DIGITS, |
|||
compute='_compute_tax_balance' |
|||
) |
|||
|
|||
@api.multi |
|||
def _compute_base_balance(self): |
|||
for rec in self: |
|||
rec.base_balance = rec.base_debit - rec.base_credit |
|||
|
|||
@api.multi |
|||
def _compute_tax_balance(self): |
|||
for rec in self: |
|||
rec.tax_balance = rec.tax_debit - rec.tax_credit |
|||
|
|||
|
|||
class ReportJournalQwebJournalTaxLine(models.TransientModel): |
|||
|
|||
_name = 'report_journal_qweb_journal_tax_line' |
|||
_inherit = 'report_journal_qweb_report_tax_line' |
|||
_order = 'tax_code' |
|||
|
|||
report_journal_id = fields.Many2one( |
|||
comodel_name='report_journal_qweb_journal', |
|||
required=True, |
|||
ondelete='cascade', |
|||
) |
@ -0,0 +1,274 @@ |
|||
# -*- 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 . import abstract_report_xlsx |
|||
from odoo.report import report_sxw |
|||
from odoo import _ |
|||
|
|||
|
|||
class JournalXslx(abstract_report_xlsx.AbstractReportXslx): |
|||
|
|||
def __init__( |
|||
self, name, table, rml=False, parser=False, header=True, |
|||
store=False): |
|||
super(JournalXslx, self).__init__( |
|||
name, table, rml, parser, header, store) |
|||
|
|||
def _get_report_name(self): |
|||
return _('Journal') |
|||
|
|||
def _get_report_columns(self, report): |
|||
columns = [ |
|||
{ |
|||
'header': _('Entry'), |
|||
'field': 'entry', |
|||
'width': 18 |
|||
}, |
|||
{ |
|||
'header': _('Date'), |
|||
'field': 'date', |
|||
'width': 11 |
|||
}, |
|||
{ |
|||
'header': _('Account'), |
|||
'field': 'account_code', |
|||
'width': 9 |
|||
}, |
|||
] |
|||
|
|||
if report.with_account_name: |
|||
columns.append({ |
|||
'header': _('Account Name'), |
|||
'field': 'account', |
|||
'width': 15 |
|||
}) |
|||
|
|||
columns += [ |
|||
{ |
|||
'header': _('Partner'), |
|||
'field': 'partner', |
|||
'width': 25 |
|||
}, |
|||
{ |
|||
'header': _('Ref - Label'), |
|||
'field': 'label', |
|||
'width': 40 |
|||
}, |
|||
{ |
|||
'header': _('Taxes'), |
|||
'field': 'taxes_description', |
|||
'width': 11 |
|||
}, |
|||
{ |
|||
'header': _('Debit'), |
|||
'field': 'debit', |
|||
'type': 'amount', |
|||
'width': 14, |
|||
}, |
|||
{ |
|||
'header': _('Credit'), |
|||
'field': 'credit', |
|||
'type': 'amount', |
|||
'width': 14 |
|||
} |
|||
] |
|||
|
|||
if report.with_currency: |
|||
columns += [ |
|||
{ |
|||
'header': _('Amount Currency'), |
|||
'field': 'amount_currency', |
|||
'type': 'amount', |
|||
'width': 14 |
|||
}, |
|||
{ |
|||
'header': _('Currency'), |
|||
'field': 'currency_name', |
|||
'width': 14 |
|||
} |
|||
] |
|||
|
|||
columns_as_dict = {} |
|||
for i, column in enumerate(columns): |
|||
columns_as_dict[i] = column |
|||
return columns_as_dict |
|||
|
|||
def _get_journal_tax_columns(self, report): |
|||
return { |
|||
0: { |
|||
'header': _('Name'), |
|||
'field': 'tax_name', |
|||
'width': 35 |
|||
}, |
|||
1: { |
|||
'header': _('Description'), |
|||
'field': 'tax_code', |
|||
'width': 18 |
|||
}, |
|||
2: { |
|||
'header': _('Base Debit'), |
|||
'field': 'base_debit', |
|||
'type': 'amount', |
|||
'width': 14 |
|||
}, |
|||
3: { |
|||
'header': _('Base Credit'), |
|||
'field': 'base_credit', |
|||
'type': 'amount', |
|||
'width': 14 |
|||
}, |
|||
4: { |
|||
'header': _('Base Balance'), |
|||
'field': 'base_balance', |
|||
'type': 'amount', |
|||
'width': 14 |
|||
}, |
|||
5: { |
|||
'header': _('Tax Debit'), |
|||
'field': 'tax_debit', |
|||
'type': 'amount', |
|||
'width': 14 |
|||
}, |
|||
6: { |
|||
'header': _('Tax Credit'), |
|||
'field': 'tax_credit', |
|||
'type': 'amount', |
|||
'width': 14 |
|||
}, |
|||
7: { |
|||
'header': _('Tax Balance'), |
|||
'field': 'tax_balance', |
|||
'type': 'amount', |
|||
'width': 14 |
|||
}, |
|||
} |
|||
|
|||
def _get_col_count_filter_name(self): |
|||
return 2 |
|||
|
|||
def _get_col_count_filter_value(self): |
|||
return 3 |
|||
|
|||
def _get_report_filters(self, report): |
|||
target_label_by_value = { |
|||
value: label |
|||
for value, label in |
|||
self.env['journal.report.wizard']._get_move_targets() |
|||
} |
|||
|
|||
sort_option_label_by_value = { |
|||
value: label |
|||
for value, label in |
|||
self.env['journal.report.wizard']._get_sort_options() |
|||
} |
|||
|
|||
return [ |
|||
[ |
|||
_('Company'), |
|||
report.company_id.name |
|||
], |
|||
[ |
|||
_('Date range filter'), |
|||
_('From: %s To: %s') % (report.date_from, report.date_to) |
|||
], |
|||
[ |
|||
_('Target moves filter'), |
|||
_("%s") % target_label_by_value[report.move_target], |
|||
], |
|||
[ |
|||
_('Entries sorted by'), |
|||
_("%s") % sort_option_label_by_value[report.sort_option], |
|||
], |
|||
[ |
|||
_('Journals'), |
|||
', '.join([ |
|||
"%s - %s" % (report_journal.code, report_journal.name) |
|||
for report_journal in report.report_journal_ids |
|||
]) |
|||
|
|||
] |
|||
] |
|||
|
|||
def _generate_report_content(self, workbook, report): |
|||
group_option = report.group_option |
|||
if group_option == 'journal': |
|||
for report_journal in report.report_journal_ids: |
|||
self._generate_journal_content(workbook, report_journal) |
|||
elif group_option == 'none': |
|||
self._generate_no_group_content(workbook, report) |
|||
|
|||
def _generate_no_group_content(self, workbook, report): |
|||
self._generate_moves_content( |
|||
workbook, report, "Report", report.report_move_ids) |
|||
self._generate_no_group_taxes_summary(workbook, report) |
|||
|
|||
def _generate_journal_content(self, workbook, report_journal): |
|||
sheet_name = "%s (%s) - %s" % ( |
|||
report_journal.code, |
|||
report_journal.currency_id.name, |
|||
report_journal.name, |
|||
) |
|||
self._generate_moves_content( |
|||
workbook, report_journal.report_id, sheet_name, |
|||
report_journal.report_move_ids) |
|||
self._generate_journal_taxes_summary(workbook, report_journal) |
|||
|
|||
def _generate_no_group_taxes_summary(self, workbook, report): |
|||
self._generate_taxes_summary( |
|||
workbook, report, "Tax Report", report.report_tax_line_ids) |
|||
|
|||
def _generate_journal_taxes_summary(self, workbook, report_journal): |
|||
sheet_name = "Tax - %s (%s) - %s" % ( |
|||
report_journal.code, |
|||
report_journal.currency_id.name, |
|||
report_journal.name, |
|||
) |
|||
report = report_journal.report_id |
|||
self._generate_taxes_summary( |
|||
workbook, report, sheet_name, report_journal.report_tax_line_ids) |
|||
|
|||
def _generate_moves_content(self, workbook, report, sheet_name, moves): |
|||
report_sheet = self.add_sheet(workbook, sheet_name) |
|||
self.set_sheet(report_sheet) |
|||
self._set_column_width() |
|||
|
|||
self.row_pos = 1 |
|||
|
|||
self.write_array_title(sheet_name) |
|||
self.row_pos += 2 |
|||
|
|||
self.write_array_header() |
|||
for move in moves: |
|||
for line in move.report_move_line_ids: |
|||
self.write_line(line) |
|||
self.row_pos += 1 |
|||
|
|||
def _generate_taxes_summary(self, workbook, report, sheet_name, tax_lines): |
|||
tax_journal_sheet = self.add_sheet(workbook, sheet_name) |
|||
self.set_sheet(tax_journal_sheet) |
|||
|
|||
self.row_pos = 1 |
|||
self.write_array_title(sheet_name) |
|||
self.row_pos += 2 |
|||
|
|||
tax_columns = self._get_journal_tax_columns(report) |
|||
self._set_columns_width(tax_columns) |
|||
|
|||
for col_pos, column in tax_columns.iteritems(): |
|||
self.sheet.write( |
|||
self.row_pos, col_pos, column['header'], |
|||
self.format_header_center |
|||
) |
|||
self.row_pos += 1 |
|||
for tax_line in tax_lines: |
|||
self._write_line(tax_columns, tax_line) |
|||
|
|||
|
|||
JournalXslx( |
|||
'report.account_financial_report_qweb.report_journal_xlsx', |
|||
'report_journal_qweb', |
|||
parser=report_sxw.rml_parse |
|||
) |
@ -0,0 +1,445 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<odoo> |
|||
|
|||
<template id="account_financial_report_qweb.report_journal_qweb"> |
|||
<t t-call="report.html_container"> |
|||
<t t-foreach="docs" t-as="o"> |
|||
<t t-call="account_financial_report_qweb.internal_layout"> |
|||
<t t-set="title">Journal Ledger</t> |
|||
<t t-set="company_name" t-value="o.company_id.name"/> |
|||
<t t-set="display_currency" t-value="o.with_currency"/> |
|||
<t t-set="display_account_name" t-value="o.with_account_name"/> |
|||
|
|||
<div class="page"> |
|||
<t t-if="o.group_option == 'none'"> |
|||
<div class="page_break"> |
|||
<t t-call="account_financial_report_qweb.report_journal_qweb_all"/> |
|||
<br/> |
|||
<t t-call="account_financial_report_qweb.report_journal_qweb_all_taxes"/> |
|||
</div> |
|||
</t> |
|||
<t t-if="o.group_option == 'journal'"> |
|||
<t t-foreach="o.report_journal_ids" t-as="journal"> |
|||
<div class="page_break"> |
|||
<t t-call="account_financial_report_qweb.report_journal_qweb_journal"/> |
|||
<br/> |
|||
<t t-call="account_financial_report_qweb.report_journal_qweb_journal_taxes"/> |
|||
<br/> |
|||
</div> |
|||
</t> |
|||
</t> |
|||
</div> |
|||
</t> |
|||
</t> |
|||
</t> |
|||
</template> |
|||
|
|||
<template id="account_financial_report_qweb.report_journal_qweb_all"> |
|||
<div class="act_as_table list_table" style="margin-top: 10px;"/> |
|||
<div class="act_as_table data_table" style="width: 1140px !important;"> |
|||
<t t-call="account_financial_report_qweb.report_journal_qweb_journal_table_header"/> |
|||
<t t-foreach="o.report_move_ids" t-as="move"> |
|||
<t t-call="account_financial_report_qweb.report_journal_qweb_move"/> |
|||
</t> |
|||
</div> |
|||
</template> |
|||
|
|||
<template id="account_financial_report_qweb.report_journal_qweb_journal"> |
|||
<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="journal.name"/> (<span t-field="journal.currency_id.name"/>) - <span t-field="o.date_from"/> to <span t-field="o.date_to"/> - <span t-field="o.move_target"/> Moves |
|||
</div> |
|||
|
|||
<div class="act_as_table data_table" style="width: 1140px !important;"> |
|||
<t t-call="account_financial_report_qweb.report_journal_qweb_journal_table_header"/> |
|||
<t t-call="account_financial_report_qweb.report_journal_qweb_journal_first_line"/> |
|||
<t t-foreach="journal.report_move_ids" t-as="move"> |
|||
<t t-call="account_financial_report_qweb.report_journal_qweb_move"/> |
|||
</t> |
|||
</div> |
|||
</template> |
|||
|
|||
<template id="account_financial_report_qweb.report_journal_qweb_journal_table_header"> |
|||
<t t-if="not display_account_name"> |
|||
<t t-set="account_column_style"> |
|||
width: 75px; |
|||
</t> |
|||
<t t-set="label_column_style"> |
|||
width: 360px; |
|||
</t> |
|||
</t> |
|||
<t t-else=""> |
|||
<t t-set="account_column_style"> |
|||
width: 220px; |
|||
</t> |
|||
<t t-set="label_column_style"> |
|||
width: 215px; |
|||
</t> |
|||
</t> |
|||
|
|||
<div class="act_as_thead"> |
|||
<div class="act_as_row labels"> |
|||
<div class="act_as_cell first_column" |
|||
name="entry" |
|||
style="width: 70px;"> |
|||
Entry |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="date" |
|||
style="width: 50px;"> |
|||
Date |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="account" t-att-style="account_column_style"> |
|||
Account |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="partner" |
|||
style="width: 140px;"> |
|||
Partner |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="label" t-att-style="label_column_style"> |
|||
Ref - Label |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="taxes" |
|||
style="width: 70px;"> |
|||
Taxes |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="debit" |
|||
style="width: 80px;"> |
|||
Debit |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="credit" |
|||
style="width: 80px;"> |
|||
Credit |
|||
</div> |
|||
<t t-if="display_currency"> |
|||
<div class="act_as_cell amount" |
|||
name="amount_currency" |
|||
style="width: 80px;"> |
|||
Currency |
|||
</div> |
|||
</t> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<template id="account_financial_report_qweb.report_journal_qweb_journal_first_line"> |
|||
<div class="act_as_row lines"> |
|||
<div class="act_as_cell" |
|||
name="entry"/> |
|||
<div class="act_as_cell" |
|||
name="date"/> |
|||
<div class="act_as_cell" |
|||
name="account"/> |
|||
<div class="act_as_cell" |
|||
name="partner"/> |
|||
<div class="act_as_cell" |
|||
name="label"/> |
|||
<div class="act_as_cell" |
|||
name="taxes"/> |
|||
<div class="act_as_cell amount" |
|||
name="debit"> |
|||
<b><span t-field="journal.debit"/></b> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="credit"> |
|||
<b><span t-field="journal.credit"/></b> |
|||
</div> |
|||
<t t-if="display_currency"> |
|||
<div class="act_as_cell amount" |
|||
name="amount_currency"> |
|||
</div> |
|||
</t> |
|||
</div> |
|||
<div style="width: 1140px !important;border-bottom: 1px solid black !important;height: 1px !important"/> |
|||
</template> |
|||
|
|||
<template id="account_financial_report_qweb.report_journal_qweb_move"> |
|||
<t t-set="display_move_info" t-value="True"/> |
|||
<t t-set="last_partner" t-eval="None"/> |
|||
<t t-set="display_partner" t-eval="True"/> |
|||
<t t-foreach="move.report_move_line_ids" t-as="move_line"> |
|||
<div class="act_as_row lines"> |
|||
<t t-set="current_partner" t-value="move_line.partner_id"/> |
|||
<t t-set="display_partner" t-value="current_partner != last_partner"/> |
|||
<t t-call="account_financial_report_qweb.report_journal_qweb_move_line"/> |
|||
<t t-set="last_partner" t-value="current_partner"/> |
|||
<t t-set="display_move_info" t-value="False"/> |
|||
</div> |
|||
</t> |
|||
</template> |
|||
|
|||
<template id="account_financial_report_qweb.report_journal_qweb_move_line"> |
|||
<div class="act_as_cell left" |
|||
name="entry"> |
|||
<span t-if="display_move_info" t-field="move_line.entry"/> |
|||
</div> |
|||
<div class="act_as_cell left" |
|||
name="date"> |
|||
<span t-if="display_move_info" t-field="move_line.date"/> |
|||
</div> |
|||
<div class="act_as_cell left" |
|||
name="account"> |
|||
<span t-field="move_line.account_code"/> |
|||
<span t-if="display_account_name"> |
|||
- <span t-field="move_line.account"/> |
|||
</span> |
|||
</div> |
|||
<div class="act_as_cell left" |
|||
name="partner"> |
|||
<span t-if="display_partner" t-field="move_line.partner"/> |
|||
</div> |
|||
<div class="act_as_cell left" |
|||
name="label"> |
|||
<span t-field="move_line.label"/> |
|||
</div> |
|||
<div class="act_as_cell left" |
|||
name="taxes"> |
|||
<span t-field="move_line.taxes_description"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="debit"> |
|||
<t t-if="move_line.debit"> |
|||
<span t-field="move_line.debit"/> |
|||
</t> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="credit"> |
|||
<t t-if="move_line.credit"> |
|||
<span t-field="move_line.credit"/> |
|||
</t> |
|||
</div> |
|||
<t t-if="display_currency"> |
|||
<div class="act_as_cell amount" |
|||
name="amount_currency"> |
|||
<t t-if="move_line.amount_currency"> |
|||
<span t-field="move_line.amount_currency"/> |
|||
</t> |
|||
</div> |
|||
</t> |
|||
</template> |
|||
|
|||
<template id="account_financial_report_qweb.report_journal_qweb_journal_taxes"> |
|||
<b>Taxes summary</b> |
|||
<div class="act_as_table data_table" style="width: 1130px !important; padding-bottom:0px !important;"> |
|||
<div class="act_as_thead"> |
|||
<div class="act_as_row labels"> |
|||
<div class="act_as_cell first_column" |
|||
name="name" |
|||
style="width: 350px;"> |
|||
Name |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="description" |
|||
style="width: 150px;"> |
|||
Description |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="base_amount" |
|||
style="width: 315px !important;"> |
|||
Base Amount |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="tax_amount" |
|||
style="width: 315px !important;"> |
|||
Tax Amount |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
</div> |
|||
|
|||
<div class="act_as_table data_table" style="width: 1130px !important; padding-top:0px !important"> |
|||
<div class="act_as_row labels"> |
|||
<div class="act_as_cell first_column" |
|||
name="name" |
|||
style="width: 350px;"/> |
|||
<div class="act_as_cell" |
|||
name="description" |
|||
style="width: 150px;"/> |
|||
<div class="act_as_cell" |
|||
name="base_debit" |
|||
style="width: 105px !important;"> |
|||
Debit |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="base_credit" |
|||
style="width: 105px !important;"> |
|||
Credit |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="base_balance" |
|||
style="width: 105px; !important"> |
|||
Balance |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="tax_debit" |
|||
style="width: 105px; !important"> |
|||
Debit |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="tax_credit" |
|||
style="width: 105px; !important"> |
|||
Credit |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="tax_balance" |
|||
style="width: 105px; !important"> |
|||
Balance |
|||
</div> |
|||
</div> |
|||
|
|||
<t t-foreach="journal.report_tax_line_ids" t-as="tax_line"> |
|||
<div class="act_as_row lines"> |
|||
<div class="act_as_cell left" |
|||
name="tax_name"> |
|||
<span t-field="tax_line.tax_name"/> |
|||
</div> |
|||
<div class="act_as_cell left" |
|||
name="tax_code"> |
|||
<span t-field="tax_line.tax_code"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="base_debit"> |
|||
<span t-field="tax_line.base_debit"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="base_credit"> |
|||
<span t-field="tax_line.base_credit"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="base_balance"> |
|||
<span t-field="tax_line.base_balance"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="tax_debit"> |
|||
<span t-field="tax_line.tax_debit"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="tax_credit"> |
|||
<span t-field="tax_line.tax_credit"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="tax_balance"> |
|||
<span t-field="tax_line.tax_balance"/> |
|||
</div> |
|||
</div> |
|||
</t> |
|||
</div> |
|||
</template> |
|||
|
|||
<template id="account_financial_report_qweb.report_journal_qweb_all_taxes"> |
|||
<b>Taxes summary</b> |
|||
<div class="act_as_table data_table" style="width: 1130px !important; padding-bottom:0px !important;"> |
|||
<div class="act_as_thead"> |
|||
<div class="act_as_row labels"> |
|||
<div class="act_as_cell first_column" |
|||
name="name" |
|||
style="width: 350px;"> |
|||
Name |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="description" |
|||
style="width: 150px;"> |
|||
Description |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="base_amount" |
|||
style="width: 315px !important;"> |
|||
Base Amount |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="tax_amount" |
|||
style="width: 315px !important;"> |
|||
Tax Amount |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
</div> |
|||
|
|||
<div class="act_as_table data_table" style="width: 1130px !important; padding-top:0px !important"> |
|||
<div class="act_as_row labels"> |
|||
<div class="act_as_cell first_column" |
|||
name="name" |
|||
style="width: 350px;"/> |
|||
<div class="act_as_cell" |
|||
name="description" |
|||
style="width: 150px;"/> |
|||
<div class="act_as_cell" |
|||
name="base_debit" |
|||
style="width: 105px !important;"> |
|||
Debit |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="base_credit" |
|||
style="width: 105px !important;"> |
|||
Credit |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="base_balance" |
|||
style="width: 105px; !important"> |
|||
Balance |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="tax_debit" |
|||
style="width: 105px; !important"> |
|||
Debit |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="tax_credit" |
|||
style="width: 105px; !important"> |
|||
Credit |
|||
</div> |
|||
<div class="act_as_cell" |
|||
name="tax_balance" |
|||
style="width: 105px; !important"> |
|||
Balance |
|||
</div> |
|||
</div> |
|||
|
|||
<t t-foreach="o.report_tax_line_ids" t-as="tax_line"> |
|||
<div class="act_as_row lines"> |
|||
<div class="act_as_cell left" |
|||
name="tax_name"> |
|||
<span t-field="tax_line.tax_name"/> |
|||
</div> |
|||
<div class="act_as_cell left" |
|||
name="tax_code"> |
|||
<span t-field="tax_line.tax_code"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="base_debit"> |
|||
<span t-field="tax_line.base_debit"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="base_credit"> |
|||
<span t-field="tax_line.base_credit"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="base_balance"> |
|||
<span t-field="tax_line.base_balance"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="tax_debit"> |
|||
<span t-field="tax_line.tax_debit"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="tax_credit"> |
|||
<span t-field="tax_line.tax_credit"/> |
|||
</div> |
|||
<div class="act_as_cell amount" |
|||
name="tax_balance"> |
|||
<span t-field="tax_line.tax_balance"/> |
|||
</div> |
|||
</div> |
|||
</t> |
|||
</div> |
|||
</template> |
|||
|
|||
</odoo> |
@ -0,0 +1,292 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 ACSONE SA/NV |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from datetime import datetime |
|||
from dateutil.relativedelta import relativedelta |
|||
|
|||
from odoo.fields import Date |
|||
from odoo.tests.common import TransactionCase |
|||
|
|||
|
|||
class TestJournalReport(TransactionCase): |
|||
|
|||
def setUp(self): |
|||
super(TestJournalReport, self).setUp() |
|||
self.AccountObj = self.env['account.account'] |
|||
self.InvoiceObj = self.env['account.invoice'] |
|||
self.JournalObj = self.env['account.journal'] |
|||
self.JournalReportObj = self.env['journal.report.wizard'] |
|||
self.MoveObj = self.env['account.move'] |
|||
self.ReportJournalQweb = self.env['report_journal_qweb'] |
|||
self.TaxObj = self.env['account.tax'] |
|||
|
|||
self.company = self.env.ref('base.main_company') |
|||
|
|||
today = datetime.today() |
|||
last_year = today - relativedelta(years=1) |
|||
|
|||
self.previous_fy_date_start = Date.to_string( |
|||
last_year.replace(month=1, day=1)) |
|||
self.previous_fy_date_end = Date.to_string( |
|||
last_year.replace(month=12, day=31)) |
|||
self.fy_date_start = Date.to_string( |
|||
today.replace(month=1, day=1)) |
|||
self.fy_date_end = Date.to_string( |
|||
today.replace(month=12, day=31)) |
|||
|
|||
self.receivable_account = self.AccountObj.search([ |
|||
('user_type_id.name', '=', 'Receivable') |
|||
], limit=1) |
|||
self.income_account = self.AccountObj.search([ |
|||
('user_type_id.name', '=', 'Income') |
|||
], limit=1) |
|||
self.payable_account = self.AccountObj.search([ |
|||
('user_type_id.name', '=', 'Payable') |
|||
], limit=1) |
|||
|
|||
self.journal_sale = self.JournalObj.create({ |
|||
'name': "Test journal sale", |
|||
'code': "TST-JRNL-S", |
|||
'type': 'sale', |
|||
'company_id': self.company.id, |
|||
}) |
|||
self.journal_purchase = self.JournalObj.create({ |
|||
'name': "Test journal purchase", |
|||
'code': "TST-JRNL-P", |
|||
'type': 'sale', |
|||
'company_id': self.company.id, |
|||
}) |
|||
|
|||
self.tax_15_s = self.TaxObj.create({ |
|||
'sequence': 30, |
|||
'name': 'Tax 15.0% (Percentage of Price)', |
|||
'amount': 15.0, |
|||
'amount_type': 'percent', |
|||
'include_base_amount': False, |
|||
'type_tax_use': 'sale', |
|||
}) |
|||
|
|||
self.tax_20_s = self.TaxObj.create({ |
|||
'sequence': 30, |
|||
'name': 'Tax 20.0% (Percentage of Price)', |
|||
'amount': 20.0, |
|||
'amount_type': 'percent', |
|||
'include_base_amount': False, |
|||
'type_tax_use': 'sale', |
|||
}) |
|||
|
|||
self.tax_15_p = self.TaxObj.create({ |
|||
'sequence': 30, |
|||
'name': 'Tax 15.0% (Percentage of Price)', |
|||
'amount': 15.0, |
|||
'amount_type': 'percent', |
|||
'include_base_amount': False, |
|||
'type_tax_use': 'purchase', |
|||
}) |
|||
|
|||
self.tax_20_p = self.TaxObj.create({ |
|||
'sequence': 30, |
|||
'name': 'Tax 20.0% (Percentage of Price)', |
|||
'amount': 20.0, |
|||
'amount_type': 'percent', |
|||
'include_base_amount': False, |
|||
'type_tax_use': 'purchase', |
|||
}) |
|||
|
|||
self.partner_2 = self.env.ref('base.res_partner_2') |
|||
|
|||
def _add_move( |
|||
self, date, journal, |
|||
receivable_debit, receivable_credit, income_debit, income_credit): |
|||
move_name = 'move name' |
|||
move_vals = { |
|||
'journal_id': journal.id, |
|||
'date': date, |
|||
'line_ids': [ |
|||
(0, 0, { |
|||
'name': move_name, |
|||
'debit': receivable_debit, |
|||
'credit': receivable_credit, |
|||
'account_id': self.receivable_account.id |
|||
}), |
|||
(0, 0, { |
|||
'name': move_name, |
|||
'debit': income_debit, |
|||
'credit': income_credit, |
|||
'account_id': self.income_account.id |
|||
}), |
|||
] |
|||
} |
|||
return self.MoveObj.create(move_vals) |
|||
|
|||
def check_report_journal_debit_credit( |
|||
self, report, expected_debit, expected_credit): |
|||
self.assertEqual( |
|||
expected_debit, |
|||
sum([journal.debit for journal in report.report_journal_ids]) |
|||
) |
|||
|
|||
self.assertEqual( |
|||
expected_credit, |
|||
sum([journal.credit for journal in report.report_journal_ids]) |
|||
) |
|||
|
|||
def check_report_journal_debit_credit_taxes( |
|||
self, report, |
|||
expected_base_debit, expected_base_credit, |
|||
expected_tax_debit, expected_tax_credit): |
|||
|
|||
self.assertEqual( |
|||
expected_base_debit, |
|||
sum([ |
|||
journal.base_debit |
|||
for journal in report.report_journal_tax_line_ids |
|||
]) |
|||
) |
|||
self.assertEqual( |
|||
expected_base_credit, |
|||
sum([ |
|||
journal.base_credit |
|||
for journal in report.report_journal_tax_line_ids |
|||
]) |
|||
) |
|||
self.assertEqual( |
|||
expected_tax_debit, |
|||
sum([ |
|||
journal.tax_debit |
|||
for journal in report.report_journal_tax_line_ids |
|||
]) |
|||
) |
|||
self.assertEqual( |
|||
expected_tax_credit, |
|||
sum([ |
|||
journal.tax_credit |
|||
for journal in report.report_journal_tax_line_ids |
|||
]) |
|||
) |
|||
|
|||
def test_01_test_total(self): |
|||
today_date = Date.today() |
|||
last_year_date = Date.to_string( |
|||
datetime.today() - relativedelta(years=1)) |
|||
|
|||
move1 = self._add_move( |
|||
today_date, self.journal_sale, |
|||
0, 100, 100, 0) |
|||
move2 = self._add_move( |
|||
last_year_date, self.journal_sale, |
|||
0, 100, 100, 0) |
|||
|
|||
report = self.ReportJournalQweb.create({ |
|||
'date_from': self.fy_date_start, |
|||
'date_to': self.fy_date_end, |
|||
'company_id': self.company.id, |
|||
'journal_ids': [(6, 0, [self.journal_sale.ids])] |
|||
}) |
|||
report.compute_data_for_report() |
|||
|
|||
self.check_report_journal_debit_credit(report, 100, 100) |
|||
|
|||
move3 = self._add_move( |
|||
today_date, self.journal_sale, |
|||
0, 100, 100, 0) |
|||
|
|||
report.refresh() |
|||
self.check_report_journal_debit_credit(report, 200, 200) |
|||
|
|||
report.move_target = 'posted' |
|||
report.refresh() |
|||
self.check_report_journal_debit_credit(report, 0, 0) |
|||
|
|||
move1.post() |
|||
report.refresh() |
|||
self.check_report_journal_debit_credit(report, 100, 100) |
|||
|
|||
move2.post() |
|||
report.refresh() |
|||
self.check_report_journal_debit_credit(report, 100, 100) |
|||
|
|||
move3.post() |
|||
report.refresh() |
|||
self.check_report_journal_debit_credit(report, 200, 200) |
|||
|
|||
report.date_from = self.previous_fy_date_start |
|||
report.refresh() |
|||
self.check_report_journal_debit_credit(report, 300, 300) |
|||
|
|||
def test_02_test_taxes_out_invoice(self): |
|||
invoice_values = { |
|||
'journal_id': self.journal_sale.id, |
|||
'partner_id': self.partner_2.id, |
|||
'type': 'out_invoice', |
|||
'invoice_line_ids': [ |
|||
(0, 0, { |
|||
'quantity': 1.0, |
|||
'price_unit': 100, |
|||
'account_id': self.receivable_account.id, |
|||
'name': "Test", |
|||
'invoice_line_tax_ids': [(6, 0, [self.tax_15_s.id])], |
|||
}), |
|||
(0, 0, { |
|||
'quantity': 1.0, |
|||
'price_unit': 100, |
|||
'account_id': self.receivable_account.id, |
|||
'name': "Test", |
|||
'invoice_line_tax_ids': [(6, 0, [ |
|||
self.tax_15_s.id, self.tax_20_s.id |
|||
])], |
|||
}) |
|||
] |
|||
} |
|||
invoice = self.InvoiceObj.create(invoice_values) |
|||
invoice.action_invoice_open() |
|||
|
|||
report = self.ReportJournalQweb.create({ |
|||
'date_from': self.fy_date_start, |
|||
'date_to': self.fy_date_end, |
|||
'company_id': self.company.id, |
|||
'journal_ids': [(6, 0, [self.journal_sale.ids])] |
|||
}) |
|||
report.compute_data_for_report() |
|||
|
|||
self.check_report_journal_debit_credit(report, 250, 250) |
|||
self.check_report_journal_debit_credit_taxes(report, 0, 300, 0, 50) |
|||
|
|||
def test_03_test_taxes_in_invoice(self): |
|||
invoice_values = { |
|||
'journal_id': self.journal_sale.id, |
|||
'partner_id': self.partner_2.id, |
|||
'type': 'in_invoice', |
|||
'invoice_line_ids': [ |
|||
(0, 0, { |
|||
'quantity': 1.0, |
|||
'price_unit': 100, |
|||
'account_id': self.payable_account.id, |
|||
'name': "Test", |
|||
'invoice_line_tax_ids': [(6, 0, [self.tax_15_p.id])], |
|||
}), |
|||
(0, 0, { |
|||
'quantity': 1.0, |
|||
'price_unit': 100, |
|||
'account_id': self.payable_account.id, |
|||
'name': "Test", |
|||
'invoice_line_tax_ids': [(6, 0, [ |
|||
self.tax_15_p.id, self.tax_20_p.id |
|||
])], |
|||
}) |
|||
] |
|||
} |
|||
invoice = self.InvoiceObj.create(invoice_values) |
|||
invoice.action_invoice_open() |
|||
|
|||
report = self.ReportJournalQweb.create({ |
|||
'date_from': self.fy_date_start, |
|||
'date_to': self.fy_date_end, |
|||
'company_id': self.company.id, |
|||
'journal_ids': [(6, 0, [self.journal_sale.ids])] |
|||
}) |
|||
report.compute_data_for_report() |
|||
|
|||
self.check_report_journal_debit_credit(report, 250, 250) |
|||
self.check_report_journal_debit_credit_taxes(report, 300, 0, 50, 0) |
@ -0,0 +1,119 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 ACSONE SA/NV |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
|||
|
|||
from odoo import api, fields, models, _ |
|||
|
|||
|
|||
class JournalReportWizard(models.TransientModel): |
|||
|
|||
_name = 'journal.report.wizard' |
|||
|
|||
company_id = fields.Many2one( |
|||
comodel_name='res.company', |
|||
default=lambda self: self.env.user.company_id, |
|||
string='Company', |
|||
required=True, |
|||
ondelete='cascade', |
|||
) |
|||
date_range_id = fields.Many2one( |
|||
comodel_name='date.range', |
|||
string='Date range', |
|||
domain="['|', " |
|||
"('company_id', '=', False)," |
|||
"('company_id', '=', company_id)]", |
|||
) |
|||
date_from = fields.Date( |
|||
string="Start date", |
|||
required=True |
|||
) |
|||
date_to = fields.Date( |
|||
string="End date", |
|||
required=True |
|||
) |
|||
journal_ids = fields.Many2many( |
|||
comodel_name='account.journal', |
|||
string="Journals", |
|||
domain="[('company_id', '=', company_id)]", |
|||
required=True, |
|||
) |
|||
move_target = fields.Selection( |
|||
selection='_get_move_targets', |
|||
default='all', |
|||
required=True, |
|||
) |
|||
with_currency = fields.Boolean() |
|||
sort_option = fields.Selection( |
|||
selection='_get_sort_options', |
|||
string="Sort entries by", |
|||
default='move_name', |
|||
required=True, |
|||
) |
|||
group_option = fields.Selection( |
|||
selection='_get_group_options', |
|||
string="Group entries by", |
|||
default='journal', |
|||
required=True, |
|||
) |
|||
with_account_name = fields.Boolean( |
|||
default=False, |
|||
) |
|||
|
|||
@api.model |
|||
def _get_move_targets(self): |
|||
return [ |
|||
('all', _("All")), |
|||
('posted', _("Posted")), |
|||
('draft', _("Not Posted")) |
|||
] |
|||
|
|||
@api.model |
|||
def _get_sort_options(self): |
|||
return [ |
|||
('move_name', _("Entry number")), |
|||
('date', _("Date")), |
|||
] |
|||
|
|||
@api.model |
|||
def _get_group_options(self): |
|||
return [ |
|||
('journal', _("Journal")), |
|||
('none', _("No group")), |
|||
] |
|||
|
|||
@api.onchange('date_range_id') |
|||
def onchange_date_range_id(self): |
|||
self.date_from = self.date_range_id.date_start |
|||
self.date_to = self.date_range_id.date_end |
|||
|
|||
@api.multi |
|||
def export_as_pdf(self): |
|||
self.ensure_one() |
|||
return self._export() |
|||
|
|||
@api.multi |
|||
def export_as_xlsx(self): |
|||
self.ensure_one() |
|||
return self._export(xlsx_report=True) |
|||
|
|||
@api.multi |
|||
def _prepare_report_journal(self): |
|||
self.ensure_one() |
|||
return { |
|||
'date_from': self.date_from, |
|||
'date_to': self.date_to, |
|||
'move_target': self.move_target, |
|||
'with_currency': self.with_currency, |
|||
'company_id': self.company_id.id, |
|||
'journal_ids': [(6, 0, self.journal_ids.ids)], |
|||
'sort_option': self.sort_option, |
|||
'group_option': self.group_option, |
|||
'with_account_name': self.with_account_name, |
|||
} |
|||
|
|||
@api.multi |
|||
def _export(self, xlsx_report=False): |
|||
self.ensure_one() |
|||
model = self.env['report_journal_qweb'] |
|||
report = model.create(self._prepare_report_journal()) |
|||
return report.print_report(xlsx_report=xlsx_report) |
@ -0,0 +1,66 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2017 ACSONE SA/NV |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
|||
|
|||
<odoo> |
|||
|
|||
<record model="ir.ui.view" id="journal_report_wizard_form_view"> |
|||
<field name="name">journal.report.wizard.form (in account_financial_report_qweb)</field> |
|||
<field name="model">journal.report.wizard</field> |
|||
<field name="arch" type="xml"> |
|||
<form> |
|||
<group> |
|||
<field name="company_id" groups="base.group_multi_company"/> |
|||
</group> |
|||
|
|||
<separator string="Periods"/> |
|||
<group> |
|||
<group> |
|||
<field name="date_range_id"/> |
|||
<field name="date_from"/> |
|||
<field name="date_to"/> |
|||
</group> |
|||
<group/> |
|||
</group> |
|||
|
|||
<separator string="Options"/> |
|||
<group name="options"> |
|||
<group> |
|||
<field name="move_target" widget="radio" options="{'horizontal': true}"/> |
|||
<field name="sort_option"/> |
|||
<field name="group_option"/> |
|||
<field name="with_currency"/> |
|||
<field name="with_account_name"/> |
|||
</group> |
|||
<group/> |
|||
</group> |
|||
|
|||
<separator string="Journals"/> |
|||
<group> |
|||
<field name="journal_ids" widget="many2many_tags"/> |
|||
</group> |
|||
|
|||
<footer> |
|||
<button name="export_as_pdf" |
|||
string="Print" class="btn-primary" |
|||
type="object"/> |
|||
<button name="export_as_xlsx" |
|||
string="Export" class="btn-primary" |
|||
type="object"/> |
|||
<button string="Cancel" |
|||
class="btn-default" |
|||
special="cancel"/> |
|||
</footer> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.actions.act_window" id="journal_report_wizard_act_window"> |
|||
<field name="name">Journal Ledger Report Wizard</field> |
|||
<field name="res_model">journal.report.wizard</field> |
|||
<field name="view_mode">form</field> |
|||
<field name="context">{}</field> |
|||
<field name="target">new</field> |
|||
</record> |
|||
|
|||
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue