Initial commit: Odoo 18.0-20251222 extra-addons
This commit is contained in:
4
account_move_template/tests/__init__.py
Executable file
4
account_move_template/tests/__init__.py
Executable file
@@ -0,0 +1,4 @@
|
||||
# Needs to be re-written because wizard.multi.charts.accounts
|
||||
# doesn't exist any more on v12
|
||||
# from . import test_account_move_template
|
||||
from . import test_account_move_template_options
|
||||
215
account_move_template/tests/test_account_move_template.py
Executable file
215
account_move_template/tests/test_account_move_template.py
Executable file
@@ -0,0 +1,215 @@
|
||||
# Copyright 2018-2019 ForgeFlow, S.L.
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
import logging
|
||||
|
||||
from psycopg2 import IntegrityError
|
||||
|
||||
from odoo import Command, fields
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestAccountMoveTemplate(TransactionCase):
|
||||
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_of_accounts_create(self, company, chart):
|
||||
_logger.debug("Creating chart of account")
|
||||
self.env.user.write(
|
||||
{"company_ids": [Command.link(company.id)], "company_id": company.id}
|
||||
)
|
||||
self.with_context(company_id=company.id, force_company=company.id)
|
||||
wizard = self.env["wizard.multi.charts.accounts"].create(
|
||||
{
|
||||
"company_id": company.id,
|
||||
"chart_template_id": chart.id,
|
||||
"code_digits": 6,
|
||||
"currency_id": self.env.ref("base.EUR").id,
|
||||
"transfer_account_id": chart.transfer_account_id.id,
|
||||
}
|
||||
)
|
||||
wizard.onchange_chart_template_id()
|
||||
wizard.execute()
|
||||
return True
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
employees_group = self.env.ref("base.group_user")
|
||||
multi_company_group = self.env.ref("base.group_multi_company")
|
||||
account_user_group = self.env.ref("account.group_account_user")
|
||||
account_manager_group = self.env.ref("account.group_account_manager")
|
||||
self.company = self.env["res.company"].create({"name": "Test company"})
|
||||
self.company_2 = self.env["res.company"].create(
|
||||
{"name": "Test company 2", "parent_id": self.company.id}
|
||||
)
|
||||
self.env.user.company_ids += self.company
|
||||
self.env.user.company_ids += self.company_2
|
||||
|
||||
self.user = (
|
||||
self.env["res.users"]
|
||||
.with_user(self.env.user)
|
||||
.with_context(no_reset_password=True)
|
||||
.create(
|
||||
{
|
||||
"name": "Test User",
|
||||
"login": "test_user",
|
||||
"email": "test@oca.com",
|
||||
"groups_id": [
|
||||
(
|
||||
6,
|
||||
0,
|
||||
[
|
||||
employees_group.id,
|
||||
account_user_group.id,
|
||||
account_manager_group.id,
|
||||
multi_company_group.id,
|
||||
],
|
||||
)
|
||||
],
|
||||
"company_id": self.company.id,
|
||||
"company_ids": [Command.link(self.company.id)],
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
self.chart = self.env["account.chart.template"].search([], limit=1)
|
||||
self._chart_of_accounts_create(self.company, self.chart)
|
||||
account_template = self.env["account.account.template"].create(
|
||||
{"name": "Test 1", "code": "Code_test", "account_type": "asset_cash"}
|
||||
)
|
||||
self.env["ir.model.data"].create(
|
||||
{
|
||||
"name": account_template.name,
|
||||
"module": "account",
|
||||
"model": "account.account.template",
|
||||
"res_id": account_template.id,
|
||||
"noupdate": 0,
|
||||
}
|
||||
)
|
||||
|
||||
self.chart_2 = self.env["account.chart.template"].create(
|
||||
{
|
||||
"name": "Test Chart",
|
||||
"currency_id": self.env.ref("base.EUR").id,
|
||||
"transfer_account_id": account_template.id,
|
||||
}
|
||||
)
|
||||
|
||||
account_template.chart_template_id = self.chart_2
|
||||
self.chart_2.tax_template_ids |= self.chart.tax_template_ids
|
||||
|
||||
self._chart_of_accounts_create(self.company_2, self.chart_2)
|
||||
|
||||
self.chart.company_id = self.company
|
||||
self.chart_2.company_id = self.company_2
|
||||
|
||||
self.account_company_1 = self.env["account.account"].search(
|
||||
[("company_id", "=", self.company.id)], limit=1
|
||||
)
|
||||
self.account_journal_1 = self.env["account.journal"].create(
|
||||
{
|
||||
"name": "Journal Company 1",
|
||||
"company_id": self.company.id,
|
||||
"code": "TST",
|
||||
"type": "general",
|
||||
}
|
||||
)
|
||||
self.partner = self.env["res.partner"].create(
|
||||
{"name": "Test partner", "company_id": False}
|
||||
)
|
||||
self.partner2 = self.env["res.partner"].create(
|
||||
{"name": "Test partner 2", "company_id": False}
|
||||
)
|
||||
|
||||
self.tax_account_id = self.env["account.account"].create(
|
||||
{
|
||||
"name": "tax account",
|
||||
"code": "TAX",
|
||||
"account_type": "income_other",
|
||||
"company_id": self.company.id,
|
||||
}
|
||||
)
|
||||
self.tax = self.env["account.tax"].create(
|
||||
{
|
||||
"name": "Tax 10.0%",
|
||||
"amount": 10.0,
|
||||
"amount_type": "percent",
|
||||
"account_id": self.tax_account_id.id,
|
||||
}
|
||||
)
|
||||
|
||||
def test_create_template(self):
|
||||
"""Test that I can create a template"""
|
||||
template = (
|
||||
self.env["account.move.template"]
|
||||
.with_user(self.user)
|
||||
.create(
|
||||
{
|
||||
"name": "Test Move Template",
|
||||
"company_id": self.company.id,
|
||||
"journal_id": self.account_journal_1.id,
|
||||
"template_line_ids": [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": "L1",
|
||||
"sequence": 1,
|
||||
"account_id": self.account_company_1.id,
|
||||
"partner_id": self.partner.id,
|
||||
"tax_line_id": self.tax.id,
|
||||
"move_line_type": "dr",
|
||||
"type": "input",
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": "L2",
|
||||
"sequence": 2,
|
||||
"account_id": self.account_company_1.id,
|
||||
"move_line_type": "cr",
|
||||
"tax_ids": [Command.link(self.tax.id)],
|
||||
"type": "input",
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(template.company_id, self.user.company_id)
|
||||
|
||||
template_2 = template.copy()
|
||||
self.assertEqual(template_2.name, f"{template.name} (copy)")
|
||||
|
||||
wiz = (
|
||||
self.env["wizard.select.move.template"]
|
||||
.with_user(self.user)
|
||||
.create(
|
||||
{
|
||||
"company_id": self.company.id,
|
||||
"template_id": template.id,
|
||||
"partner_id": self.partner2.id,
|
||||
"date": fields.Date.today(),
|
||||
}
|
||||
)
|
||||
)
|
||||
wiz.load_lines()
|
||||
res = wiz.load_template()
|
||||
aml = self.env["account.move.line"].search(
|
||||
[("account_id", "=", self.account_company_1.id)], limit=1
|
||||
)
|
||||
self.assertEqual(res["domain"], ([("id", "in", aml.move_id.ids)]))
|
||||
aml = self.env["account.move.line"].search([("name", "=", "L1")], limit=1)
|
||||
self.assertEqual(aml.tax_line_id, self.tax)
|
||||
self.assertEqual(aml.partner_id, self.partner)
|
||||
aml = self.env["account.move.line"].search([("name", "=", "L2")], limit=1)
|
||||
self.assertEqual(aml.tax_ids[0], self.tax)
|
||||
with self.assertRaises(IntegrityError), mute_logger("odoo.sql_db"):
|
||||
template_2.name = template.name
|
||||
339
account_move_template/tests/test_account_move_template_options.py
Executable file
339
account_move_template/tests/test_account_move_template_options.py
Executable file
@@ -0,0 +1,339 @@
|
||||
# Copyright 2020 Ecosoft (http://ecosoft.co.th)
|
||||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import Command, fields
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tests import tagged
|
||||
|
||||
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
|
||||
|
||||
|
||||
@tagged("post_install", "-at_install")
|
||||
class TestAccountMoveTemplateEnhanced(AccountTestInvoicingCommon):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
|
||||
cls.company = cls.company_data["company"]
|
||||
cls.env.user.write({"company_ids": [Command.link(cls.company.id)]})
|
||||
cls.Move = cls.env["account.move"]
|
||||
cls.Journal = cls.env["account.journal"]
|
||||
cls.Account = cls.env["account.account"]
|
||||
cls.Template = cls.env["account.move.template"]
|
||||
cls.Partner = cls.env["res.partner"]
|
||||
|
||||
cls.journal = cls.company_data["default_journal_misc"]
|
||||
cls.ar_account_id = cls.company_data["default_account_receivable"]
|
||||
cls.ap_account_id = cls.company_data["default_account_payable"]
|
||||
cls.income_account_id = cls.company_data["default_account_revenue"]
|
||||
cls.expense_account_id = cls.company_data["default_account_expense"]
|
||||
cls.automatic_balancing_account_id = cls._get_first_record(
|
||||
cls.Account, [("code", "=", "101402")]
|
||||
)
|
||||
cls.tax_paid_account_id = cls._get_first_record(
|
||||
cls.Account, [("code", "=", "131000")]
|
||||
)
|
||||
|
||||
cls.partner0 = cls.Partner.create({"name": "Beloved test partner"})
|
||||
cls.partner1 = cls.Partner.create({"name": "World company test inc."})
|
||||
cls.partner2 = cls.Partner.create({"name": "Odoo debug expert GmbH"})
|
||||
|
||||
cls.payment_term = cls._get_first_record(
|
||||
cls.env["account.payment.term.line"], [("nb_days", "=", 30)]
|
||||
)
|
||||
cls.tax = cls._get_first_record(
|
||||
cls.env["account.tax"],
|
||||
[("type_tax_use", "=", "purchase"), ("company_id", "=", cls.company.id)],
|
||||
)
|
||||
|
||||
cls.move_template = cls._create_move_template("Test Template", with_tax=False)
|
||||
cls.move_template_with_tax_and_payment_terms = cls._create_move_template(
|
||||
"Test Template With Tax And Payment Terms", with_tax=True
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _get_first_record(cls, model, domain):
|
||||
return model.search(domain, limit=1)
|
||||
|
||||
@classmethod
|
||||
def _create_move_template(cls, name, with_tax=False):
|
||||
ar_line = {
|
||||
"sequence": 0,
|
||||
"name": "AR Line 1" + (" With Tax And Payment Terms" if with_tax else ""),
|
||||
"account_id": cls.ar_account_id.id,
|
||||
"opt_account_id": cls.ap_account_id.id,
|
||||
"move_line_type": "dr",
|
||||
"type": "input",
|
||||
}
|
||||
if with_tax:
|
||||
ar_line.update(
|
||||
{"payment_term_id": cls.payment_term.id, "tax_ids": cls.tax.ids}
|
||||
)
|
||||
|
||||
income_line1 = {
|
||||
"sequence": 1,
|
||||
"name": "Income Line 1",
|
||||
"account_id": cls.income_account_id.id,
|
||||
"opt_account_id": cls.expense_account_id.id,
|
||||
"move_line_type": "cr",
|
||||
"type": "computed",
|
||||
"python_code": "L0*1/3",
|
||||
}
|
||||
income_line2 = {
|
||||
"sequence": 2,
|
||||
"name": "Income Line 2",
|
||||
"account_id": cls.income_account_id.id,
|
||||
"opt_account_id": cls.expense_account_id.id,
|
||||
"move_line_type": "cr",
|
||||
"type": "computed",
|
||||
"python_code": "L0*2/3",
|
||||
}
|
||||
|
||||
return cls.Template.create(
|
||||
{
|
||||
"name": name,
|
||||
"journal_id": cls.journal.id,
|
||||
"company_id": cls.company.id,
|
||||
"line_ids": [
|
||||
Command.create(ar_line),
|
||||
Command.create(income_line1),
|
||||
Command.create(income_line2),
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
def _run_template_and_validate(
|
||||
self, template, input_amount, expected_values, sort_field
|
||||
):
|
||||
wiz = self.env["account.move.template.run"].create({"template_id": template.id})
|
||||
wiz.load_lines()
|
||||
wiz.line_ids[0].amount = input_amount
|
||||
res = wiz.generate_move()
|
||||
move = self.Move.browse(res["res_id"])
|
||||
self.assertRecordValues(move.line_ids.sorted(sort_field), expected_values)
|
||||
|
||||
def test_move_template_normal(self):
|
||||
"""Test normal case, input amount 300"""
|
||||
expected_values = [
|
||||
{"account_id": self.ar_account_id.id, "credit": 0.0, "debit": 300.0},
|
||||
{"account_id": self.income_account_id.id, "credit": 100.0, "debit": 0.0},
|
||||
{"account_id": self.income_account_id.id, "credit": 200.0, "debit": 0.0},
|
||||
]
|
||||
self._run_template_and_validate(
|
||||
self.move_template, 300, expected_values, "credit"
|
||||
)
|
||||
|
||||
def test_move_template_normal_with_tax_and_payment_terms(self):
|
||||
"""Test case with tax and payment terms, input amount 300"""
|
||||
expected_maturity_date = fields.Date.today() + timedelta(days=30)
|
||||
expected_values = [
|
||||
{
|
||||
"account_id": self.ar_account_id.id,
|
||||
"credit": 0.0,
|
||||
"debit": 300.0,
|
||||
"date_maturity": expected_maturity_date,
|
||||
},
|
||||
{
|
||||
"account_id": self.tax_paid_account_id.id,
|
||||
"credit": 0.0,
|
||||
"debit": 45.0,
|
||||
"date_maturity": None,
|
||||
},
|
||||
{
|
||||
"account_id": self.automatic_balancing_account_id.id,
|
||||
"credit": 45.0,
|
||||
"debit": 0.0,
|
||||
"date_maturity": None,
|
||||
},
|
||||
{
|
||||
"account_id": self.income_account_id.id,
|
||||
"credit": 100.0,
|
||||
"debit": 0.0,
|
||||
"date_maturity": fields.Date.today(),
|
||||
},
|
||||
{
|
||||
"account_id": self.income_account_id.id,
|
||||
"credit": 200.0,
|
||||
"debit": 0.0,
|
||||
"date_maturity": fields.Date.today(),
|
||||
},
|
||||
]
|
||||
self._run_template_and_validate(
|
||||
self.move_template_with_tax_and_payment_terms,
|
||||
300,
|
||||
expected_values,
|
||||
"credit",
|
||||
)
|
||||
|
||||
def test_move_template_optional(self):
|
||||
"""Test optional case, input amount -300, expect optional account"""
|
||||
expected_values = [
|
||||
{"account_id": self.ap_account_id.id, "credit": 300.0, "debit": 0.0},
|
||||
{"account_id": self.expense_account_id.id, "credit": 0.0, "debit": 100.0},
|
||||
{"account_id": self.expense_account_id.id, "credit": 0.0, "debit": 200.0},
|
||||
]
|
||||
self._run_template_and_validate(
|
||||
self.move_template, -300, expected_values, "debit"
|
||||
)
|
||||
|
||||
def test_move_template_overwrite(self):
|
||||
"""Test case overwrite, amount = 3000, no need to manual input"""
|
||||
# Test for error when debit is not a valid field
|
||||
wiz = self.env["account.move.template.run"].create(
|
||||
{
|
||||
"template_id": self.move_template.id,
|
||||
"overwrite": str(
|
||||
{
|
||||
"L0": {
|
||||
"partner_id": self.partner0.id,
|
||||
"amount": 3000,
|
||||
"debit": 3000,
|
||||
},
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
msg_error = "overwrite are .'partner_id', 'amount', 'name', 'date_maturity'"
|
||||
with self.assertRaisesRegex(ValidationError, msg_error):
|
||||
wiz.load_lines()
|
||||
# Assign only on valid fields, and load_lines again
|
||||
wiz = self.env["account.move.template.run"].create(
|
||||
{
|
||||
"template_id": self.move_template.id,
|
||||
"overwrite": str(
|
||||
{
|
||||
"L0": {"partner_id": self.partner0.id, "amount": 3000},
|
||||
"L1": {"partner_id": self.partner1.id},
|
||||
"L2": {"partner_id": self.partner2.id},
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
res = wiz.load_lines()
|
||||
self.assertEqual(wiz.line_ids[0].partner_id, self.partner0)
|
||||
self.assertEqual(wiz.line_ids[0].amount, 3000)
|
||||
res = wiz.with_context(**res["context"]).generate_move()
|
||||
move = self.Move.browse(res["res_id"])
|
||||
self.assertRecordValues(
|
||||
move.line_ids.sorted("credit"),
|
||||
[
|
||||
{
|
||||
"partner_id": self.partner0.id,
|
||||
"account_id": self.ar_account_id.id,
|
||||
"credit": 0.0,
|
||||
"debit": 3000.0,
|
||||
},
|
||||
{
|
||||
"partner_id": self.partner1.id,
|
||||
"account_id": self.income_account_id.id,
|
||||
"credit": 1000.0,
|
||||
"debit": 0.0,
|
||||
},
|
||||
{
|
||||
"partner_id": self.partner2.id,
|
||||
"account_id": self.income_account_id.id,
|
||||
"credit": 2000.0,
|
||||
"debit": 0.0,
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
def test_move_copy(self):
|
||||
template_copy = self.move_template.copy()
|
||||
self.assertEqual(template_copy.name, "Test Template (copy)")
|
||||
|
||||
def test_move_generate_from_action_button(self):
|
||||
# `Generate Journal Entry` action button
|
||||
res = self.move_template.generate_journal_entry()
|
||||
self.assertEqual(res["name"], "Create Entry from Template")
|
||||
self.assertEqual(res["res_model"], "account.move.template.run")
|
||||
|
||||
def test_move_template_exceptions(self):
|
||||
msg_error = "Python Code must be set for computed line with sequence 1."
|
||||
with self.assertRaisesRegex(ValidationError, msg_error):
|
||||
self.move_template.line_ids[1].python_code = ""
|
||||
|
||||
self.move_template.line_ids[1].python_code = "P0*1/3"
|
||||
wiz = self.env["account.move.template.run"].create(
|
||||
{
|
||||
"template_id": self.move_template.id,
|
||||
}
|
||||
)
|
||||
wiz.load_lines()
|
||||
msg_error = "really exists and have a lower sequence than the current line."
|
||||
with self.assertRaisesRegex(UserError, msg_error):
|
||||
wiz.generate_move()
|
||||
|
||||
self.move_template.line_ids[1].python_code = "L0*"
|
||||
wiz = self.env["account.move.template.run"].create(
|
||||
{
|
||||
"template_id": self.move_template.id,
|
||||
}
|
||||
)
|
||||
wiz.load_lines()
|
||||
msg_error = "the syntax of the formula is wrong."
|
||||
with self.assertRaisesRegex(UserError, msg_error):
|
||||
wiz.generate_move()
|
||||
|
||||
self.move_template.line_ids[1].python_code = "L0*1/3"
|
||||
wiz = self.env["account.move.template.run"].create(
|
||||
{
|
||||
"template_id": self.move_template.id,
|
||||
}
|
||||
)
|
||||
wiz.load_lines()
|
||||
wiz.line_ids[0].amount = 0
|
||||
msg_error = "Debit and credit of all lines are null."
|
||||
with self.assertRaisesRegex(UserError, msg_error):
|
||||
wiz.generate_move()
|
||||
|
||||
wiz = self.env["account.move.template.run"].create(
|
||||
{
|
||||
"template_id": self.move_template.id,
|
||||
"overwrite": [],
|
||||
}
|
||||
)
|
||||
msg_error = "Overwrite value must be a valid python dict"
|
||||
with self.assertRaisesRegex(ValidationError, msg_error):
|
||||
wiz.load_lines()
|
||||
|
||||
wiz = self.env["account.move.template.run"].create(
|
||||
{
|
||||
"template_id": self.move_template.id,
|
||||
"overwrite": str({"P0": {"amount": 100}}),
|
||||
}
|
||||
)
|
||||
msg_error = "Keys must be line sequence i.e. L1, L2, ..."
|
||||
with self.assertRaisesRegex(ValidationError, msg_error):
|
||||
wiz.load_lines()
|
||||
|
||||
wiz = self.env["account.move.template.run"].create(
|
||||
{
|
||||
"template_id": self.move_template.id,
|
||||
"overwrite": str({"L0": []}),
|
||||
}
|
||||
)
|
||||
msg_error = "Invalid dictionary: 'list' object has no attribute 'keys'"
|
||||
with self.assertRaisesRegex(ValidationError, msg_error):
|
||||
wiz.load_lines()
|
||||
|
||||
wiz = self.env["account.move.template.run"].create(
|
||||
{
|
||||
"template_id": self.move_template.id,
|
||||
"overwrite": str({"L0": {"test": 100}}),
|
||||
}
|
||||
)
|
||||
msg_error = "overwrite are .'partner_id', 'amount', 'name', 'date_maturity'"
|
||||
with self.assertRaisesRegex(ValidationError, msg_error):
|
||||
wiz.load_lines()
|
||||
|
||||
wiz = self.env["account.move.template.run"].create(
|
||||
{
|
||||
"template_id": self.move_template.id,
|
||||
}
|
||||
)
|
||||
wiz.line_ids.unlink()
|
||||
msg_error = "You deleted a line in the wizard. This is not allowed:"
|
||||
with self.assertRaisesRegex(UserError, msg_error):
|
||||
wiz.generate_move()
|
||||
Reference in New Issue
Block a user