diff --git a/multicompany_property_account/README.rst b/multicompany_property_account/README.rst new file mode 100644 index 00000000..77977cc0 --- /dev/null +++ b/multicompany_property_account/README.rst @@ -0,0 +1,53 @@ +.. image:: https://img.shields.io/badge/license-LGPL--3-blue.png + :target: https://www.gnu.org/licenses/lgpl + :alt: License: LGPL-3 + +============================= +Multicompany Property Account +============================= + +This module is part of a set of modules that allow to set property fields on +a given model for multiple companies simultaneously. Specifically this module: + +* Allows to define the company-specific accounting fields of the product and + product category in the new 'Multi company' page of the product form view. + +* Allows to define the company-specific accounting fields of the partner + in the new 'Multi company' page of the partner form view. + + +Company +------- + +* Adds a page 'Accounting' in the company that allows to maintain + company-specific accounting settings that one would usually maintain + separately for each company in 'Invoicing / Settings'. + + +Credits +======= + +Contributors +------------ + +* Enric Tobella +* Jordi Ballester +* Miquel Raïch +* Lois Rilo + +Do not contact contributors directly about support or help with technical issues. + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/multicompany_property_account/__init__.py b/multicompany_property_account/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/multicompany_property_account/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/multicompany_property_account/__manifest__.py b/multicompany_property_account/__manifest__.py new file mode 100644 index 00000000..64a06d20 --- /dev/null +++ b/multicompany_property_account/__manifest__.py @@ -0,0 +1,25 @@ +# Copyright 2017 Creu Blanca +# Copyright 2017-21 ForgeFlow, S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +{ + "name": "Multi Company Property Account", + "version": "15.0.1.0.0", + "summary": "Account Company Properties", + "author": "Creu Blanca, ForgeFlow, Odoo Community Association (OCA)", + "sequence": 30, + "license": "LGPL-3", + "website": "https://github.com/ForgeFlow/multicompany-fixes", + "depends": ["account", "multicompany_property_product"], + "data": [ + "security/ir.model.access.csv", + "views/partner_views.xml", + "views/product_views.xml", + "views/product_category_views.xml", + "views/res_company_views.xml", + "views/tax_group_views.xml", + ], + "installable": True, + "application": False, + "auto_install": True, +} diff --git a/multicompany_property_account/models/__init__.py b/multicompany_property_account/models/__init__.py new file mode 100644 index 00000000..bc18ceb0 --- /dev/null +++ b/multicompany_property_account/models/__init__.py @@ -0,0 +1,5 @@ +from . import res_company +from . import res_partner +from . import product +from . import product_category +from . import account_tax_group diff --git a/multicompany_property_account/models/account_tax_group.py b/multicompany_property_account/models/account_tax_group.py new file mode 100644 index 00000000..850a3164 --- /dev/null +++ b/multicompany_property_account/models/account_tax_group.py @@ -0,0 +1,95 @@ +# Copyright 2021 Creu Blanca +# Copyright 2021 ForgeFlow, S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo import fields, models + + +class AccountTaxGroup(models.Model): + _inherit = "account.tax.group" + + property_ids = fields.One2many( + comodel_name="account.tax.group.property", + compute="_compute_properties", + inverse="_inverse_properties", + string="Properties", + ) + + def _inverse_properties(self): + """Hack here: We do not really store any value here. + But this allows us to have the fields of the transient + model editable.""" + return + + def _compute_properties(self): + for record in self: + property_obj = self.env["account.tax.group.property"] + values = [] + for company in self.env.companies: + val = property_obj.create( + {"tax_group_id": record.id, "company_id": company.id} + ) + values.append(val.id) + record.property_ids = values + + +class AccountTaxGroupProperty(models.TransientModel): + _name = "account.tax.group.property" + _inherit = "model.property" + _description = "Properties of Tax groups" + + tax_group_id = fields.Many2one(comodel_name="account.tax.group") + property_tax_payable_account_id = fields.Many2one( + "account.account", + compute="_compute_property_fields", + readonly=False, + string="Tax current account (payable)", + ) + property_tax_receivable_account_id = fields.Many2one( + "account.account", + compute="_compute_property_fields", + readonly=False, + string="Tax current account (receivable)", + ) + property_advance_tax_payment_account_id = fields.Many2one( + "account.account", + compute="_compute_property_fields", + readonly=False, + string="Advance Tax payment account", + ) + + def _compute_property_fields(self): + self.ensure_one() + obj = self.tax_group_id + self.get_property_fields( + obj, + self.env["ir.property"].with_company(self.company_id), + ) + + def get_property_fields(self, obj, properties): + for rec in self: + rec.property_tax_payable_account_id = rec.get_property_value( + "property_tax_payable_account_id", obj, properties + ) + rec.property_tax_receivable_account_id = rec.get_property_value( + "property_tax_receivable_account_id", obj, properties + ) + rec.property_advance_tax_payment_account_id = rec.get_property_value( + "property_advance_tax_payment_account_id", obj, properties + ) + + def get_property_fields_list(self): + res = super(AccountTaxGroupProperty, self).get_property_fields_list() + res.append("property_tax_payable_account_id") + res.append("property_tax_receivable_account_id") + res.append("property_advance_tax_payment_account_id") + return res + + def write(self, vals): + prop_obj = self.env["ir.property"].with_company(self.company_id) + p_fields = self.get_property_fields_list() + for field in p_fields: + if field in vals: + for rec in self: + self.set_property(rec.tax_group_id, field, vals[field], prop_obj) + return super(AccountTaxGroupProperty, self).write(vals) diff --git a/multicompany_property_account/models/product.py b/multicompany_property_account/models/product.py new file mode 100644 index 00000000..48d65a42 --- /dev/null +++ b/multicompany_property_account/models/product.py @@ -0,0 +1,49 @@ +# Copyright 2017 Creu Blanca +# Copyright 2017 ForgeFlow, S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo import fields, models + + +class ProductProperty(models.TransientModel): + _inherit = "product.property" + + property_account_income_id = fields.Many2one( + comodel_name="account.account", + string="Income Account", + domain=[("deprecated", "=", False)], + compute="_compute_property_fields", + readonly=False, + store=False, + help="Keep this field empty to use the default value from the " + "product category.", + ) + property_account_expense_id = fields.Many2one( + comodel_name="account.account", + string="Expense Account", + domain=[("deprecated", "=", False)], + compute="_compute_property_fields", + readonly=False, + store=False, + help="Keep this field empty to use the default value from the " + "product category. If anglo-saxon accounting with automated " + "valuation method is configured, the expense account on the " + "product category will be used.", + ) + + def get_property_fields(self, obj, properties): + res = super(ProductProperty, self).get_property_fields(obj, properties) + for rec in self: + rec.property_account_income_id = rec.get_property_value( + "property_account_income_id", obj, properties + ) + rec.property_account_expense_id = rec.get_property_value( + "property_account_expense_id", obj, properties + ) + return res + + def get_property_fields_list(self): + res = super(ProductProperty, self).get_property_fields_list() + res.append("property_account_income_id") + res.append("property_account_expense_id") + return res diff --git a/multicompany_property_account/models/product_category.py b/multicompany_property_account/models/product_category.py new file mode 100644 index 00000000..48888b7a --- /dev/null +++ b/multicompany_property_account/models/product_category.py @@ -0,0 +1,48 @@ +# Copyright 2017 Creu Blanca +# Copyright 2017 ForgeFlow, S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo import fields, models + + +class ProductCategoryProperty(models.TransientModel): + _inherit = "product.category.property" + + property_account_income_categ_id = fields.Many2one( + comodel_name="account.account", + string="Income Account", + domain=[("deprecated", "=", False)], + compute="_compute_property_fields", + readonly=False, + store=False, + help="This account will be used when validating a customer invoice.", + ) + property_account_expense_categ_id = fields.Many2one( + comodel_name="account.account", + string="Expense Account", + domain=[("deprecated", "=", False)], + compute="_compute_property_fields", + readonly=False, + store=False, + help="The expense is accounted for when a vendor bill is validated, " + "except in anglo-saxon accounting with perpetual inventory " + "valuation in which case the expense (Cost of Goods Sold account) " + "is recognized at the customer invoice validation.", + ) + + def get_property_fields(self, obj, properties): + res = super(ProductCategoryProperty, self).get_property_fields(obj, properties) + for rec in self: + rec.property_account_income_categ_id = rec.get_property_value( + "property_account_income_categ_id", obj, properties + ) + rec.property_account_expense_categ_id = rec.get_property_value( + "property_account_expense_categ_id", obj, properties + ) + return res + + def get_property_fields_list(self): + res = super(ProductCategoryProperty, self).get_property_fields_list() + res.append("property_account_income_categ_id") + res.append("property_account_expense_categ_id") + return res diff --git a/multicompany_property_account/models/res_company.py b/multicompany_property_account/models/res_company.py new file mode 100644 index 00000000..4ee5d197 --- /dev/null +++ b/multicompany_property_account/models/res_company.py @@ -0,0 +1,233 @@ +# Copyright 2017 Creu Blanca +# Copyright 2017 ForgeFlow, S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo import api, fields, models + + +class ResCompany(models.Model): + _inherit = "res.company" + + default_sale_tax_id = fields.Many2one( + "account.tax", + string="Default sale tax", + compute="_compute_tax", + inverse="_inverse_tax", + domain="[('type_tax_use', 'in', ('sale', 'all')), " + "('company_id', '=', active_id)]", + store=False, + ) + default_purchase_tax_id = fields.Many2one( + "account.tax", + string="Default purchase tax", + compute="_compute_tax", + inverse="_inverse_tax", + domain="[('type_tax_use', 'in', ('purchase', 'all')), " + "('company_id', '=', active_id)]", + store=False, + ) + transfer_account_id = fields.Many2one( + domain=lambda self: ( + "[" + "('reconcile', '=', True)," + "('user_type_id.id', '='," + + str(self.env.ref("account.data_account_type_current_assets").id) + + ")," + "('company_id', '=', active_id)," + "('deprecated', '=', False)]" + ), + ) + expects_chart_of_accounts = fields.Boolean( + string="Expects a Chart of Accounts", default=True + ) + property_stock_account_input_categ_id = fields.Many2one( + domain="[('company_id', '=', active_id)]", + ) + property_stock_account_output_categ_id = fields.Many2one( + domain="[('company_id', '=', active_id)]", + ) + property_stock_valuation_account_id = fields.Many2one( + domain="[('company_id', '=', active_id)]", + ) + partner_account_payable_id = fields.Many2one( + "account.account", + domain="[('internal_type', '=', 'payable')," + "('deprecated', '=', False)," + "('company_id', '=', active_id)]", + compute="_compute_partner_account_payable", + inverse="_inverse_partner_account_payable", + string="Default Account Payable in Partner", + ) + partner_account_receivable_id = fields.Many2one( + "account.account", + domain="[('internal_type', '=', 'receivable')," + "('deprecated', '=', False)," + "('company_id', '=', active_id)]", + compute="_compute_partner_account_receivable", + inverse="_inverse_partner_account_receivable", + string="Default Account Receivable in Partner", + ) + categ_account_expense_id = fields.Many2one( + "account.account", + domain="[('internal_type', '=', 'expense')," + "('deprecated', '=', False)," + "('company_id', '=', active_id)]", + compute="_compute_categ_account_expense", + inverse="_inverse_categ_account_expense", + string="Default Expense Account in Product Category", + ) + categ_account_income_id = fields.Many2one( + "account.account", + domain="[('internal_type', '=', 'income')," + "('deprecated', '=', False)," + "('company_id', '=', active_id)]", + compute="_compute_categ_account_income", + inverse="_inverse_categ_account_income", + string="Default Income Account in Product Category", + ) + + def get_property_value(self, model, field): + value = self.env["ir.property"].with_company(self).sudo()._get(field, model) + if value: + if isinstance(value, list): + return value[0] + else: + return value + return False + + def set_property_value(self, model, field_name, value): + field = ( + self.env["ir.model.fields"] + .sudo() + .search([("name", "=", field_name), ("model", "=", model)], limit=1) + ) + if isinstance(value, models.BaseModel): + if value: + val = value.id + else: + val = False + else: + val = value + prop = ( + self.env["ir.property"] + .sudo() + .search( + [ + ("name", "=", field_name), + ("fields_id", "=", field.id), + ("company_id", "=", self.id), + ("res_id", "=", False), + ] + ) + ) + if not prop: + prop = ( + self.env["ir.property"] + .sudo() + .create( + { + "name": field_name, + "fields_id": field.id, + "company_id": self.id, + "res_id": False, + } + ) + ) + if isinstance(value, models.BaseModel) and not val: + prop.sudo().unlink() + else: + prop.sudo().write({"value": val}) + + @api.model + def _compute_partner_account_payable(self): + for rec in self: + rec.partner_account_payable_id = rec.get_property_value( + "res.partner", "property_account_payable_id" + ) + + @api.model + def _inverse_partner_account_payable(self): + for rec in self: + rec.set_property_value( + "res.partner", + "property_account_payable_id", + rec.partner_account_payable_id, + ) + + @api.model + def _compute_partner_account_receivable(self): + for rec in self: + rec.partner_account_receivable_id = rec.get_property_value( + "res.partner", "property_account_receivable_id" + ) + + @api.model + def _inverse_partner_account_receivable(self): + for rec in self: + rec.set_property_value( + "res.partner", + "property_account_receivable_id", + rec.partner_account_receivable_id, + ) + + @api.model + def _compute_categ_account_expense(self): + for rec in self: + rec.categ_account_expense_id = rec.get_property_value( + "product.category", "property_account_expense_categ_id" + ) + + @api.model + def _inverse_categ_account_expense(self): + for rec in self: + rec.set_property_value( + "product.category", + "property_account_expense_categ_id", + rec.categ_account_expense_id, + ) + + @api.model + def _compute_categ_account_income(self): + for rec in self: + rec.categ_account_income_id = rec.get_property_value( + "product.category", "property_account_income_categ_id" + ) + + @api.model + def _inverse_categ_account_income(self): + for rec in self: + rec.set_property_value( + "product.category", + "property_account_income_categ_id", + rec.categ_account_income_id, + ) + + @api.model + def _compute_tax(self): + IrDefault = self.env["ir.default"].sudo() + tax_obj = self.env["account.tax"] + for record in self: + record.default_sale_tax_id = tax_obj.browse( + IrDefault.get("product.template", "taxes_id", company_id=record.id) + ) + record.default_purchase_tax_id = tax_obj.browse( + IrDefault.get( + "product.template", "supplier_taxes_id", company_id=record.id + ) + ) + + def _inverse_tax(self): + IrDefault = self.env["ir.default"].sudo() + for record in self: + IrDefault.set( + "product.template", + "taxes_id", + record.default_sale_tax_id.ids, + company_id=record.id, + ) + IrDefault.set( + "product.template", + "supplier_taxes_id", + record.default_purchase_tax_id.ids, + company_id=record.id, + ) diff --git a/multicompany_property_account/models/res_partner.py b/multicompany_property_account/models/res_partner.py new file mode 100644 index 00000000..48b7ed05 --- /dev/null +++ b/multicompany_property_account/models/res_partner.py @@ -0,0 +1,97 @@ +# Copyright 2017 Creu Blanca +# Copyright 2017 ForgeFlow, S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo import fields, models + + +class PartnerProperty(models.TransientModel): + _inherit = "res.partner.property" + + property_account_payable_id = fields.Many2one( + comodel_name="account.account", + string="Account Payable", + domain="[('internal_type', '=', 'payable'), ('deprecated', '=', False)]", + compute="_compute_property_fields", + readonly=False, + store=False, + help="This account will be used instead of the default " + "one as the payable account for the current partner", + required=True, + ) + property_account_receivable_id = fields.Many2one( + comodel_name="account.account", + string="Account Receivable", + domain="[('internal_type', '=', 'receivable'), ('deprecated', '=', False)]", + compute="_compute_property_fields", + readonly=False, + store=False, + help="This account will be used instead of " + "the default one as the receivable account " + "for the current partner", + required=True, + ) + property_account_position_id = fields.Many2one( + comodel_name="account.fiscal.position", + string="Fiscal Position", + compute="_compute_property_fields", + readonly=False, + store=False, + help="The fiscal position determines the taxes/accounts " + "used for this contact.", + ) + property_payment_term_id = fields.Many2one( + comodel_name="account.payment.term", + string="Customer Payment Terms", + compute="_compute_property_fields", + readonly=False, + store=False, + help="This payment term will be used instead of the " + "default one for sale orders and customer invoices", + ) + property_supplier_payment_term_id = fields.Many2one( + comodel_name="account.payment.term", + string="Vendor Payment Terms", + compute="_compute_property_fields", + readonly=False, + store=False, + help="This payment term will be used instead of the " + "default one for purchase orders and vendor bills", + ) + trust = fields.Selection( + [("good", "Good Debtor"), ("normal", "Normal Debtor"), ("bad", "Bad Debtor")], + string="Degree of trust you have in this debtor", + compute="_compute_property_fields", + readonly=False, + ) + + def get_property_fields(self, obj, properties): + res = super(PartnerProperty, self).get_property_fields(obj, properties) + for rec in self: + rec.property_account_payable_id = rec.get_property_value( + "property_account_payable_id", obj, properties + ) + rec.property_account_receivable_id = rec.get_property_value( + "property_account_receivable_id", obj, properties + ) + rec.property_account_position_id = rec.get_property_value( + "property_account_position_id", obj, properties + ) + rec.property_payment_term_id = rec.get_property_value( + "property_payment_term_id", obj, properties + ) + rec.property_supplier_payment_term_id = rec.get_property_value( + "property_supplier_payment_term_id", obj, properties + ) + rec.trust = rec.get_property_value("trust", obj, properties) + return res + + def get_property_fields_list(self): + res = super(PartnerProperty, self).get_property_fields_list() + res.append("property_account_payable_id") + res.append("property_account_receivable_id") + res.append("property_account_position_id") + res.append("property_payment_term_id") + res.append("property_supplier_payment_term_id") + res.append("trust") + return res diff --git a/multicompany_property_account/security/ir.model.access.csv b/multicompany_property_account/security/ir.model.access.csv new file mode 100644 index 00000000..bc6fc2ef --- /dev/null +++ b/multicompany_property_account/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_account_tax_group_property,access_account_tax_group_property,model_account_tax_group_property,base.group_user,1,1,1,1 diff --git a/multicompany_property_account/static/description/icon.png b/multicompany_property_account/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/multicompany_property_account/static/description/icon.png differ diff --git a/multicompany_property_account/tests/__init__.py b/multicompany_property_account/tests/__init__.py new file mode 100644 index 00000000..658a348e --- /dev/null +++ b/multicompany_property_account/tests/__init__.py @@ -0,0 +1,2 @@ +from . import test_multicompany +from . import test_account_company_config diff --git a/multicompany_property_account/tests/test_account_company_config.py b/multicompany_property_account/tests/test_account_company_config.py new file mode 100644 index 00000000..be8f1193 --- /dev/null +++ b/multicompany_property_account/tests/test_account_company_config.py @@ -0,0 +1,59 @@ +# Copyright 2017 Creu Blanca +# Copyright 2017 ForgeFlow, S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from ..tests import test_multicompany + + +class TestAccountCompanyConfig(test_multicompany.TestMulticompanyProperty): + def test_company_config_defaults(self): + purchase_tax = self.env["account.tax"].search( + [ + ("type_tax_use", "in", ("purchase", "all")), + ("company_id", "=", self.company_1.id), + ("id", "not in", self.company_1.default_purchase_tax_id.ids), + ], + limit=1, + ) + sale_tax = self.env["account.tax"].search( + [ + ("type_tax_use", "in", ("purchase", "all")), + ("company_id", "=", self.company_1.id), + ("id", "not in", self.company_1.default_sale_tax_id.ids), + ], + limit=1, + ) + ap_account = self.env["account.account"].create( + { + "name": "New default AR", + "code": "NAP", + "user_type_id": self.env.ref("account.data_account_type_payable").id, + "reconcile": True, + "company_id": self.company_1.id, + } + ) + ar_account = self.env["account.account"].create( + { + "name": "New default AR", + "code": "NAR", + "user_type_id": self.env.ref("account.data_account_type_receivable").id, + "reconcile": True, + "company_id": self.company_1.id, + } + ) + self.company_1.write( + { + "default_purchase_tax_id": purchase_tax.id, + "default_sale_tax_id": sale_tax.id, + "partner_account_payable_id": ap_account.id, + "partner_account_receivable_id": ar_account.id, + } + ) + self.assertEqual(self.company_1.default_purchase_tax_id, purchase_tax) + self.assertEqual(self.company_1.default_sale_tax_id, sale_tax) + partner = self.env["res.partner"].create({"name": "Test partner"}) + partner.property_ids.invalidate_cache() + prop = partner.property_ids.filtered(lambda r: r.company_id == self.company_1) + self.assertTrue(prop) + self.assertEqual(prop.property_account_payable_id, ap_account) + self.assertEqual(prop.property_account_receivable_id, ar_account) diff --git a/multicompany_property_account/tests/test_multicompany.py b/multicompany_property_account/tests/test_multicompany.py new file mode 100644 index 00000000..c653df59 --- /dev/null +++ b/multicompany_property_account/tests/test_multicompany.py @@ -0,0 +1,88 @@ +# Copyright 2017 Creu Blanca +# Copyright 2017 ForgeFlow, S.L. +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo.addons.multicompany_property_product.tests import test_multicompany + + +class TestMulticompanyProperty(test_multicompany.TestMulticompanyProperty): + def create_company(self, name): + company = super().create_company(name) + chart_template_id = self.env["account.chart.template"].search([], limit=1) + if not company.chart_template_id: + self.env.user.write( + {"company_ids": [(4, company.id)], "company_id": company.id} + ) + chart_template_id.try_loading() + return company + + def test_partner(self): + res = super().test_partner() + account = self.env["account.account"].search( + [ + ("deprecated", "=", False), + ("internal_type", "=", "payable"), + ("company_id", "=", self.company_1.id), + ], + limit=1, + ) + self.assertTrue(account) + prop = self.partner.property_ids.filtered( + lambda r: r.company_id == self.company_1 + ) + prop.write({"property_account_payable_id": account.id}) + self.assertEqual( + self.partner.with_company(self.company_1).property_account_payable_id, + account, + ) + self.assertEqual( + self.partner.with_company(self.company_1).property_account_payable_id, + prop.property_account_payable_id, + ) + return res + + def test_product_category(self): + res = super().test_product_category() + account = self.env["account.account"].search( + [("deprecated", "=", False), ("company_id", "=", self.company_1.id)], + limit=1, + ) + self.assertTrue(account) + prop = self.category.property_ids.filtered( + lambda r: r.company_id == self.company_1 + ) + prop.write({"property_account_income_categ_id": account.id}) + self.assertEqual( + self.category.with_company(self.company_1).property_account_income_categ_id, + account, + ) + self.assertEqual( + self.category.with_company(self.company_1).property_account_income_categ_id, + prop.property_account_income_categ_id, + ) + return res + + def test_product_template(self): + res = super().test_product_template() + account = self.env["account.account"].search( + [("deprecated", "=", False), ("company_id", "=", self.company_1.id)], + limit=1, + ) + self.assertTrue(account) + prop = self.product_template.property_ids.filtered( + lambda r: r.company_id == self.company_1 + ) + prop.write({"property_account_income_id": account.id}) + self.assertEqual( + self.product_template.with_company( + self.company_1 + ).property_account_income_id, + account, + ) + self.assertEqual( + self.product_template.with_company( + self.company_1 + ).property_account_income_id, + prop.property_account_income_id, + ) + return res diff --git a/multicompany_property_account/views/partner_views.xml b/multicompany_property_account/views/partner_views.xml new file mode 100644 index 00000000..f38e89f5 --- /dev/null +++ b/multicompany_property_account/views/partner_views.xml @@ -0,0 +1,96 @@ + + + + res.partner.property.form.inherit + res.partner + + + + True + + + True + + + True + 0 + + + True + 0 + + + True + + + + + res.partner.property.tree + res.partner.property + + + + + + + + + + + + + res.partner.property.form + res.partner.property + + + + + + + + + + + + + + + + + diff --git a/multicompany_property_account/views/product_category_views.xml b/multicompany_property_account/views/product_category_views.xml new file mode 100644 index 00000000..60371b04 --- /dev/null +++ b/multicompany_property_account/views/product_category_views.xml @@ -0,0 +1,40 @@ + + + + product.category.property.form.inherit + product.category + + + + True + + + True + + + + + product.category.property.form + product.category.property + + + + + + + + + + + + + diff --git a/multicompany_property_account/views/product_views.xml b/multicompany_property_account/views/product_views.xml new file mode 100644 index 00000000..f32d3d8c --- /dev/null +++ b/multicompany_property_account/views/product_views.xml @@ -0,0 +1,62 @@ + + + + product.template.form.inherit + product.template + + + + True + + + True + + + + + product.property.form + product.property + + + + + + + + + + + + + + + product.property.tree + product.property + + + + + + + + + + diff --git a/multicompany_property_account/views/res_company_views.xml b/multicompany_property_account/views/res_company_views.xml new file mode 100644 index 00000000..be8752f2 --- /dev/null +++ b/multicompany_property_account/views/res_company_views.xml @@ -0,0 +1,56 @@ + + + + + res.company.form + res.company + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/multicompany_property_account/views/tax_group_views.xml b/multicompany_property_account/views/tax_group_views.xml new file mode 100644 index 00000000..5b83b3be --- /dev/null +++ b/multicompany_property_account/views/tax_group_views.xml @@ -0,0 +1,38 @@ + + + + + account.tax.group.property.tree + account.tax.group.property + + + + + + + + + account.tax.group.property.form + account.tax.group.property + +
+ + + + + + + + + + + + + + + + +
+
+
+
diff --git a/setup/multicompany_property_account/odoo/addons/multicompany_property_account b/setup/multicompany_property_account/odoo/addons/multicompany_property_account new file mode 120000 index 00000000..9239a6e9 --- /dev/null +++ b/setup/multicompany_property_account/odoo/addons/multicompany_property_account @@ -0,0 +1 @@ +../../../../multicompany_property_account \ No newline at end of file diff --git a/setup/multicompany_property_account/setup.py b/setup/multicompany_property_account/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/multicompany_property_account/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)