Purpose ======= Make it possible to compare analytic values between plans by inputting up to one account per plan on each line. For instance, if we have 2 plans: "Country" and "Product Type", with the following accounts | Country | Product Type | | ------- | ------------ | | BE | Drinks | | LU | Food | And the following invoices: * 1000€ of drinks in Belgium * 2000€ of food in Belgium * 3000€ of food in Luxemburg We want to be able to display the following pivot tables: | | Drinks | Food | Total | | --- | ------ | ---- | ----- | | BE | 1000 | 2000 | 3000 | | LU | 0 | 3000 | 3000 | | Tot | 1000 | 5000 | 6000 | | | Total | | ------ | ----- | | Food | 5000 | | * BE | 2000 | | * LU | 3000 | | Drinks | 1000 | | * BE | 1000 | | Total | 6000 | Implementation ============== * `ir.fields` are added/removed dynamically on `account.analytic.line` * Each analytic plan corresponds to one field on `account.analytic.line` * The fields are added dynamically in the views. * `account.analytic.plan` doesn't have a `company_id` field anymore, meaning that all the companies have access to all the plans. This means that the applicability fields and lines are now company dependent, and those can be used to know which fields/plans to display for which company. * There can no longer be one "Project" plan per company, even if the accounts of that project can still be owned by only one company. * There is now only one method to get the default (or "Project" plan), which is `_get_plan_columns` task-3497653 closes odoo/odoo#139225 Related: odoo/upgrade#5306 Related: odoo/enterprise#49226 Signed-off-by: William André (wan) <wan@odoo.com> Co-authored-by: william <wan@odoo.com> Co-authored-by: h4818 <ayh@odoo.com>
189 lines
9.4 KiB
Python
189 lines
9.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo.tests import tagged
|
|
from odoo.tests.common import TransactionCase
|
|
from odoo import Command
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestAnalyticAccount(TransactionCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
|
|
# Create new user to avoid demo data.
|
|
user = cls.env['res.users'].create({
|
|
'name': 'The anal(ytic) expert!',
|
|
'login': 'analytic',
|
|
'password': 'analytic',
|
|
'groups_id': [
|
|
(6, 0, cls.env.user.groups_id.ids),
|
|
(4, cls.env.ref('analytic.group_analytic_accounting').id),
|
|
],
|
|
})
|
|
user.partner_id.email = 'analyticman@test.com'
|
|
|
|
# Shadow the current environment/cursor with one having the report user.
|
|
# This is mandatory to test access rights.
|
|
cls.env = cls.env(user=user)
|
|
cls.cr = cls.env.cr
|
|
|
|
cls.company_data = cls.env['res.company'].create({
|
|
'name': 'company_data',
|
|
})
|
|
cls.env.user.company_ids |= cls.company_data
|
|
|
|
user.write({
|
|
'company_ids': [(6, 0, cls.company_data.ids)],
|
|
'company_id': cls.company_data.id,
|
|
})
|
|
cls.analytic_plan_offset = len(cls.env['account.analytic.plan'].get_relevant_plans())
|
|
|
|
cls.analytic_plan_1 = cls.env['account.analytic.plan'].create({
|
|
'name': 'Plan 1',
|
|
'default_applicability': 'unavailable',
|
|
})
|
|
cls.analytic_plan_child = cls.env['account.analytic.plan'].create({
|
|
'name': 'Plan Child',
|
|
'parent_id': cls.analytic_plan_1.id,
|
|
})
|
|
cls.analytic_plan_2 = cls.env['account.analytic.plan'].create({
|
|
'name': 'Plan 2',
|
|
})
|
|
|
|
cls.partner_a = cls.env['res.partner'].create({'name': 'partner_a', 'company_id': False})
|
|
cls.partner_b = cls.env['res.partner'].create({'name': 'partner_b', 'company_id': False})
|
|
|
|
cls.analytic_account_1 = cls.env['account.analytic.account'].create({'name': 'Account 1', 'plan_id': cls.analytic_plan_1.id})
|
|
cls.analytic_account_2 = cls.env['account.analytic.account'].create({'name': 'Account 2', 'plan_id': cls.analytic_plan_child.id})
|
|
cls.analytic_account_3 = cls.env['account.analytic.account'].create({'name': 'Account 3', 'plan_id': cls.analytic_plan_2.id})
|
|
|
|
cls.distribution_1 = cls.env['account.analytic.distribution.model'].create({
|
|
'partner_id': cls.partner_a.id,
|
|
'analytic_distribution': {cls.analytic_account_3.id: 100}
|
|
})
|
|
|
|
cls.distribution_2 = cls.env['account.analytic.distribution.model'].create({
|
|
'partner_id': cls.partner_b.id,
|
|
'analytic_distribution': {cls.analytic_account_2.id: 100}
|
|
})
|
|
|
|
def test_get_plans_without_options(self):
|
|
""" Test that the plans with the good appliability are returned without if no options are given """
|
|
kwargs = {}
|
|
plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
|
|
self.assertEqual(1, len(plans_json) - self.analytic_plan_offset, "Only the Default plan and the demo data plans should be available")
|
|
|
|
self.analytic_plan_1.write({'default_applicability': 'mandatory'})
|
|
plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
|
|
self.assertEqual(2, len(plans_json) - self.analytic_plan_offset, "All root plans should be available")
|
|
|
|
def test_get_plans_with_option(self):
|
|
""" Test the plans returned with applicability rules and options """
|
|
kwargs = {'business_domain': 'general'}
|
|
plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
|
|
self.assertEqual(1, len(plans_json) - self.analytic_plan_offset, "Only the Default plan and the demo data plans should be available")
|
|
|
|
applicability = self.env['account.analytic.applicability'].create({
|
|
'business_domain': 'general',
|
|
'analytic_plan_id': self.analytic_plan_1.id,
|
|
'applicability': 'mandatory'
|
|
})
|
|
plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
|
|
self.assertEqual(2, len(plans_json) - self.analytic_plan_offset, "All root plans should be available")
|
|
|
|
self.analytic_plan_1.write({'default_applicability': 'mandatory'})
|
|
applicability.write({'applicability': 'unavailable'})
|
|
plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
|
|
self.assertEqual(1, len(plans_json) - self.analytic_plan_offset, "Plan 1 should be unavailable")
|
|
|
|
kwargs = {'business_domain': 'purchase_order'}
|
|
plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
|
|
self.assertEqual(2, len(plans_json) - self.analytic_plan_offset, "Both plans should be available")
|
|
|
|
kwargs = {'applicability': 'optional'}
|
|
plans_json = self.env['account.analytic.plan'].get_relevant_plans(**kwargs)
|
|
self.assertEqual(2, len(plans_json) - self.analytic_plan_offset, "All root plans should be available")
|
|
|
|
def test_analytic_distribution_model(self):
|
|
""" Test the distribution returned from the distribution model """
|
|
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({})
|
|
self.assertEqual(distribution_json, {}, "No distribution should be given")
|
|
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
|
|
"partner_id": self.partner_a.id,
|
|
"company_id": self.company_data.id,
|
|
})
|
|
self.assertEqual(distribution_json, {str(self.analytic_account_3.id): 100}, "Distribution 1 should be given")
|
|
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
|
|
"partner_id": self.partner_b.id,
|
|
"company_id": self.company_data.id,
|
|
})
|
|
self.assertEqual(distribution_json, {str(self.analytic_account_2.id): 100}, "Distribution 2 should be given")
|
|
|
|
def test_order_analytic_distribution_model(self):
|
|
""" Test the distribution returned with company field"""
|
|
distribution_3 = self.env['account.analytic.distribution.model'].create({
|
|
'partner_id': self.partner_a.id,
|
|
'analytic_distribution': {self.analytic_account_1.id: 100},
|
|
'company_id': self.company_data.id,
|
|
})
|
|
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({})
|
|
self.assertEqual(distribution_json, {}, "No distribution should be given")
|
|
|
|
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
|
|
"partner_id": self.partner_a.id,
|
|
"company_id": self.company_data.id,
|
|
})
|
|
self.assertEqual(distribution_json, distribution_3.analytic_distribution,
|
|
"Distribution 3 should be given, as the company is specified in the model")
|
|
|
|
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
|
|
"partner_id": self.partner_b.id,
|
|
"company_id": self.company_data.id,
|
|
})
|
|
self.assertEqual(distribution_json, {str(self.analytic_account_2.id): 100},
|
|
"Distribution 2 should be given, for the partner")
|
|
|
|
partner_category = self.env['res.partner.category'].create({'name': 'partner_categ'})
|
|
self.partner_a.write({
|
|
'category_id': [Command.set([partner_category.id])]
|
|
})
|
|
|
|
distribution_4 = self.env['account.analytic.distribution.model'].create({
|
|
'partner_id': self.partner_a.id,
|
|
'analytic_distribution': {self.analytic_account_1.id: 100, self.analytic_account_2.id: 100},
|
|
'partner_category_id': partner_category.id,
|
|
})
|
|
|
|
distribution_json = self.env['account.analytic.distribution.model']._get_distribution({
|
|
"partner_id": self.partner_a.id,
|
|
"company_id": self.company_data.id,
|
|
"partner_category_id": partner_category.ids,
|
|
})
|
|
self.assertEqual(distribution_json, distribution_4.analytic_distribution,
|
|
"Distribution 4 should be given, as the partner_category_id is better than the company_id")
|
|
|
|
def test_analytic_plan_account_child(self):
|
|
"""
|
|
Check that when an analytic account is set to the third (or more) child,
|
|
the root plan is correctly retrieved.
|
|
"""
|
|
self.analytic_plan = self.env['account.analytic.plan'].create({
|
|
'name': 'Parent Plan',
|
|
})
|
|
self.analytic_sub_plan = self.env['account.analytic.plan'].create({
|
|
'name': 'Sub Plan',
|
|
'parent_id': self.analytic_plan.id,
|
|
})
|
|
self.analytic_sub_sub_plan = self.env['account.analytic.plan'].create({
|
|
'name': 'Sub Sub Plan',
|
|
'parent_id': self.analytic_sub_plan.id,
|
|
})
|
|
self.env['account.analytic.account'].create({'name': 'Account', 'plan_id': self.analytic_plan.id})
|
|
self.env['account.analytic.account'].create({'name': 'Child Account', 'plan_id': self.analytic_sub_plan.id})
|
|
self.env['account.analytic.account'].create({'name': 'Grand Child Account', 'plan_id': self.analytic_sub_sub_plan.id})
|
|
plans_json = self.env['account.analytic.plan'].get_relevant_plans()
|
|
self.assertEqual(2, len(plans_json) - self.analytic_plan_offset,
|
|
"The parent plan should be available even if the analytic account is set on child of third generation")
|