You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

444 lines
15 KiB

# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo.tests import common
from odoo.tools import test_reports
_logger = logging.getLogger(__name__)
class AbstractTest(common.TransactionCase):
"""Common technical tests for all reports."""
at_install = False
post_install = True
accounts = {}
def with_context(self, *args, **kwargs):
context = dict(args[0] if args else self.env.context, **kwargs)
self.env = self.env(context=context)
return self
def _chart_template_create(self):
transfer_account_id = self.env["account.account.template"].create(
{
"code": "000",
"name": "Liquidity Transfers",
"reconcile": True,
"user_type_id": self.ref("account.data_account_type_current_assets"),
}
)
self.chart = self.env["account.chart.template"].create(
{
"name": "Test COA",
"code_digits": 4,
"bank_account_code_prefix": 1014,
"cash_account_code_prefix": 1014,
"currency_id": self.ref("base.USD"),
"transfer_account_code_prefix": "000",
}
)
transfer_account_id.update(
{"chart_template_id": self.chart.id,}
)
self.env["ir.model.data"].create(
{
"res_id": transfer_account_id.id,
"model": transfer_account_id._name,
"name": "Liquidity Transfers",
}
)
act = self.env["account.account.template"].create(
{
"code": "001",
"name": "Expenses",
"user_type_id": self.ref("account.data_account_type_expenses"),
"chart_template_id": self.chart.id,
"reconcile": True,
}
)
self.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "expenses",}
)
act = self.env["account.account.template"].create(
{
"code": "002",
"name": "Product Sales",
"user_type_id": self.ref("account.data_account_type_revenue"),
"chart_template_id": self.chart.id,
"reconcile": True,
}
)
self.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "sales",}
)
act = self.env["account.account.template"].create(
{
"code": "003",
"name": "Account Receivable",
"user_type_id": self.ref("account.data_account_type_receivable"),
"chart_template_id": self.chart.id,
"reconcile": True,
}
)
self.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "receivable",}
)
act = self.env["account.account.template"].create(
{
"code": "004",
"name": "Account Payable",
"user_type_id": self.ref("account.data_account_type_payable"),
"chart_template_id": self.chart.id,
"reconcile": True,
}
)
self.env["ir.model.data"].create(
{"res_id": act.id, "model": act._name, "name": "payable",}
)
def _add_chart_of_accounts(self):
self.company = self.env["res.company"].create({"name": "Spanish test company",})
self.env.ref("base.group_multi_company").write(
{"users": [(4, self.env.uid)],}
)
self.env.user.write(
{"company_ids": [(4, self.company.id)], "company_id": self.company.id,}
)
self.with_context(company_id=self.company.id, force_company=self.company.id)
self.chart.try_loading_for_current_company()
self.revenue = self.env["account.account"].search(
[("user_type_id", "=", self.ref("account.data_account_type_revenue"))],
limit=1,
)
self.expense = self.env["account.account"].search(
[("user_type_id", "=", self.ref("account.data_account_type_expenses"))],
limit=1,
)
self.receivable = self.env["account.account"].search(
[("user_type_id", "=", self.ref("account.data_account_type_receivable"))],
limit=1,
)
self.payable = self.env["account.account"].search(
[("user_type_id", "=", self.ref("account.data_account_type_payable"))],
limit=1,
)
return True
def _journals_create(self):
self.journal_sale = self.env["account.journal"].create(
{
"company_id": self.company.id,
"name": "Test journal for sale",
"type": "sale",
"code": "TSALE",
"default_debit_account_id": self.revenue.id,
"default_credit_account_id": self.revenue.id,
}
)
self.journal_purchase = self.env["account.journal"].create(
{
"company_id": self.company.id,
"name": "Test journal for purchase",
"type": "purchase",
"code": "TPUR",
"default_debit_account_id": self.expense.id,
"default_credit_account_id": self.expense.id,
}
)
return True
def _invoice_create(self):
self.partner = self.env["res.partner"].create(
{
"name": "Test partner",
"company_id": self.company.id,
"property_account_receivable_id": self.receivable.id,
"property_account_payable_id": self.payable.id,
}
)
# customer invoice
customer_invoice_lines = [
(
0,
False,
{
"name": "Test description #1",
"account_id": self.revenue.id,
"quantity": 1.0,
"price_unit": 100.0,
},
),
(
0,
False,
{
"name": "Test description #2",
"account_id": self.revenue.id,
"quantity": 2.0,
"price_unit": 25.0,
},
),
]
self.invoice_out = self.env["account.invoice"].create(
{
"partner_id": self.partner.id,
"type": "out_invoice",
"invoice_line_ids": customer_invoice_lines,
"account_id": self.partner.property_account_receivable_id.id,
"journal_id": self.journal_sale.id,
}
)
self.invoice_out.action_invoice_open()
# vendor bill
vendor_invoice_lines = [
(
0,
False,
{
"name": "Test description #1",
"account_id": self.revenue.id,
"quantity": 1.0,
"price_unit": 100.0,
},
),
(
0,
False,
{
"name": "Test description #2",
"account_id": self.revenue.id,
"quantity": 2.0,
"price_unit": 25.0,
},
),
]
self.invoice_in = self.env["account.invoice"].create(
{
"partner_id": self.partner.id,
"type": "in_invoice",
"invoice_line_ids": vendor_invoice_lines,
"account_id": self.partner.property_account_payable_id.id,
"journal_id": self.journal_purchase.id,
}
)
self.invoice_in.action_invoice_open()
def setUp(self):
super(AbstractTest, self).setUp()
self.with_context()
self._chart_template_create()
self._add_chart_of_accounts()
self._journals_create()
self._invoice_create()
self.model = self._getReportModel()
self.qweb_report_name = self._getQwebReportName()
self.xlsx_report_name = self._getXlsxReportName()
self.xlsx_action_name = self._getXlsxReportActionName()
self.report_title = self._getReportTitle()
self.base_filters = self._getBaseFilters()
self.additional_filters = self._getAdditionalFiltersToBeTested()
self.report = self.model.create(self.base_filters)
self.report.compute_data_for_report()
def test_html(self):
test_reports.try_report(
self.env.cr,
self.env.uid,
self.qweb_report_name,
[self.report.id],
report_type="qweb-html",
)
def test_qweb(self):
test_reports.try_report(
self.env.cr,
self.env.uid,
self.qweb_report_name,
[self.report.id],
report_type="qweb-pdf",
)
def test_xlsx(self):
test_reports.try_report(
self.env.cr,
self.env.uid,
self.xlsx_report_name,
[self.report.id],
report_type="xlsx",
)
def test_print(self):
self.report.print_report("qweb")
self.report.print_report("xlsx")
def test_02_generation_report_html(self):
"""Check if report HTML is correctly generated"""
# Check if returned report action is correct
report_type = "qweb-html"
report_action = self.report.print_report(report_type)
self.assertDictContainsSubset(
{
"type": "ir.actions.report",
"report_name": self.qweb_report_name,
"report_type": "qweb-html",
},
report_action,
)
# Check if report template is correct
report = self.env["ir.actions.report"].search(
[
("report_name", "=", self.qweb_report_name),
("report_type", "=", report_type),
],
limit=1,
)
self.assertEqual(report.report_type, "qweb-html")
rep = report.render(self.report.ids, {})
self.assertTrue(self.report_title.encode("utf8") in rep[0])
self.assertTrue(self.report.account_ids[0].name.encode("utf8") in rep[0])
def test_04_compute_data(self):
"""Check that the SQL queries work with all filters options"""
for filters in [{}] + self.additional_filters:
current_filter = self.base_filters.copy()
current_filter.update(filters)
report = self.model.create(current_filter)
report.compute_data_for_report()
self.assertGreaterEqual(len(report.account_ids), 1)
# Same filters with only one account
current_filter = self.base_filters.copy()
current_filter.update(filters)
report_accounts = report.account_ids.filtered("account_id")
current_filter.update(
{"filter_account_ids": [(6, 0, report_accounts[0].account_id.ids)],}
)
report2 = self.model.create(current_filter)
report2.compute_data_for_report()
self.assertEqual(len(report2.account_ids), 1)
self.assertEqual(report2.account_ids.name, report_accounts[0].name)
if self._partner_test_is_possible(filters):
# Same filters with only one partner
report_partner_ids = report.account_ids.mapped("partner_ids")
partner_ids = report_partner_ids.mapped("partner_id")
current_filter = self.base_filters.copy()
current_filter.update(filters)
current_filter.update(
{"filter_partner_ids": [(6, 0, partner_ids[0].ids)],}
)
report3 = self.model.create(current_filter)
report3.compute_data_for_report()
self.assertGreaterEqual(len(report3.account_ids), 1)
report_partner_ids3 = report3.account_ids.mapped("partner_ids")
partner_ids3 = report_partner_ids3.mapped("partner_id")
self.assertEqual(len(partner_ids3), 1)
self.assertEqual(partner_ids3.name, partner_ids[0].name)
# Same filters with only one partner and one account
report_partner_ids = report3.account_ids.mapped("partner_ids")
report_account_id = report_partner_ids.filtered(lambda p: p.partner_id)[
0
].report_account_id
current_filter = self.base_filters.copy()
current_filter.update(filters)
current_filter.update(
{
"filter_account_ids": [
(6, 0, report_account_id.account_id.ids)
],
"filter_partner_ids": [(6, 0, partner_ids[0].ids)],
}
)
report4 = self.model.create(current_filter)
report4.compute_data_for_report()
self.assertEqual(len(report4.account_ids), 1)
self.assertEqual(
report4.account_ids.name, report_account_id.account_id.name
)
report_partner_ids4 = report4.account_ids.mapped("partner_ids")
partner_ids4 = report_partner_ids4.mapped("partner_id")
self.assertEqual(len(partner_ids4), 1)
self.assertEqual(partner_ids4.name, partner_ids[0].name)
def _partner_test_is_possible(self, filters):
"""
:return:
a boolean to indicate if partner test is possible
with current filters
"""
return True
def _getReportModel(self):
"""
:return: the report model name
"""
raise NotImplementedError()
def _getQwebReportName(self):
"""
:return: the qweb report name
"""
raise NotImplementedError()
def _getXlsxReportName(self):
"""
:return: the xlsx report name
"""
raise NotImplementedError()
def _getXlsxReportActionName(self):
"""
:return: the xlsx report action name
"""
raise NotImplementedError()
def _getReportTitle(self):
"""
:return: the report title displayed into the report
"""
raise NotImplementedError()
def _getBaseFilters(self):
"""
:return: the minimum required filters to generate report
"""
raise NotImplementedError()
def _getAdditionalFiltersToBeTested(self):
"""
:return: the additional filters to generate report variants
"""
raise NotImplementedError()