diff --git a/fiscal_company_account/__manifest__.py b/fiscal_company_account/__manifest__.py
index c66c1fa..6321fb8 100644
--- a/fiscal_company_account/__manifest__.py
+++ b/fiscal_company_account/__manifest__.py
@@ -5,7 +5,7 @@
{
"name": "CAE - Account",
- "version": "12.0.1.1.0",
+ "version": "16.0.1.0.0",
"category": "CAE",
"summary": "Glue Module between CAE and Account modules",
"author": "GRAP",
@@ -14,18 +14,15 @@
"depends": ["fiscal_company_base", "account"],
"data": [
"security/ir_rule.xml",
- "views/menu.xml",
- "views/view_account_move.xml",
- "views/view_res_partner.xml",
+ # "views/menu.xml",
+ # "views/view_account_move.xml",
+ # "views/view_res_partner.xml",
],
"demo": [
"demo/res_groups.xml",
"demo/account_account.xml",
"demo/account_journal.xml",
"demo/account_tax.xml",
- "demo/product_category.xml",
- "demo/product_product.xml",
- "demo/product_template.xml",
"demo/res_partner.xml",
"demo/ir_property.xml",
],
diff --git a/fiscal_company_account/demo/account_account.xml b/fiscal_company_account/demo/account_account.xml
index 6d15a6f..44961e3 100644
--- a/fiscal_company_account/demo/account_account.xml
+++ b/fiscal_company_account/demo/account_account.xml
@@ -9,65 +9,96 @@ Copyright (C) 2013-Today GRAP (http://www.grap.coop)
- 401_CAE
+ 401CAE
CAE - Payable - (test)
-
+ liability_payable
- 411_CAE
+ 411CAE
CAE - Receivable - (test)
-
+ asset_receivable
- 401_CAE_CUS
+ 401CAECUSTOM
CAE - Custom Payable - (test)
-
+ liability_payable
- 411_CAE_CUS
+ 411CAECUSTOM
CAE - Custom Receivable - (test)
-
+ asset_receivable
+
+
+
+
+
+ 4456CAE
+ CAE - VAT Received - (test)
+ liability_current
+
+
+
+
+
+ 4457CAE
+ CAE - VAT Deductible - (test)
+ liability_current
-
+
+
+ 512CAEBANKDEFAULT
+ CAE - Bank (Default Account) - (test)
+ asset_cash
+
+
+
+
+ 512CAEBANKSUSPENSE
+ CAE - Bank (Suspense Account) - (test)
+ asset_current
+
+
+
- CAE_512
- CAE - Bank - (test)
-
+ 512CAEBANKPAYMENT
+ CAE - Bank (Payment Account) - (test)
+ asset_current
+
- CAE_581
+ 581CAE
CAE - Cash - (test)
-
+ asset_cash
- CAE_601
+ 607CAE
CAE - Expenses - (test)
-
+ expense
- CAE_702
+ 707CAE
CAE - Product Sales - (test)
-
+ income
diff --git a/fiscal_company_account/demo/account_journal.xml b/fiscal_company_account/demo/account_journal.xml
index e7d7def..4c21787 100644
--- a/fiscal_company_account/demo/account_journal.xml
+++ b/fiscal_company_account/demo/account_journal.xml
@@ -26,6 +26,18 @@ Copyright (C) 2013-Today GRAP (http://www.grap.coop)
CAE_BANK
CAE - Bank Journal - (test)
bank
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fiscal_company_account/demo/account_tax.xml b/fiscal_company_account/demo/account_tax.xml
index 255e27a..beedd50 100644
--- a/fiscal_company_account/demo/account_tax.xml
+++ b/fiscal_company_account/demo/account_tax.xml
@@ -1,4 +1,5 @@
+
-
+
+
+ 100
+ base
+
+
+
+ 100
+ tax
+
+
+
+ 100
+ base
+
+
+
+ 100
+ tax
+
+
+
+ Sale Tax 20% (Price Excl.)
+ sale
+ percent
+ 20.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 100
+ base
+
+
+
+ 100
+ tax
+
+
+
+ 100
+ base
+
+
+
+ 100
+ tax
+
+
+
+ Purchase Tax 20% (Price Excl.)
+ purchase
+ percent
+ 20.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fiscal_company_account/demo/ir_property.xml b/fiscal_company_account/demo/ir_property.xml
index 54fde0f..6d21653 100644
--- a/fiscal_company_account/demo/ir_property.xml
+++ b/fiscal_company_account/demo/ir_property.xml
@@ -7,32 +7,76 @@ Copyright (C) 2013-Today GRAP (http://www.grap.coop)
-->
+
- CAE - property_account_receivable CH1
+ property_account_receivable_id
- CAE - property_account_receivable CH2
+ property_account_receivable_id
- CAE - property_account_payable CH1
+ property_account_payable_id
- CAE - property_account_payable CH2
+ property_account_payable_id
+
+
+ property_account_income_categ_id
+
+
+
+
+
+
+ property_account_income_categ_id
+
+
+
+
+
+
+ property_account_income_categ_id
+
+
+
+
+
+
+ property_account_expense_categ_id
+
+
+
+
+
+
+ CAE - property_account_expense_categ_id CH1
+
+
+
+
+
+
+ property_account_expense_categ_id
+
+
+
+
+
diff --git a/fiscal_company_account/demo/product_category.xml b/fiscal_company_account/demo/product_category.xml
deleted file mode 100644
index b426583..0000000
--- a/fiscal_company_account/demo/product_category.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
diff --git a/fiscal_company_account/demo/product_product.xml b/fiscal_company_account/demo/product_product.xml
deleted file mode 100644
index 8cfbfd9..0000000
--- a/fiscal_company_account/demo/product_product.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
- CAE - Mother Product Variant With Property
-
-
-
-
-
-
-
diff --git a/fiscal_company_account/demo/product_template.xml b/fiscal_company_account/demo/product_template.xml
deleted file mode 100644
index 20cf77d..0000000
--- a/fiscal_company_account/demo/product_template.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
- CAE - Mother Product Template With Property
-
-
-
-
-
-
-
diff --git a/fiscal_company_account/demo/res_partner.xml b/fiscal_company_account/demo/res_partner.xml
index d29051f..1425b6b 100644
--- a/fiscal_company_account/demo/res_partner.xml
+++ b/fiscal_company_account/demo/res_partner.xml
@@ -7,24 +7,18 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
- CAE - Mother Partner With Property
+ CAE - Mother Partner
-
-
-
- CAE - Fiscal 1 Partner With Property
+
+ CAE - Fiscal 1 Partner
-
-
-
+
+ CAE - Fiscal 2 Partner
+
+
diff --git a/fiscal_company_account/models/__init__.py b/fiscal_company_account/models/__init__.py
index 93d9db9..e6d329a 100644
--- a/fiscal_company_account/models/__init__.py
+++ b/fiscal_company_account/models/__init__.py
@@ -1,16 +1,11 @@
# Accounting Part
from . import account_account
from . import account_bank_statement
-from . import account_invoice
from . import account_journal
from . import account_move
from . import account_move_line
from . import account_payment
-from . import account_reconciliation_widget
from . import account_tax
-# Propagation properties Part
-from . import fiscal_property_propagate_mixin
-from . import product_template
from . import res_company
from . import res_partner
diff --git a/fiscal_company_account/models/account_account.py b/fiscal_company_account/models/account_account.py
index 80284f6..75c0535 100644
--- a/fiscal_company_account/models/account_account.py
+++ b/fiscal_company_account/models/account_account.py
@@ -3,13 +3,20 @@
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from odoo import models
+from odoo import fields, models
class AccountAccount(models.Model):
_name = "account.account"
_inherit = [
"account.account",
- "include.fiscal.company.search.mixin",
- "fiscal.child.check.mixin",
+ "fiscal.company.change.search.domain.mixin",
+ "fiscal.company.check.company.mixin",
]
+
+ _fiscal_company_forbid_fiscal_type = ["fiscal_child"]
+
+ company_id = fields.Many2one(default=lambda self: self._default_company_id())
+
+ def _default_company_id(self):
+ return self.env.company.fiscal_company_id
diff --git a/fiscal_company_account/models/account_bank_statement.py b/fiscal_company_account/models/account_bank_statement.py
index 905a261..b6f8fda 100644
--- a/fiscal_company_account/models/account_bank_statement.py
+++ b/fiscal_company_account/models/account_bank_statement.py
@@ -7,6 +7,8 @@
class AccountBankStatement(models.Model):
_name = "account.bank.statement"
- _inherit = ["account.bank.statement", "fiscal.mother.check.mixin"]
+ _inherit = ["account.bank.statement", "fiscal.company.check.company.mixin"]
+
+ _fiscal_company_forbid_fiscal_type = ["fiscal_mother"]
company_id = fields.Many2one(related=False)
diff --git a/fiscal_company_account/models/account_invoice.py b/fiscal_company_account/models/account_invoice.py
deleted file mode 100644
index 5d16739..0000000
--- a/fiscal_company_account/models/account_invoice.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (C) 2018-Today: GRAP (http://www.grap.coop)
-# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-
-from odoo import models
-
-
-class AccountInvoice(models.Model):
- _name = "account.invoice"
- _inherit = ["account.invoice", "fiscal.mother.check.mixin"]
diff --git a/fiscal_company_account/models/account_journal.py b/fiscal_company_account/models/account_journal.py
index 065233d..9dd4e82 100644
--- a/fiscal_company_account/models/account_journal.py
+++ b/fiscal_company_account/models/account_journal.py
@@ -8,4 +8,48 @@
class AccountJournal(models.Model):
_name = "account.journal"
- _inherit = ["account.journal", "include.fiscal.company.search.mixin"]
+ _inherit = [
+ "account.journal",
+ "fiscal.company.change.search.domain.mixin",
+ ]
+
+ def _get_journal_dashboard_data_batched(self):
+ # Modify Context to add domain based on allowed companies
+ # when making request on account.move
+ return super(
+ AccountJournal, self.with_context(add_company_domain=True)
+ )._get_journal_dashboard_data_batched()
+
+ def _get_journal_dashboard_outstanding_payments(self):
+ """Oustanding payments are computed in an non overloable way.
+ so in a integrated company context, it compute the values
+ for the all CAE.
+ Feature is so disabled in that context
+ """
+ if self.env.company.fiscal_type == "fiscal_child":
+ return {x.id: (0, 0) for x in self}
+ return super()._get_journal_dashboard_outstanding_payments()
+
+ def _get_sale_purchase_graph_data(self):
+ """Invoice amount repartition over the time is computed
+ in a non overloable way, so in a integrated company context,
+ it compute the values for the all CAE.
+ Feature is so disabled in that context.
+ """
+ res = super()._get_sale_purchase_graph_data()
+ if self.env.company.fiscal_type == "fiscal_child":
+ for k, _v in res.items():
+ res[k][0]["values"] = []
+ return res
+
+ def _get_bank_cash_graph_data(self):
+ """Statement amount repartition over the time is computed
+ in a non overloable way, so in a integrated company context,
+ it compute the values for the all CAE.
+ Feature is so disabled in that context.
+ """
+ res = super()._get_bank_cash_graph_data()
+ if self.env.company.fiscal_type == "fiscal_child":
+ for k, _v in res.items():
+ res[k][0]["values"] = []
+ return res
diff --git a/fiscal_company_account/models/account_move.py b/fiscal_company_account/models/account_move.py
index 99eb228..d2e552b 100644
--- a/fiscal_company_account/models/account_move.py
+++ b/fiscal_company_account/models/account_move.py
@@ -3,20 +3,55 @@
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from odoo import fields, models
+from odoo import api, fields, models
class AccountMove(models.Model):
_name = "account.move"
- _inherit = ["account.move", "fiscal.mother.check.mixin"]
-
- company_id = fields.Many2one(
- related=False, default=lambda x: x._default_company_id()
- )
-
- def _default_company_id(self):
- if self.env.context.get("force_company", False):
- return self.env.context["force_company"]
- if self.env.context.get("company_id", False):
- return self.env.context["company_id"]
- return self.env.user.company_id.id
+ _inherit = [
+ "account.move",
+ "fiscal.company.check.company.mixin",
+ ]
+
+ _fiscal_company_forbid_fiscal_type = ["fiscal_mother"]
+
+ journal_id = fields.Many2one(check_company=False)
+
+ @api.onchange("partner_id")
+ def _onchange_partner_id(self):
+ return super(
+ AccountMove, self.with_context(fiscal_company_disable_switch_company=True)
+ )._onchange_partner_id()
+
+ @api.depends("journal_id")
+ def _compute_company_id(self):
+ """In odoo Core, the company of an account move is the company of the journal,
+ that allows to write account moves in group level.
+ However, this behaviour is not correct in a CAE context.
+ So we disable the call of super in this case, and set the current company.
+ """
+ for move in self.filtered(
+ lambda x: x.journal_id.company_id.fiscal_type == "fiscal_mother"
+ ):
+ move.company_id = self.env.company
+ return super(
+ AccountMove,
+ self.filtered(
+ lambda x: x.journal_id.company_id.fiscal_type != "fiscal_mother"
+ ),
+ )._compute_company_id()
+
+ @api.model
+ def _where_calc(self, domain, active_test=True):
+ """Used only in a dashboard context (see account_journal.py)
+ to add extra filters, based on current allowed companies
+ to filter in an integrated company context, data of other integrated
+ companies of the same CAE."""
+ if self.env.context.get("add_company_domain", False):
+ if self.env.context.get("allowed_company_ids"):
+ domain += [
+ ("company_id", "in", self.env.context.get("allowed_company_ids"))
+ ]
+ else:
+ domain += [("company_id", "=", self.env.company.id)]
+ return super()._where_calc(domain, active_test=active_test)
diff --git a/fiscal_company_account/models/account_move_line.py b/fiscal_company_account/models/account_move_line.py
index 0d7c42e..ff3cfe5 100644
--- a/fiscal_company_account/models/account_move_line.py
+++ b/fiscal_company_account/models/account_move_line.py
@@ -8,6 +8,13 @@
class AccountMoveLine(models.Model):
_name = "account.move.line"
- _inherit = ["account.move.line", "fiscal.mother.check.mixin"]
+ _inherit = [
+ "account.move.line",
+ "fiscal.company.check.company.mixin",
+ ]
- company_id = fields.Many2one(related="move_id.company_id")
+ _fiscal_company_forbid_fiscal_type = ["fiscal_mother"]
+
+ account_id = fields.Many2one(check_company=False)
+
+ tax_ids = fields.Many2many(check_company=False)
diff --git a/fiscal_company_account/models/account_payment.py b/fiscal_company_account/models/account_payment.py
index f8c8f27..67636e4 100644
--- a/fiscal_company_account/models/account_payment.py
+++ b/fiscal_company_account/models/account_payment.py
@@ -1,4 +1,5 @@
-# Copyright (C) 2018-Today: GRAP (http://www.grap.coop)
+# Copyright (C) 2013-Today: GRAP (http://www.grap.coop)
+# @author: Julien WESTE
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
@@ -6,9 +7,8 @@
class AccountPayment(models.Model):
- _name = "account.payment"
- _inherit = ["account.payment", "fiscal.mother.check.mixin"]
+ _inherit = "account.payment"
- company_id = fields.Many2one(
- related=False, default=lambda self: self.env.user.company_id
- )
+ destination_account_id = fields.Many2one(check_company=False)
+
+ outstanding_account_id = fields.Many2one(check_company=False)
diff --git a/fiscal_company_account/models/account_reconciliation_widget.py b/fiscal_company_account/models/account_reconciliation_widget.py
deleted file mode 100644
index 77176bb..0000000
--- a/fiscal_company_account/models/account_reconciliation_widget.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2020-Today: GRAP (http://www.grap.coop)
-# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-
-from odoo import api, models
-
-
-class AccountReconciliationWidget(models.AbstractModel):
- _inherit = "account.reconciliation.widget"
-
- @api.model
- def _set_domain_to_current_company(self, domain):
- result = []
- for item in domain:
- if "company_id" in str(item):
- result.append(("company_id", "=", self.env.user.company_id.id))
- else:
- result.append(item)
- return result
-
- @api.model
- def _domain_move_lines_for_reconciliation(
- self, st_line, aml_accounts, partner_id, excluded_ids=None, search_str=False
- ):
- domain = super()._domain_move_lines_for_reconciliation(
- st_line,
- aml_accounts,
- partner_id,
- excluded_ids=excluded_ids,
- search_str=search_str,
- )
- return self._set_domain_to_current_company(domain)
-
- @api.model
- def _domain_move_lines_for_manual_reconciliation(
- self, account_id, partner_id=False, excluded_ids=None, search_str=False
- ):
- domain = super()._domain_move_lines_for_manual_reconciliation(
- account_id, partner_id=False, excluded_ids=None, search_str=search_str
- )
- return self._set_domain_to_current_company(domain)
diff --git a/fiscal_company_account/models/account_tax.py b/fiscal_company_account/models/account_tax.py
index e86a211..1885f17 100644
--- a/fiscal_company_account/models/account_tax.py
+++ b/fiscal_company_account/models/account_tax.py
@@ -3,29 +3,16 @@
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from odoo import api, models
+from odoo import models
class AccountTax(models.Model):
_name = "account.tax"
_inherit = [
"account.tax",
- "include.fiscal.company.search.mixin",
- "fiscal.child.check.mixin",
+ "fiscal.company.change.search.domain.mixin",
+ "fiscal.company.change.filtered.mixin",
+ "fiscal.company.check.company.mixin",
]
- @api.multi
- def filtered(self, func):
- # a lot of function in Odoo are filtering taxes by the current company
- # for exemple in 'addons/account/models/account_invoice.py#L1809'
- # In our CAE case, we replace the current company by the fiscal one.
-
- # TODO, improve that ugly code.
- if (
- not self.env.context.get("dont_change_filter", False)
- and callable(func)
- and "company_id" in func.__code__.co_names
- ):
- company = self.env.user.company_id.fiscal_company_id
- return super().filtered(lambda x: x.company_id == company)
- return super().filtered(func)
+ _fiscal_company_forbid_fiscal_type = ["fiscal_child"]
diff --git a/fiscal_company_account/models/fiscal_property_propagate_mixin.py b/fiscal_company_account/models/fiscal_property_propagate_mixin.py
deleted file mode 100644
index 6c5f2b3..0000000
--- a/fiscal_company_account/models/fiscal_property_propagate_mixin.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright (C) 2013 - Today: GRAP (http://www.grap.coop)
-# @author: Julien WESTE
-# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-
-
-from odoo import api, models
-
-
-class FiscalPropertyPropagateMixin(models.AbstractModel):
- _name = "fiscal.property.propagate.mixin"
- _description = "Fiscal Property Propagation Features Mixin"
-
- @api.model
- def _fiscal_property_creation_list(self):
- """Overload me to define property fields to create to a new
- fiscal company
- """
- return []
-
- @api.multi
- def _fiscal_property_propagation_list(self):
- """Overload me to define property fields to propagate to all
- fiscal company.
- """
- self.ensure_one()
- return []
-
- # Overload Section
- @api.model
- def create(self, vals):
- res = super().create(vals)
- res._propagate_fiscal_property_to_all_companies(vals)
- return res
-
- @api.multi
- def write(self, vals):
- res = super().write(vals)
- self._propagate_fiscal_property_to_all_companies(vals)
- return res
-
- # Custom Function
- @api.multi
- def _propagate_fiscal_property_to_all_companies(self, vals):
- """
- Propagate a property of objects of for all fiscal
- childs of a mother company
- """
- IrModelFields = self.env["ir.model.fields"]
- IrProperty = self.env["ir.property"]
- company_id = self.env.context.get("force_company", False)
- if company_id:
- current_company = self.env["res.company"].browse(company_id)
- else:
- current_company = self.env.user.company_id
-
- if current_company.fiscal_type not in ("fiscal_child", "fiscal_mother"):
- return True
-
- for obj in self:
- property_name_list = [
- x for x in obj._fiscal_property_propagation_list() if x in vals
- ]
- for property_name in property_name_list:
- property_value = vals[property_name]
-
- # Get fields information
- field = IrModelFields.search(
- [("model", "=", self._name), ("name", "=", property_name)]
- )[0]
-
- # Get all companies and remove the current company which
- # property has been just written
- company_ids = current_company.fiscal_company_id.fiscal_child_ids.ids
- company_ids.remove(current_company.id)
-
- # Delete all property
- domain = [
- ("res_id", "=", f"{self._name},{obj.id}"),
- ("fields_id", "=", field.id),
- ("company_id", "in", company_ids),
- ]
- properties = IrProperty.search(domain)
- properties.unlink()
-
- # Create property for all fiscal childs
- if property_value:
- for company_id in company_ids:
- IrProperty.create(
- {
- "name": property_name,
- "res_id": f"{self._name},{obj.id}",
- "value": property_value,
- "fields_id": field.id,
- "type": field.ttype,
- "company_id": company_id,
- }
- )
diff --git a/fiscal_company_account/models/product_template.py b/fiscal_company_account/models/product_template.py
deleted file mode 100644
index 1cff61b..0000000
--- a/fiscal_company_account/models/product_template.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2013 - Today: GRAP (http://www.grap.coop)
-# @author: Julien WESTE
-# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-
-
-from odoo import api, models
-
-
-class ProductTemplate(models.Model):
- _name = "product.template"
- _inherit = ["product.template", "fiscal.property.propagate.mixin"]
-
- _FISCAL_PROPERTY_LIST = [
- "property_account_expense_id",
- "property_account_income_id",
- ]
-
- @api.model
- def _fiscal_property_creation_list(self):
- res = super()._fiscal_property_creation_list()
- return res + self._FISCAL_PROPERTY_LIST
-
- @api.multi
- def _fiscal_property_propagation_list(self):
- self.ensure_one()
- res = super()._fiscal_property_propagation_list()
- # Propagation only for object that belong to the fiscal_mother
- # company
- if self.company_id.fiscal_type == "fiscal_mother":
- res = res + self._FISCAL_PROPERTY_LIST
- return res
diff --git a/fiscal_company_account/models/res_company.py b/fiscal_company_account/models/res_company.py
index 2a39606..52e368b 100644
--- a/fiscal_company_account/models/res_company.py
+++ b/fiscal_company_account/models/res_company.py
@@ -8,45 +8,11 @@
class ResCompany(models.Model):
_inherit = "res.company"
- _PROPERTY_MODEL_LIST = ["res.partner", "product.template"]
+ @api.depends("country_id", "parent_id.country_id", "fiscal_type")
+ def compute_account_tax_fiscal_country(self):
+ for company in self.filtered(lambda x: x.fiscal_type == "fiscal_child"):
+ company.account_fiscal_country_id = company.parent_id.country_id
- @api.model
- def create(self, vals):
- res = super().create(vals)
- if vals.get("fiscal_type") == "fiscal_child":
- res._propagate_properties_to_new_fiscal_child()
- return res
-
- @api.multi
- def write(self, vals):
- res = super().write(vals)
- if vals.get("fiscal_type") == "fiscal_child":
- self._propagate_properties_to_new_fiscal_child()
- return res
-
- @api.multi
- def _propagate_properties_to_new_fiscal_child(self):
- """
- Propagate all properties of objects (product, category) for a new
- fiscal company
- """
- IrModelFields = self.env["ir.model.fields"]
- IrProperty = self.env["ir.property"]
- for company in self:
- for model_name in self._PROPERTY_MODEL_LIST:
- CurrentModel = self.env[model_name]
- property_name_list = CurrentModel._fiscal_property_creation_list()
- for property_name in property_name_list:
- field = IrModelFields.search(
- [("model", "=", model_name), ("name", "=", property_name)]
- )[0]
- # Get existing properties
- existing_properties = IrProperty.search(
- [
- ("fields_id", "=", field.id),
- ("company_id", "=", company.fiscal_company_id.id),
- ]
- )
- # Duplicate properties for the new fiscal childc company
- for existing_property in existing_properties:
- existing_property.copy(default={"company_id": company.id})
+ return super(
+ ResCompany, self.filtered(lambda x: x.fiscal_type != "fiscal_child")
+ ).compute_account_tax_fiscal_country()
diff --git a/fiscal_company_account/models/res_partner.py b/fiscal_company_account/models/res_partner.py
index 7065718..6cff5f6 100644
--- a/fiscal_company_account/models/res_partner.py
+++ b/fiscal_company_account/models/res_partner.py
@@ -3,90 +3,11 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from odoo import api, fields, models
+from odoo import fields, models
class ResPartner(models.Model):
- _name = "res.partner"
- _inherit = ["res.partner", "fiscal.property.propagate.mixin"]
+ _inherit = "res.partner"
- _FISCAL_PROPERTY_LIST = [
- "property_account_position_id",
- "property_account_payable_id",
- "property_account_receivable_id",
- "property_payment_term_id",
- "property_supplier_payment_term_id",
- ]
-
- @api.model
- def _fiscal_property_creation_list(self):
- res = super()._fiscal_property_creation_list()
- return res + self._FISCAL_PROPERTY_LIST
-
- @api.multi
- def _fiscal_property_propagation_list(self):
- self.ensure_one()
- res = super()._fiscal_property_propagation_list()
- # Propagation only for object that belong to the fiscal_mother
- # company
- if self.company_id.fiscal_type == "fiscal_mother":
- res = res + self._FISCAL_PROPERTY_LIST
- return res
-
- #
- # the reason of the following lines are :
- # property_account_position_id is a property
- # 1) using this field, a domain is automatically added by the orm / web
- # in the name_get for exemple:
- # ('company_id', 'in', (current_company, False))
- # this domain is not fixed for the time being, by any decorator
- # So the selection can not be done in a fiscal_company context
- # 2) also, we have to rewrite after a create, because the _inverse
- # function doesn't seems to work for properties, (only for create,
- # it works for regular write)
- @api.model
- def create(self, vals):
- res = super().create(vals)
- if "no_property_account_position_id" in vals.keys():
- res.write(
- {
- "property_account_position_id": vals[
- "no_property_account_position_id"
- ]
- }
- )
- return res
-
- no_property_account_position_id = fields.Many2one(
- string="Fiscal Position (*)",
- comodel_name="account.fiscal.position",
- domain=lambda x: x._domain_no_property_account_position_id(),
- compute="_compute_no_property_account_position_id",
- inverse="_inverse_no_property_account_position_id",
- )
-
- def _domain_no_property_account_position_id(self):
- return [
- (
- "company_id",
- "in",
- [
- self.env.user.company_id.id,
- self.env.user.company_id.fiscal_company_id.id,
- ],
- )
- ]
-
- def _compute_no_property_account_position_id(self):
- for partner in self:
- partner.no_property_account_position_id = (
- partner.property_account_position_id
- )
-
- def _inverse_no_property_account_position_id(self):
- for partner in self:
- partner.property_account_position_id = (
- partner.no_property_account_position_id
- )
-
- #
+ # Display all accessible fiscal position
+ property_account_position_id = fields.Many2one(domain=[])
diff --git a/fiscal_company_account/readme/CREDITS.rst b/fiscal_company_account/readme/CREDITS.rst
deleted file mode 100644
index 26111c6..0000000
--- a/fiscal_company_account/readme/CREDITS.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-The development of this module has been financially supported by:
-
-* GRAP, Groupement Régional Alimentaire de Proximité (http://www.grap.coop)
-
-Porting from odoo V8 to odoo V10 has been funded by :
- * BABEL.COOP, leverage cooperation through the digital age ()
diff --git a/fiscal_company_account/readme/DEVELOP.rst b/fiscal_company_account/readme/DEVELOP.rst
index a7069ce..28e886a 100644
--- a/fiscal_company_account/readme/DEVELOP.rst
+++ b/fiscal_company_account/readme/DEVELOP.rst
@@ -1,9 +1,9 @@
-* For the migration to V>12, take care of the tax.filtered occurences in
- Odoo and OCA modules.
- There are a lot of ``filtered(lambda x: x.company_id == current_company)``
- in Odoo. The module ``fiscal_company_account`` alter the behaviour of the function
- ``filtered`` of the ``account.tax`` module, to filter on the mother fiscal company.
- However, the changes is imperfect, and multiple filters (company and not company filters)
- will fail.
- During migration, please run:
- ``rgrep "tax.*filtered.*company_id"``
+For the migration, take care of the tax.filtered occurences in Odoo and OCA modules.
+There are a lot of ``filtered(lambda x: x.company_id == current_company)``
+in Odoo. The module ``fiscal_company_account`` alter the behaviour of the function
+``filtered`` of the ``account.tax`` module, to filter on the mother fiscal company.
+However, the changes is imperfect, and multiple filters (company and not company filters)
+will fail.
+
+During migration, please run:
+``rgrep "tax.*filtered.*company_id"``
diff --git a/fiscal_company_account/security/ir_rule.xml b/fiscal_company_account/security/ir_rule.xml
index d9ce260..84e5d07 100644
--- a/fiscal_company_account/security/ir_rule.xml
+++ b/fiscal_company_account/security/ir_rule.xml
@@ -8,90 +8,40 @@ Copyright (C) 2013-Today GRAP (http://www.grap.coop)
-
-
-
-
-
- ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
-
-
-
-
-
-
-
- ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
-
-
-
-
+
+
- ['|', '|',
- ('company_id','=',False),
- ('company_id','child_of',[user.company_id.id]),
- ('company_id','=',user.company_id.fiscal_company_id.id),
- ]
+
+ [('company_id', 'in', user._include_fiscal_company_ids(company_ids))]
+
-
-
+
+
- ['|', '|',
- ('company_id','=',False),
- ('company_id','child_of',[user.company_id.id]),
- ('company_id','=',user.company_id.fiscal_company_id.id),
- ]
+
+ [('company_id', 'in', user._include_fiscal_company_ids(company_ids))]
+
-
-
+
+
- ['|', '|',
- ('company_id','=',False),
- ('company_id','child_of',[user.company_id.id]),
- ('company_id','=',user.company_id.fiscal_company_id.id),
- ]
+
+ [('company_id', 'in', user._include_fiscal_company_ids(company_ids))]
+
-
-
+
+
- ['|', '|',
- ('company_id','=',False),
- ('company_id','child_of',[user.company_id.id]),
- ('company_id','=',user.company_id.fiscal_company_id.id),
- ]
-
-
-
-
-
-
- Account Fiscal Year - CAE Rule
-
- ['|', '|',
- ('company_id','=',False),
- ('company_id','child_of',[user.company_id.id]),
- ('company_id','=',user.company_id.fiscal_company_id.id),
- ]
+
+ [('company_id', 'in', user._include_fiscal_company_ids(company_ids))]
+
diff --git a/fiscal_company_account/tests/__init__.py b/fiscal_company_account/tests/__init__.py
index db8382f..2e37774 100644
--- a/fiscal_company_account/tests/__init__.py
+++ b/fiscal_company_account/tests/__init__.py
@@ -1,3 +1,3 @@
-from . import test_tax_filtered
-from . import test_decorator
-from . import test_propagate_properties
+from . import test_account_journal_dashboard
+from . import test_mixin_change_filtered
+from . import test_mixin_change_search_domain
diff --git a/fiscal_company_account/tests/test_abstract.py b/fiscal_company_account/tests/test_abstract.py
new file mode 100644
index 0000000..0cecc87
--- /dev/null
+++ b/fiscal_company_account/tests/test_abstract.py
@@ -0,0 +1,15 @@
+# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop)
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from odoo.addons.fiscal_company_base.tests import test_abstract
+
+
+class TestAbstract(test_abstract.TestAbstract):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.AccountAccount = cls.env["account.account"]
+ cls.ProductProduct = cls.env["product.product"]
+ cls.AccountMove = cls.env["account.move"]
+ cls.AccountJournal = cls.env["account.journal"]
diff --git a/fiscal_company_account/tests/test_account_journal_dashboard.py b/fiscal_company_account/tests/test_account_journal_dashboard.py
new file mode 100644
index 0000000..0dc3734
--- /dev/null
+++ b/fiscal_company_account/tests/test_account_journal_dashboard.py
@@ -0,0 +1,62 @@
+# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop)
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+import json
+
+from odoo import Command
+
+from .test_abstract import TestAbstract
+
+
+class TestAccountJournalDashboard(TestAbstract):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.user_accountant.company_id = cls.child_company
+
+ move_vals = {
+ "partner_id": cls.ResPartner.with_user(cls.user_accountant)
+ .search([])[0]
+ .id,
+ "move_type": "out_invoice",
+ "line_ids": [
+ Command.create(
+ {
+ "product_id": cls.ProductProduct.with_user(cls.user_accountant)
+ .search([])[0]
+ .id
+ }
+ )
+ ],
+ }
+ cls.move1 = cls.AccountMove.with_user(cls.user_accountant).create(move_vals)
+ cls.move2 = cls.AccountMove.with_user(cls.user_accountant).create(move_vals)
+ cls.move3 = cls.AccountMove.with_user(cls.user_accountant).create(move_vals)
+ (cls.move1 | cls.move2).action_post()
+
+ def test_01_dashboard_in_fiscal_child(self):
+ self.user_accountant.company_id = self.child_company
+ sale_journal = self.AccountJournal.with_user(self.user_accountant).search(
+ [("type", "=", "sale")]
+ )
+ res = json.loads(sale_journal.kanban_dashboard)
+ self.assertEqual(res.get("number_draft"), 1)
+ self.assertEqual(res.get("number_waiting"), 2)
+ self.assertEqual(res.get("entries_count"), 3)
+
+ res = json.loads(sale_journal.kanban_dashboard_graph)
+ self.assertEqual(len(res[0].get("values")), 0)
+
+ def test_02_dashboard_in_fiscal_mother(self):
+ self.user_accountant.company_id = self.mother_company
+ sale_journal = self.AccountJournal.with_user(self.user_accountant).search(
+ [("type", "=", "sale")]
+ )
+ res = json.loads(sale_journal.kanban_dashboard)
+ self.assertEqual(res.get("number_draft"), 0)
+ self.assertEqual(res.get("number_waiting"), 0)
+ self.assertEqual(res.get("entries_count"), 0)
+
+ res = json.loads(sale_journal.kanban_dashboard_graph)
+ self.assertEqual(len(res[0].get("values")), 6)
diff --git a/fiscal_company_account/tests/test_decorator.py b/fiscal_company_account/tests/test_decorator.py
deleted file mode 100644
index bc8cd36..0000000
--- a/fiscal_company_account/tests/test_decorator.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2013 - Today: GRAP (http://www.grap.coop)
-# @author Julien WESTE
-# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-
-from odoo.tests.common import TransactionCase
-
-# from odoo.addons.fiscal_company_base.fix_test import fix_required_field
-
-
-class TestDecorator(TransactionCase):
- """Tests for Account Fiscal Company Module (Decorator)"""
-
- def setUp(self):
- super().setUp()
- self.AccountAccount = self.env["account.account"]
- self.AccountJournal = self.env["account.journal"]
- self.user_accountant = self.env.ref("fiscal_company_base.user_accountant")
- self.child_company = self.env.ref("fiscal_company_base.company_fiscal_child_1")
- self.mother_company = self.env.ref("fiscal_company_base.company_fiscal_mother")
- # fix_required_field(self, 'DROP')
-
- # def tearDown(self):
- # self.cr.rollback()
- # fix_required_field(self, 'SET')
- # super().tearDown()
-
- # Test Section
- def test_01_decorator_account_account(self):
- """Searching an account in a child company should return
- accounts of the mother company"""
- self.user_accountant.company_id = self.child_company.id
- res = self.AccountAccount.sudo(self.user_accountant).search(
- [("company_id", "=", self.mother_company.id)]
- )
- self.assertNotEqual(
- len(res),
- 0,
- "Searching accounts in a fiscal child company should return"
- " accounts of the mother company",
- )
-
- # Test Section
- def test_02_decorator_account_journal(self):
- """Searching a journal in a child company should return
- journals of the mother company"""
- self.user_accountant.company_id = self.child_company.id
- res = self.AccountJournal.sudo(self.user_accountant).search(
- [("company_id", "=", self.mother_company.id)]
- )
- self.assertNotEqual(
- len(res),
- 0,
- "Searching accounts in a fiscal child company should return"
- " accounts of the mother company",
- )
diff --git a/fiscal_company_account/tests/test_tax_filtered.py b/fiscal_company_account/tests/test_mixin_change_filtered.py
similarity index 84%
rename from fiscal_company_account/tests/test_tax_filtered.py
rename to fiscal_company_account/tests/test_mixin_change_filtered.py
index 22ba049..822f9e1 100644
--- a/fiscal_company_account/tests/test_tax_filtered.py
+++ b/fiscal_company_account/tests/test_mixin_change_filtered.py
@@ -2,19 +2,16 @@
# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from odoo.tests.common import TransactionCase
+from .test_abstract import TestAbstract
-class TestTaxFiltered(TransactionCase):
- """Tests for Account Fiscal Company Module (Tax filter)"""
-
- def setUp(self):
- super().setUp()
- self.taxes = self.env.ref("fiscal_company_account.sale_tax_20") | self.env.ref(
+class TestMixinChangeFiltered(TestAbstract):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.taxes = cls.env.ref("fiscal_company_account.sale_tax_20") | cls.env.ref(
"fiscal_company_account.purchase_tax_20"
)
- self.child_company = self.env.ref("fiscal_company_base.company_fiscal_child_1")
- self.mother_company = self.env.ref("fiscal_company_base.company_fiscal_mother")
# Test Section
def test_01_filter_company(self):
@@ -71,7 +68,7 @@ def test_01_filter_company(self):
len(filtered_taxes), 0, "Filtering taxes by name should worker (3/3"
)
- def test_that_should_fail(self):
+ def test_02_filter_company_that_should_fail(self):
# we test multiple filter in the same time.
# The non company condition will not be applyed (and should be).
# It is a limitation of the current implementation.
diff --git a/fiscal_company_account/tests/test_mixin_change_search_domain.py b/fiscal_company_account/tests/test_mixin_change_search_domain.py
new file mode 100644
index 0000000..bb016a6
--- /dev/null
+++ b/fiscal_company_account/tests/test_mixin_change_search_domain.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2013 - Today: GRAP (http://www.grap.coop)
+# @author Julien WESTE
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+
+from .test_abstract import TestAbstract
+
+
+class TestMixinChangeSearchDomain(TestAbstract):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.user_accountant.company_id = cls.child_company.id
+
+ # Test Section
+ def test_01_mixin_change_search_domain_account_account(self):
+ """Searching an account in a child company should return
+ accounts of the mother company"""
+ res = self.AccountAccount.with_user(self.user_accountant).search(
+ [("company_id", "=", self.mother_company.id)]
+ )
+ self.assertNotEqual(
+ len(res),
+ 0,
+ "Searching accounts in a fiscal child company should return"
+ " accounts of the mother company",
+ )
+
+ def test_02_mixin_change_search_domain_account_journal(self):
+ """Searching a journal in a child company should return
+ journals of the mother company"""
+ self.user_accountant.company_id = self.child_company.id
+ res = self.AccountJournal.with_user(self.user_accountant).search(
+ [("company_id", "=", self.mother_company.id)]
+ )
+ self.assertNotEqual(
+ len(res),
+ 0,
+ "Searching accounts in a fiscal child company should return"
+ " accounts of the mother company",
+ )
diff --git a/fiscal_company_account/tests/test_propagate_properties.py b/fiscal_company_account/tests/test_propagate_properties.py
deleted file mode 100644
index aca7dd8..0000000
--- a/fiscal_company_account/tests/test_propagate_properties.py
+++ /dev/null
@@ -1,295 +0,0 @@
-# Copyright (C) 2013 - Today: GRAP (http://www.grap.coop)
-# @author Julien WESTE
-# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-
-from odoo.tests.common import TransactionCase
-
-# from odoo.addons.fiscal_company_base.fix_test import fix_required_field
-
-
-class TestPropagateProperties(TransactionCase):
- """Tests for Account Fiscal Company Module (Propagate Properties)"""
-
- def setUp(self):
- super().setUp()
- self.ResCompany = self.env["res.company"]
- self.ResPartner = self.env["res.partner"]
- self.ProductTemplate = self.env["product.template"]
- self.ProductProduct = self.env["product.product"]
-
- self.mother_company = self.env.ref("fiscal_company_base.company_fiscal_mother")
- self.child_company = self.env.ref("fiscal_company_base.company_fiscal_child_1")
- self.account_expense_cae = self.env.ref(
- "fiscal_company_account.account_expense_cae"
- )
- self.account_income_cae = self.env.ref(
- "fiscal_company_account.account_income_cae"
- )
- self.account_payable_cae = self.env.ref(
- "fiscal_company_account.account_payable_cae"
- )
- self.account_receivable_cae = self.env.ref(
- "fiscal_company_account.account_receivable_cae"
- )
- self.account_custom_payable_cae = self.env.ref(
- "fiscal_company_account.account_custom_payable_cae"
- )
- self.account_custom_receivable_cae = self.env.ref(
- "fiscal_company_account.account_custom_receivable_cae"
- )
-
- self.accountant = self.env.ref("fiscal_company_base.user_accountant")
-
- # Object with demo accounting properties
- self.product_template_mother_property = self.env.ref(
- "fiscal_company_account.product_template_mother_property"
- )
- self.product_product_mother_property = self.env.ref(
- "fiscal_company_account.product_product_mother_property"
- )
- self.partner_mother_property = self.env.ref(
- "fiscal_company_account.partner_mother_property"
- )
-
- # Object without demo accounting properties
- self.product_template_mother = self.env.ref(
- "fiscal_company_product.product_template_mother"
- )
- self.product_template_child = self.env.ref(
- "fiscal_company_product.product_template_child"
- )
- self.product_product_mother = self.env.ref(
- "fiscal_company_product.product_product_mother"
- )
- self.product_product_child = self.env.ref(
- "fiscal_company_product.product_product_child"
- )
- # fix_required_field(self, 'DROP')
-
- # def tearDown(self):
- # self.cr.rollback()
- # fix_required_field(self, 'SET')
- # super().tearDown()
-
- # Test Section
- def test_01_account_property_propagation_new_company(self):
- """Create a new child company must propagate properties"""
-
- # Create a new Child company
- child_company = self.ResCompany.create(
- {
- "name": "Your Test Child Company",
- "fiscal_type": "fiscal_child",
- "fiscal_company_id": self.mother_company.id,
- "parent_id": self.mother_company.id,
- }
- )
-
- # Change current company and load objects with the new context
- self.env.user.company_id = child_company.id
-
- # Check if product properties has been propagated for the new company
- product = self.ProductProduct.browse([self.product_product_mother_property.id])
- self.assertEqual(
- product.property_account_expense_id.id,
- self.account_expense_cae.id,
- "Create a new child company must set expense account property"
- " of the mother company to the new child company for product.",
- )
-
- self.assertEqual(
- product.property_account_income_id.id,
- self.account_income_cae.id,
- "Create a new child company must set income account property"
- " of the mother company to the new child company for product.",
- )
-
- # Check if template properties has been propagated for the new company
- template = self.ProductTemplate.browse(
- [self.product_template_mother_property.id]
- )
- self.assertEqual(
- template.property_account_expense_id.id,
- self.account_expense_cae.id,
- "Create a new child company must set expense account property"
- " of the mother company to the new child company for template.",
- )
-
- self.assertEqual(
- template.property_account_income_id.id,
- self.account_income_cae.id,
- "Create a new child company must set income account property"
- " of the mother company to the new child company for template.",
- )
-
- # Check if custom partner properties has been propagated for the new
- # company
- partner = self.ResPartner.browse([self.partner_mother_property.id])
- self.assertEqual(
- partner.property_account_payable_id.id,
- self.account_custom_payable_cae.id,
- "Create a new child company must set custom payable account"
- " property of the mother company to the new child company for"
- " partner.",
- )
-
- self.assertEqual(
- partner.property_account_receivable_id.id,
- self.account_custom_receivable_cae.id,
- "Create a new child company must set custom receivable account"
- " property of the mother company to the new child company for"
- " partner.",
- )
-
- def test_03_template_mother_propagate_fiscal_property_to_all(self):
- """Change a template property of a fiscal company must change the value
- for all other companies if the template belong to the
- fiscal mother company"""
-
- template_id = self.env.ref("fiscal_company_product.product_template_mother").id
-
- ProductTemplateAccountant = self.env["product.template"].sudo(self.accountant)
- self.accountant.company_id = self.mother_company.id
-
- templateInMotherCompany = ProductTemplateAccountant.browse(template_id)
-
- templateInMotherCompany.write(
- {
- "property_account_expense_id": self.account_expense_cae.id,
- "property_account_income_id": self.account_income_cae.id,
- }
- )
-
- # Change current company and load template with the new context
- self.accountant.company_id = self.child_company.id
-
- # self.env.user.company_id = self.child_company.id
- templateInChildCompany = ProductTemplateAccountant.browse(template_id)
-
- # Check if properties has been propagated to the other company
- self.assertEqual(
- templateInChildCompany.property_account_expense_id.id,
- self.account_expense_cae.id,
- "Change an expense property for a template in a mother company"
- " must change the value for all the other fiscal company.",
- )
-
- self.assertEqual(
- templateInChildCompany.property_account_income_id.id,
- self.account_income_cae.id,
- "Change an income property for a template in a mother company"
- " must change the value for all the other fiscal company.",
- )
-
- def test_04_template_child_propagate_fiscal_property_to_all(self):
- """Change a template property of a fiscal company must not change the
- value for all other companies if the template belong to a
- fiscal child company"""
-
- # Change current company
- self.env.user.company_id = self.child_company.id
-
- self.product_template_child.write(
- {
- "property_account_expense_id": self.account_expense_cae.id,
- "property_account_income_id": self.account_income_cae.id,
- }
- )
-
- # Change current company and load template with the new context
- self.env.user.company_id = self.mother_company.id
- template = self.ProductTemplate.browse([self.product_template_child.id])
-
- # Check if properties has not been propagated to the other company
- self.assertNotEqual(
- template.property_account_expense_id.id,
- self.account_expense_cae.id,
- "Change an expense property for a template in a child company"
- " must change the value for all the other fiscal company.",
- )
-
- self.assertNotEqual(
- template.property_account_income_id.id,
- self.account_income_cae.id,
- "Change an income property for a template in a child company"
- " must not change the value for all the other fiscal company.",
- )
-
- def test_05_product_mother_propagate_fiscal_property_to_all(self):
- """Change a product property of a fiscal company must change the value
- for all other companies if the product belong to the
- fiscal mother company"""
-
- product_id = self.env.ref(
- "fiscal_company_account.product_product_mother_property"
- ).id
-
- ProductProductAccountant = self.env["product.product"].sudo(self.accountant)
-
- # Change current company
- self.accountant.company_id = self.mother_company.id
-
- productInMotherCompany = ProductProductAccountant.browse(product_id)
-
- productInMotherCompany.write(
- {
- "property_account_expense_id": self.account_expense_cae.id,
- "property_account_income_id": self.account_income_cae.id,
- }
- )
-
- # Change current company and load template with the new context
- self.accountant.company_id = self.child_company.id
-
- # self.env.user.company_id = self.child_company.id
- productInChildCompany = ProductProductAccountant.browse(product_id)
-
- # Check if properties has been propagated to the other company
- self.assertEqual(
- productInChildCompany.property_account_expense_id.id,
- self.account_expense_cae.id,
- "Change an expense property for a product in a mother company"
- " must change the value for all the other fiscal company.",
- )
-
- self.assertEqual(
- productInChildCompany.property_account_income_id.id,
- self.account_income_cae.id,
- "Change an income property for a product in a mother company"
- " must change the value for all the other fiscal company.",
- )
-
- def test_06_product_child_propagate_fiscal_property_to_all(self):
- """Change a product property of a fiscal company must not change the
- value for all other companies if the product belong to a
- fiscal child company"""
-
- # Change current company
- self.env.user.company_id = self.child_company.id
-
- self.product_product_child.write(
- {
- "property_account_expense_id": self.account_expense_cae.id,
- "property_account_income_id": self.account_income_cae.id,
- }
- )
-
- # Change current company and load product with the new context
- self.env.user.company_id = self.mother_company.id
- product = self.ProductProduct.browse([self.product_product_child.id])
-
- # Check if properties has not been propagated to the other company
- self.assertNotEqual(
- product.property_account_expense_id.id,
- self.account_expense_cae.id,
- "Change an expense property for a product in a child company"
- " must change the value for all the other fiscal company.",
- )
-
- self.assertNotEqual(
- product.property_account_income_id.id,
- self.account_income_cae.id,
- "Change an income property for a product in a child company"
- " must not change the value for all the other fiscal company.",
- )
diff --git a/fiscal_company_base/demo/res_partner_company.xml b/fiscal_company_base/demo/res_partner_company.xml
index 0e1dd0c..bc0c777 100644
--- a/fiscal_company_base/demo/res_partner_company.xml
+++ b/fiscal_company_base/demo/res_partner_company.xml
@@ -29,6 +29,7 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop)
CAE Company
+
@@ -43,6 +44,7 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop)
Integrated Company 1 (Service)
+
@@ -56,6 +58,7 @@ Copyright (C) 2015-Today GRAP (http://www.grap.coop)
+
Integrated Company 2 (Production)
diff --git a/fiscal_company_base/models/__init__.py b/fiscal_company_base/models/__init__.py
index b455d87..854c25b 100644
--- a/fiscal_company_base/models/__init__.py
+++ b/fiscal_company_base/models/__init__.py
@@ -1,3 +1,6 @@
+from . import models
from . import res_company
+from . import res_users
from . import fiscal_company_change_search_domain_mixin
+from . import fiscal_company_change_filtered_mixin
from . import fiscal_company_check_company_mixin
diff --git a/fiscal_company_base/models/fiscal_company_change_filtered_mixin.py b/fiscal_company_base/models/fiscal_company_change_filtered_mixin.py
new file mode 100644
index 0000000..b09122f
--- /dev/null
+++ b/fiscal_company_base/models/fiscal_company_change_filtered_mixin.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop)
+# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+
+from odoo import models
+
+
+class FiscalCompanyChangeFilteredMixin(models.AbstractModel):
+ """This abstract change the filtered features for models.
+
+ if a filtered is call with "lambda x: x.company_id = company_id"
+ it will be replace by ('company_id', '=', fiscal_company_id)
+ """
+
+ _name = "fiscal.company.change.filtered.mixin"
+ _description = "Fiscal Company : Change Filtered Mixin"
+
+ def filtered(self, func):
+ # a lot of function in Odoo are filtering taxes by the current company
+ # for exemple in 'addons/account/models/account_invoice.py#L1809'
+ # In our CAE case, we replace the current company by the fiscal one.
+
+ # TODO, improve that ugly code.
+ if (
+ not self.env.context.get("dont_change_filter", False)
+ and callable(func)
+ and "company_id" in func.__code__.co_names
+ ):
+ company = self.env.company.fiscal_company_id
+ return super().filtered(lambda x: x.company_id == company)
+ return super().filtered(func)
diff --git a/fiscal_company_base/models/fiscal_company_change_search_domain_mixin.py b/fiscal_company_base/models/fiscal_company_change_search_domain_mixin.py
index 2e80da4..ed5d81b 100644
--- a/fiscal_company_base/models/fiscal_company_change_search_domain_mixin.py
+++ b/fiscal_company_base/models/fiscal_company_change_search_domain_mixin.py
@@ -49,8 +49,15 @@ def _fiscal_company_change_domain(self, domain):
new_operator = "in"
elif item[1] in ["!=", "not in"]:
new_operator = "not in"
+ elif item[1] in ["child_of"]:
+ new_operator = "child_of"
else:
- raise NotImplementedError("Not implemented operator")
+ raise NotImplementedError(
+ "fiscal.company.change.search.domain.mixin:"
+ f" Not implemented operator {item[1]}"
+ f" ({self._name}).\n"
+ f" Full Domain: {domain}"
+ )
if has_false:
new_company_ids.append(False)
diff --git a/fiscal_company_base/models/models.py b/fiscal_company_base/models/models.py
new file mode 100644
index 0000000..926f4f5
--- /dev/null
+++ b/fiscal_company_base/models/models.py
@@ -0,0 +1,16 @@
+# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop)
+# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from odoo import models
+
+with_company_original = models.BaseModel.with_company
+
+
+def with_company(self, company):
+ if self.env.context.get("fiscal_company_disable_switch_company", False):
+ return self
+ return with_company_original(self, company)
+
+
+models.BaseModel.with_company = with_company
diff --git a/fiscal_company_base/models/res_users.py b/fiscal_company_base/models/res_users.py
new file mode 100644
index 0000000..3ea2b61
--- /dev/null
+++ b/fiscal_company_base/models/res_users.py
@@ -0,0 +1,18 @@
+# Copyright (C) 2024-Today: GRAP (http://www.grap.coop)
+# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from odoo import models
+
+
+class ResUsers(models.Model):
+ _inherit = "res.users"
+
+ def _include_fiscal_company_ids(self, company_ids):
+ companies = self.env["res.company"].browse(company_ids)
+ return (
+ company_ids
+ + companies.filtered(lambda x: x.fiscal_type == "fiscal_child")
+ .mapped("parent_id")
+ .ids
+ )
diff --git a/fiscal_company_base/readme/DEVELOP.rst b/fiscal_company_base/readme/DEVELOP.rst
index b130f06..776ec76 100644
--- a/fiscal_company_base/readme/DEVELOP.rst
+++ b/fiscal_company_base/readme/DEVELOP.rst
@@ -1,4 +1,32 @@
-This module introduces 2 mixin:
+This module introduce a contextual key to change the behaviour of with_company.
+
+For exemple, in odoo/addons/account/models/account_move.py file, the following
+code is present
+
+.. code-block:: python
+
+ @api.onchange('partner_id')
+ def _onchange_partner_id(self):
+ self = self.with_company(self.journal_id.company_id)
+ ...
+
+That's annoying, because the company of the journal is not the same as
+the company of the account move. So, in a CAE context, the company of the move
+will be the integrated company, and the company of the journal will be the CAE.
+
+So, it's possible to write the following code, to disable locally the with_company call
+with the following syntax.
+
+
+.. code-block:: python
+
+ @api.onchange("partner_id")
+ def _onchange_partner_id(self):
+ return super(
+ AccountMove, self.with_context(fiscal_company_disable_switch_company=True)
+ )._onchange_partner_id()
+
+This module also introduces 2 mixin:
``fiscal.company.change.search.domain.mixin``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/fiscal_company_base/tests/__init__.py b/fiscal_company_base/tests/__init__.py
index f434a12..637a31b 100644
--- a/fiscal_company_base/tests/__init__.py
+++ b/fiscal_company_base/tests/__init__.py
@@ -1,3 +1,5 @@
from . import test_fiscal_type_constrains
+from . import test_fiscal_company_change_filtered_mixin
from . import test_fiscal_company_change_search_domain_mixin
from . import test_fiscal_company_check_company_mixin
+from . import test_with_company
diff --git a/fiscal_company_base/tests/models.py b/fiscal_company_base/tests/models.py
index b69d827..34a22f4 100644
--- a/fiscal_company_base/tests/models.py
+++ b/fiscal_company_base/tests/models.py
@@ -1,21 +1,42 @@
from odoo import fields, models
+class ModelFiscalCompanyChangeFilteredMixin(models.Model):
+ _name = "model.fiscal.company.change.filtered.mixin"
+ _description = "model.fiscal.company.change.filtered.mixin"
+ _inherit = ["fiscal.company.change.filtered.mixin"]
+
+ company_id = fields.Many2one(comodel_name="res.company")
+
+
class ModelFiscalCompanyChangeSearchDomainMixin(models.Model):
_name = "model.fiscal.company.change.search.domain.mixin"
- _inherit = ["fiscal.company.change.search.domain.mixin"]
-
_description = "model.fiscal.company.change.search.domain.mixin"
+ _inherit = ["fiscal.company.change.search.domain.mixin"]
company_id = fields.Many2one(comodel_name="res.company")
-class FiscalCompanyCheckCompanyMixinFiscalMother(models.Model):
+class ModelFiscalCompanyCheckCompanyMixinFiscalMother(models.Model):
_name = "model.fiscal.company.check.company.mixin.fiscal.mother"
- _inherit = ["fiscal.company.check.company.mixin"]
-
_description = "model.fiscal.company.change.search.domain.mixin"
+ _inherit = ["fiscal.company.check.company.mixin"]
_fiscal_company_forbid_fiscal_type = ["fiscal_mother"]
company_id = fields.Many2one(comodel_name="res.company")
+
+
+class ModelWithCompany(models.Model):
+ _name = "model.with.company"
+ _description = "model.with.company"
+
+ def with_company_disabled(self, company):
+ return self.with_context(
+ fiscal_company_disable_switch_company=True
+ ).with_company(company)
+
+ def with_company_enabled(self, company):
+ return self.with_context(
+ fiscal_company_disable_switch_company=False
+ ).with_company(company)
diff --git a/fiscal_company_base/tests/test_abstract.py b/fiscal_company_base/tests/test_abstract.py
index 48e4d9d..ad35873 100644
--- a/fiscal_company_base/tests/test_abstract.py
+++ b/fiscal_company_base/tests/test_abstract.py
@@ -9,9 +9,10 @@ class TestAbstract(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
-
cls.ResCompany = cls.env["res.company"]
+ cls.ResPartner = cls.env["res.partner"]
cls.group_company = cls.env.ref("fiscal_company_base.company_group")
cls.mother_company = cls.env.ref("fiscal_company_base.company_fiscal_mother")
cls.child_company = cls.env.ref("fiscal_company_base.company_fiscal_child_1")
cls.normal_company = cls.env.ref("base.main_company")
+ cls.user_accountant = cls.env.ref("fiscal_company_base.user_accountant")
diff --git a/fiscal_company_base/tests/test_fiscal_company_change_filtered_mixin.py b/fiscal_company_base/tests/test_fiscal_company_change_filtered_mixin.py
new file mode 100644
index 0000000..5f9774e
--- /dev/null
+++ b/fiscal_company_base/tests/test_fiscal_company_change_filtered_mixin.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop)
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+from odoo_test_helper import FakeModelLoader
+
+from .test_abstract import TestAbstract
+
+
+class TestFiscalCompanyChangeFilteredMixin(TestAbstract):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ # Load a test model using odoo_test_helper
+ cls.loader = FakeModelLoader(cls.env, cls.__module__)
+ cls.loader.backup_registry()
+ from .models import ModelFiscalCompanyChangeFilteredMixin
+
+ cls.loader.update_registry((ModelFiscalCompanyChangeFilteredMixin,))
+
+ cls.model = cls.env["model.fiscal.company.change.filtered.mixin"]
+ cls.items = cls.model.create(
+ [
+ {"company_id": False},
+ {"company_id": cls.group_company.id},
+ {"company_id": cls.normal_company.id},
+ {"company_id": cls.mother_company.id},
+ {"company_id": cls.child_company.id},
+ ]
+ )
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.loader.restore_registry()
+ return super().tearDownClass()
+
+ def test_filtered(self):
+ result = self.items.filtered(lambda x: True)
+ self.assertEqual(len(self.items), 5)
+
+ result = self.items.with_company(self.child_company).filtered(
+ lambda x: x.company_id == self.child_company
+ )
+ self.assertEqual(len(result), 1)
+ self.assertEqual(result.company_id, self.mother_company)
diff --git a/fiscal_company_base/tests/test_fiscal_company_check_company_mixin.py b/fiscal_company_base/tests/test_fiscal_company_check_company_mixin.py
index dcf957d..4064114 100644
--- a/fiscal_company_base/tests/test_fiscal_company_check_company_mixin.py
+++ b/fiscal_company_base/tests/test_fiscal_company_check_company_mixin.py
@@ -15,9 +15,9 @@ def setUpClass(cls):
# Load a test model using odoo_test_helper
cls.loader = FakeModelLoader(cls.env, cls.__module__)
cls.loader.backup_registry()
- from .models import FiscalCompanyCheckCompanyMixinFiscalMother
+ from .models import ModelFiscalCompanyCheckCompanyMixinFiscalMother
- cls.loader.update_registry((FiscalCompanyCheckCompanyMixinFiscalMother,))
+ cls.loader.update_registry((ModelFiscalCompanyCheckCompanyMixinFiscalMother,))
cls.model_fiscal_mother = cls.env[
"model.fiscal.company.check.company.mixin.fiscal.mother"
diff --git a/fiscal_company_base/tests/test_with_company.py b/fiscal_company_base/tests/test_with_company.py
new file mode 100644
index 0000000..2f870e1
--- /dev/null
+++ b/fiscal_company_base/tests/test_with_company.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop)
+# @author Sylvain LE GAL (https://twitter.com/legalsylvain)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+from odoo_test_helper import FakeModelLoader
+
+from .test_abstract import TestAbstract
+
+
+class TestWithCompany(TestAbstract):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ # Load a test model using odoo_test_helper
+ cls.loader = FakeModelLoader(cls.env, cls.__module__)
+ cls.loader.backup_registry()
+ from .models import ModelWithCompany
+
+ cls.loader.update_registry((ModelWithCompany,))
+
+ cls.model_with_company = cls.env["model.with.company"]
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.loader.restore_registry()
+ return super().tearDownClass()
+
+ def test_with_company_change_disabled(self):
+ res = self.model_with_company.with_company_disabled(self.mother_company)
+ self.assertEqual(res.env.company, self.normal_company)
+
+ def test_with_company_change_enabled(self):
+ res = self.model_with_company.with_company_enabled(self.mother_company)
+ self.assertEqual(res.env.company, self.mother_company)