From a5b6f31cf28e5381e1c85f66730bcdb55998e643 Mon Sep 17 00:00:00 2001 From: Yannick Tivisse Date: Thu, 25 Apr 2019 15:42:05 +0000 Subject: [PATCH] [IMP] base: Contextualize the multi company Purpose ======= Allow the user to select the allowed companies for which he wants to see records on top of selecting his current company. It is confusing for users to see the records from the company he is connected to and the records of the children companies. Instead of using the hierarchy of companies to access records across companies, the user can now select (from his set of allowed companies) the companies for which he wants to access records. /!\ This means that the user will interact with records from company A when in company B. Example: a SO has been created and confirmed in A. When in B, I create the invoice from it. Specifications ============== 1/ Deprecate the parent/children hierarchy on the res.company model. The fields are kept on the res.company model to ensure the retro-compatibility, but won't be used accross the standard code anymore. The only functional usage for this mechanism was to allow to see records from several companies by creating a virtual parent company, which will be possible with the new mechanism. 2/ By default, a user will only see the records of the company he is connected to (or records without a company). (It is still editable by the user if needed). For that, put this information in the user context, to allow having different configurations on different browser tabs. Instead of having domains like ['|', ('company_id', '=', False), ('company_id', 'child_of', user.company_id.id)] you'll have something like ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] Note that the 'company_ids' is a value that is passed in the evaluation context on the record rule, as we already have user, or time. company_ids is a list of the ids of all the enabled companies in the user's context. 3/ Out of the generic improvements brought by this task, this will illustrate issues that could exist since several versions. For example, it should not be possible to create a scrap order for the company A with a package of the company B, or it should not be possible to create an invoice on the company A with payment terms from the company B. Before the version 12.0, it was easy to encounter this kind of issues as the admin was the SUPERUSER_ID. A positive side effect of the fact that the SUPERUSER_ID has become an inactive user was to make it more difficult to introduce mismatch on the records, but haven't solved the issue, as it was still possible to do it with parent companies configuration. Some of these issues have been fixed in this commit, but all the business flows should be re-tested to check if an ir.rule should be introduced (eg: a multi company rule for stock.quand.package), if the company of a record is correctly transfered to another record created from the first record (eg: From a SO, create an invoice and a payment, the company of the sales order should be transfered on the invoice and the payment, even if the company of the sales order is A and I'm logged into the company B with the company A enabled. 4/ Currently, if I click on a button on a notification email (example 'View Task'), I face a traceback if I'm not logged into the company of the record. Now, if you click on a button and if you have access to the record, the correct company will be automatically set. 5/ If I display a kanban view with several records from several companies (and an image), all the images should be displayed. 6/ Currently if you copy paste an url, this will crash if you're not in the correct company. This won't be fixed because it's quite impossible to do it in a clean way. This task brings a workaround. Copy/Paste -> Traceback -> Log into the correct company, re-copy/paste -> Ok. 7/ 2 property methods have been added on the environment to retrieve the company on which the user is logged in and the companies the user enabled, on a specific tab. That way, when creating a record, instead of doing default=lambda self: self.env.user.company_id do default=lambda self: self.env.company_id On the other hand, to retrieve the enabled companies, do companies = self.env.company_ids 8/ Modify the Company Switcher widget to allow to log into another company WITHOUT writing on the res.users (and thus bringing cache invalidation issues and so on). Also allow to enable several companies and see records from several companies, and independantly of the other browser's tabs. 9/ When focusing on a tab, save the current company configuration on the local storage. That way, when doing 'CTRL+T' or a middle click, the context is propagated to the new tab. 10/ Improve the error message in case of multi company access errors. Now, when the user is in debug mode, display the related names of the records and the name of the user who brings the issue. 11/ Remove the context erasing when writing on a res.users This is probably coming from the migration to new API of the base module. The context was not propagated at this moment, which was a common mistake at that time. When migrating the module, probably by using the 'black box' method, as the context was not propagated, it was erased on the new version. This is now an issue because the context (i.e. the enabled companies) was erased when writing on a res.users, leading to tracebacks. See: https://github.com/odoo/odoo/commit/7eab8e26d3d46c53f4be924d6a34e80a66e74960#diff-4c2e738ee8f64f11806c889ea097b5e7R624 12/ Fix the crash manager on redirect warnings. The issue is the following - Create an invoice on a company without a configured CoA. - Set a partner - On the onchange_partner_id, a redirect warning is raised to propose you to configure a CoA - Click on 'Go to the configuration panel' - A generic warning says something like 'Do you want to discard your changes?' - Click on yes, the page refreshes, but not on the redirect action. Now, set correctly the action on the hash, and reload instead. The breadcrumb is lost for example, but you reach the correct action at least. 13/ Introduce a res.group to enable/disable the multi company per tab feature. 14/ To help the users to know which tab is in which company, add the possibility to have a favicon per company. When creating a company, the classical 'O' icon is colored by default in a random color. 15/ Remove the company switcher on the frontend. This was mainly there to allow a user to swicth to the company linked to the website. This behavior is now transparent to the user. If the website A is activated, then the company set on the context is the company of the website. 16/ Deprecated the _company_default_get method on the res.company model. Remove the method _get_company on the res.users model. 17/ Add 'allowed_company_ids' and 'current_company_id' on the pyeval context. You can now use those variables on domains in the views to access directly to the activated company.ies on the current tab. TaskID: 1960971 closes odoo/odoo#32341 Signed-off-by: Yannick Tivisse (yti) --- addons/account/__init__.py | 2 +- addons/account/controllers/onboarding.py | 4 +- addons/account/models/account.py | 20 ++--- .../account/models/account_bank_statement.py | 4 +- addons/account/models/account_fiscal_year.py | 2 +- addons/account/models/account_invoice.py | 16 ++-- .../models/account_journal_dashboard.py | 2 +- addons/account/models/account_move.py | 16 ++-- addons/account/models/account_payment.py | 6 +- addons/account/models/account_payment_term.py | 2 +- .../account/models/account_reconcile_model.py | 2 +- addons/account/models/chart_template.py | 18 ++-- addons/account/models/company.py | 16 ++-- addons/account/models/partner.py | 12 +-- addons/account/models/product.py | 4 +- .../account/models/reconciliation_widget.py | 2 +- addons/account/models/res_config_settings.py | 2 +- .../report/account_aged_partner_balance.py | 10 +-- .../account/report/account_invoice_report.py | 4 +- addons/account/security/account_security.xml | 30 +++---- addons/account/tests/account_test_classes.py | 2 +- addons/account/tests/test_account_all_l10n.py | 2 +- .../tests/test_account_customer_invoice.py | 4 +- .../test_bank_statement_reconciliation.py | 2 +- addons/account/tests/test_reconciliation.py | 6 +- addons/account/wizard/account_invoice_send.py | 4 +- .../account/wizard/account_report_common.py | 2 +- addons/account/wizard/setup_wizards.py | 8 +- .../account/wizard/wizard_tax_adjustments.py | 2 +- .../account_analytic_default_security.xml | 2 +- .../account_bank_statement_import.py | 2 +- .../account_facturx/models/account_invoice.py | 2 +- .../account_tax_python/models/account_tax.py | 4 +- .../account_voucher/models/account_voucher.py | 10 +-- .../security/account_voucher_security.xml | 4 +- addons/analytic/models/analytic_account.py | 10 +-- .../analytic/security/analytic_security.xml | 8 +- .../base_setup/models/res_config_settings.py | 7 +- .../views/res_config_settings_views.xml | 12 +++ addons/base_vat/models/res_partner.py | 4 +- addons/crm/models/crm_lead.py | 4 +- addons/crm/security/crm_security.xml | 4 +- .../crm/tests/test_new_lead_notification.py | 2 +- .../models/crm_reveal_rule.py | 2 +- addons/delivery/models/stock_picking.py | 2 +- .../security/delivery_carrier_security.xml | 2 +- addons/delivery/tests/test_delivery_cost.py | 2 +- addons/digest/models/digest.py | 2 +- addons/event/models/event.py | 6 +- addons/event/security/event_security.xml | 4 +- addons/event_sale/models/sale_order.py | 2 +- addons/fleet/models/fleet_vehicle.py | 2 +- addons/fleet/models/fleet_vehicle_cost.py | 2 +- addons/gamification/models/goal.py | 2 +- .../security/gamification_security.xml | 2 +- addons/hr/models/hr.py | 4 +- addons/hr/models/res_partner.py | 3 +- addons/hr/security/hr_security.xml | 6 +- .../models/hr_employee.py | 2 +- addons/hr_contract/models/hr_contract.py | 4 +- addons/hr_contract/security/security.xml | 2 +- addons/hr_expense/models/hr_expense.py | 12 +-- addons/hr_expense/security/ir_rule.xml | 4 +- addons/hr_expense/tests/test_expenses.py | 6 +- .../hr_expense_sheet_register_payment.py | 2 +- addons/hr_holidays/models/hr_leave.py | 15 ++-- .../hr_holidays/models/hr_leave_allocation.py | 3 + addons/hr_holidays/models/hr_leave_type.py | 4 +- .../security/hr_holidays_security.xml | 4 +- .../hr_org_chart/controllers/hr_org_chart.py | 18 ++-- .../static/src/js/hr_org_chart.js | 7 +- addons/hr_presence/models/hr_employee.py | 2 +- addons/hr_recruitment/models/hr_job.py | 2 +- .../hr_recruitment/models/hr_recruitment.py | 2 +- .../security/hr_recruitment_security.xml | 2 +- addons/hr_timesheet/models/hr_timesheet.py | 4 +- addons/hr_timesheet/models/ir_http.py | 2 +- addons/hr_timesheet/models/project.py | 2 +- addons/iap/models/iap.py | 4 +- addons/iap/security/ir_rule.xml | 4 +- addons/l10n_de/models/chart_template.py | 2 +- addons/l10n_do/models/chart_template.py | 2 +- addons/l10n_eu_service/wizard/wizard.py | 2 +- .../data/account_move.xml | 2 +- .../l10n_fr_certification/models/account.py | 2 +- addons/l10n_fr_fec/wizard/account_fr_fec.py | 4 +- .../data/pos_inalterability.xml | 2 +- addons/l10n_fr_pos_cert/models/pos.py | 2 +- .../security/account_closing_intercompany.xml | 2 +- .../data/account_bank_statement_demo.xml | 14 +-- .../data/account_invoice_demo.xml | 8 +- addons/l10n_in/data/account_invoice_demo.xml | 34 ++++---- addons/l10n_in/data/account_payment_demo.xml | 4 +- addons/l10n_it_edi/models/account_invoice.py | 16 ++-- .../l10n_nl/models/account_chart_template.py | 4 +- addons/lunch/models/lunch_cashmove.py | 2 +- addons/lunch/models/lunch_order.py | 2 +- addons/lunch/models/lunch_product.py | 8 +- addons/lunch/wizard/lunch_line_wizard.py | 2 +- addons/mail/controllers/main.py | 30 ++++++- addons/mail/models/mail_message.py | 2 +- addons/mail/models/mail_template.py | 2 +- addons/mail/models/mail_thread.py | 18 +++- addons/maintenance/models/maintenance.py | 10 +-- addons/maintenance/security/maintenance.xml | 8 +- .../tests/test_maintenance_multicompany.py | 30 +++---- addons/mrp/models/mrp_bom.py | 2 +- addons/mrp/models/mrp_production.py | 10 +-- addons/mrp/models/mrp_routing.py | 2 +- addons/mrp/models/mrp_unbuild.py | 4 +- addons/mrp/report/mrp_report_bom_structure.py | 12 +-- addons/mrp/security/mrp_security.xml | 10 +-- .../mrp_subcontracting/models/res_partner.py | 2 +- addons/pad/models/pad.py | 2 +- .../models/res_partner.py | 4 +- .../src/js/partner_autocomplete_fieldchar.js | 3 - addons/payment/controllers/portal.py | 2 +- addons/payment/models/payment_acquirer.py | 10 +-- addons/payment/models/res_company.py | 2 +- .../views/payment_portal_templates.xml | 2 +- .../payment_acquirer_onboarding_wizard.py | 10 +-- addons/payment_transfer/models/payment.py | 4 +- .../models/phone_validation_mixin.py | 4 +- addons/point_of_sale/models/pos_config.py | 14 +-- addons/point_of_sale/models/pos_order.py | 8 +- .../security/point_of_sale_security.xml | 8 +- .../tests/test_point_of_sale_flow.py | 2 +- addons/point_of_sale/wizard/pos_details.py | 4 +- addons/portal/wizard/portal_wizard.py | 2 +- addons/product/models/decimal_precision.py | 2 +- addons/product/models/product.py | 10 +-- addons/product/models/product_pricelist.py | 8 +- addons/product/models/product_template.py | 10 +-- addons/product/models/res_partner.py | 2 +- addons/product/security/product_security.xml | 8 +- addons/product/tests/test_seller.py | 2 +- addons/product/wizard/product_price_list.py | 4 +- .../product_margin/models/product_product.py | 2 +- addons/project/models/project.py | 6 +- addons/project/security/project_security.xml | 6 +- addons/project_timesheet_holidays/__init__.py | 2 +- .../models/hr_holidays.py | 6 +- .../tests/test_timesheet_holidays.py | 6 +- addons/purchase/models/account_invoice.py | 2 +- addons/purchase/models/product.py | 2 +- addons/purchase/models/purchase.py | 14 +-- addons/purchase/models/res_config_settings.py | 4 +- .../purchase/security/purchase_security.xml | 8 +- .../models/purchase_requisition.py | 6 +- .../purchase_requisition_security.xml | 4 +- .../models/purchase_requisition.py | 2 +- .../tests/test_purchase_requisition_stock.py | 2 +- .../purchase_stock/models/account_invoice.py | 2 +- addons/purchase_stock/models/purchase.py | 2 +- addons/purchase_stock/models/stock_rule.py | 2 +- addons/purchase_stock/tests/common.py | 2 +- .../tests/test_create_picking.py | 2 +- .../tests/test_purchase_lead_time.py | 2 +- .../tests/test_stockvaluation.py | 10 +-- addons/repair/models/repair.py | 2 +- addons/repair/security/repair_security.xml | 2 +- addons/resource/models/resource.py | 6 +- addons/resource/models/resource_mixin.py | 4 +- addons/sale/controllers/onboarding.py | 2 +- addons/sale/models/account_invoice.py | 2 +- addons/sale/models/res_company.py | 8 +- addons/sale/models/sale.py | 18 ++-- addons/sale/security/sale_security.xml | 6 +- addons/sale/tests/test_onchange.py | 4 +- ...est_sale_product_attribute_value_config.py | 2 +- .../payment_acquirer_onboarding_wizard.py | 10 +-- .../sale_coupon/models/sale_coupon_program.py | 2 +- addons/sale_crm/models/crm_lead.py | 2 +- .../models/sale_order_template.py | 4 +- addons/sale_margin/models/sale_order.py | 6 +- addons/sale_purchase/models/sale_order.py | 2 +- addons/sale_stock/models/sale_order.py | 2 +- .../sale_timesheet/models/project_overview.py | 2 +- addons/sale_timesheet/models/sale_order.py | 2 +- addons/sale_timesheet/tests/test_reporting.py | 2 +- addons/sales_team/models/crm_team.py | 5 +- .../security/sales_team_security.xml | 2 +- addons/sms/wizard/send_sms.py | 2 +- addons/snailmail/models/snailmail_letter.py | 12 +-- .../wizard/snailmail_letter_format_error.py | 4 +- .../wizard/account_invoice_send.py | 2 +- addons/stock/data/stock_demo.xml | 2 +- addons/stock/models/product.py | 2 +- addons/stock/models/stock_inventory.py | 4 +- addons/stock/models/stock_location.py | 4 +- addons/stock/models/stock_move.py | 2 +- addons/stock/models/stock_move_line.py | 4 +- addons/stock/models/stock_picking.py | 4 +- addons/stock/models/stock_quant.py | 2 +- addons/stock/models/stock_rule.py | 6 +- addons/stock/models/stock_scrap.py | 4 +- addons/stock/models/stock_warehouse.py | 8 +- addons/stock/security/stock_security.xml | 32 ++++--- addons/stock/tests/test_move.py | 2 +- addons/stock/tests/test_move2.py | 2 +- addons/stock/tests/test_stock_flow.py | 20 ++--- addons/stock/views/stock_move_line_views.xml | 1 + addons/stock/views/stock_move_views.xml | 1 + addons/stock/views/stock_picking_views.xml | 2 +- addons/stock/wizard/product_replenish.py | 2 +- .../stock/wizard/stock_change_product_qty.py | 2 +- .../stock/wizard/stock_scheduler_compute.py | 3 +- addons/stock_account/models/product.py | 8 +- addons/stock_account/models/stock.py | 12 +-- .../security/stock_account_security.xml | 2 +- ...o_saxon_valuation_reconciliation_common.py | 2 +- .../tests/test_stockvaluation.py | 2 +- .../tests/test_stockvaluation.py | 18 ++-- .../models/stock_landed_cost.py | 4 +- .../security/stock_landed_cost_security.xml | 2 +- .../tests/test_stock_landed_costs.py | 2 +- .../tests/test_stock_landed_costs_purchase.py | 4 +- addons/survey/wizard/survey_invite.py | 2 +- addons/test_mail/tests/test_mail_channel.py | 2 +- addons/test_mail/tests/test_mail_message.py | 8 +- addons/test_mail/tests/test_mail_template.py | 2 +- addons/test_mail/tests/test_performance.py | 2 +- addons/web/models/ir_http.py | 11 ++- .../src/js/chrome/abstract_web_client.js | 26 +++++- addons/web/static/src/js/chrome/web_client.js | 3 +- addons/web/static/src/js/core/py_utils.js | 6 +- addons/web/static/src/js/core/session.js | 23 +++++ .../static/src/js/services/crash_manager.js | 6 +- .../static/src/js/views/basic/basic_model.js | 8 ++ .../src/js/widgets/switch_company_menu.js | 85 +++++++++++-------- .../static/src/scss/switch_company_menu.scss | 24 ++++++ addons/web/static/src/xml/base.xml | 38 ++++++++- .../static/tests/views/basic_model_tests.js | 1 + addons/web/views/webclient_templates.xml | 1 + .../controllers/main.py | 4 +- addons/website/controllers/backend.py | 2 +- addons/website/models/ir_http.py | 3 + addons/website/models/ir_ui_view.py | 2 +- addons/website/models/res_config_settings.py | 5 +- .../static/src/js/content/website_root.js | 14 --- addons/website/static/src/js/tours/rte.js | 1 + .../views/res_config_settings_views.xml | 3 +- .../views/website_navbar_templates.xml | 21 ----- addons/website_gengo/controllers/main.py | 2 +- addons/website_sale/controllers/main.py | 2 +- addons/website_sale/models/product.py | 2 +- addons/website_sale/models/res_company.py | 2 +- .../payment_acquirer_onboarding_wizard.py | 2 +- .../wizard/slide_channel_invite.py | 2 +- odoo/addons/base/__manifest__.py | 1 + .../base/data/ir_module_category_data.xml | 4 + odoo/addons/base/data/res_company_data.xml | 1 + odoo/addons/base/data/res_groups_demo.xml | 8 ++ odoo/addons/base/models/ir_actions_report.py | 6 +- odoo/addons/base/models/ir_attachment.py | 2 +- odoo/addons/base/models/ir_default.py | 4 +- odoo/addons/base/models/ir_module.py | 7 ++ odoo/addons/base/models/ir_property.py | 12 ++- odoo/addons/base/models/ir_qweb_fields.py | 2 +- odoo/addons/base/models/ir_rule.py | 28 ++++-- odoo/addons/base/models/ir_sequence.py | 4 +- odoo/addons/base/models/ir_ui_view.py | 4 +- odoo/addons/base/models/res_bank.py | 2 +- odoo/addons/base/models/res_company.py | 78 ++++++++++------- odoo/addons/base/models/res_currency.py | 8 +- odoo/addons/base/models/res_lang.py | 2 +- odoo/addons/base/models/res_partner.py | 4 +- odoo/addons/base/models/res_users.py | 12 +-- odoo/addons/base/security/base_groups.xml | 4 + odoo/addons/base/security/base_security.xml | 32 +++---- odoo/addons/base/tests/test_acl.py | 2 +- odoo/addons/base/tests/test_expression.py | 1 - odoo/addons/base/tests/test_ir_default.py | 2 +- odoo/addons/base/views/ir_rule_views.xml | 2 +- odoo/addons/base/views/res_company_views.xml | 8 +- odoo/addons/base/views/res_users_views.xml | 2 +- .../test_access_rights/tests/test_feedback.py | 18 ++-- .../test_new_api/tests/test_new_fields.py | 4 +- odoo/api.py | 33 +++++++ odoo/fields.py | 6 +- odoo/tools/misc.py | 14 --- 281 files changed, 1023 insertions(+), 799 deletions(-) create mode 100644 addons/web/static/src/scss/switch_company_menu.scss create mode 100644 odoo/addons/base/data/res_groups_demo.xml diff --git a/addons/account/__init__.py b/addons/account/__init__.py index 866c39de02e..1c47b94f829 100644 --- a/addons/account/__init__.py +++ b/addons/account/__init__.py @@ -13,7 +13,7 @@ SYSCOHADA_LIST = ['BJ', 'BF', 'CM', 'CF', 'KM', 'CG', 'CI', 'GA', 'GN', 'GW', 'G def _auto_install_l10n(cr, registry): #check the country of the main company (only) and eventually load some module needed in that country env = api.Environment(cr, SUPERUSER_ID, {}) - country_code = env.user.company_id.country_id.code + country_code = env.company_id.country_id.code if country_code: #auto install localization module(s) if available module_list = [] diff --git a/addons/account/controllers/onboarding.py b/addons/account/controllers/onboarding.py index 879fd0a82fc..1fd3044623b 100644 --- a/addons/account/controllers/onboarding.py +++ b/addons/account/controllers/onboarding.py @@ -10,7 +10,7 @@ class OnboardingController(http.Controller): It can be empty if the user has closed it or if he doesn't have the permission to see it. """ - company = request.env.user.company_id + company = request.env.company_id if not request.env.user._is_admin() or \ company.account_invoice_onboarding_state == 'closed': return {} @@ -27,7 +27,7 @@ class OnboardingController(http.Controller): """ Returns the `banner` for the account dashboard onboarding panel. It can be empty if the user has closed it or if he doesn't have the permission to see it. """ - company = request.env.user.company_id + company = request.env.company_id if not request.env.user._is_admin() or \ company.account_dashboard_onboarding_state == 'closed': diff --git a/addons/account/models/account.py b/addons/account/models/account.py index db5a88044a6..3453e39a2cf 100644 --- a/addons/account/models/account.py +++ b/addons/account/models/account.py @@ -91,7 +91,7 @@ class AccountAccount(models.Model): 'account_id', 'tax_id', string='Default Taxes') note = fields.Text('Internal Notes') company_id = fields.Many2one('res.company', string='Company', required=True, - default=lambda self: self.env['res.company']._company_default_get('account.account')) + default=lambda self: self.env.company_id) tag_ids = fields.Many2many('account.account.tag', 'account_account_account_tag', string='Tags', help="Optional tags you may want to assign for custom reporting") group_id = fields.Many2one('account.group') @@ -390,7 +390,7 @@ class AccountJournalGroup(models.Model): _description = "Account Journal Group" name = fields.Char(required=True, translate=True) - company_id = fields.Many2one('res.company', required=True, default=lambda self: self.env['res.company']._company_default_get('account.account')) + company_id = fields.Many2one('res.company', required=True, default=lambda self: self.env.company_id) account_journal_ids = fields.Many2many('account.journal', string="Journals") sequence = fields.Integer(default=10) @@ -457,7 +457,7 @@ class AccountJournal(models.Model): #groups_id = fields.Many2many('res.groups', 'account_journal_group_rel', 'journal_id', 'group_id', string='Groups') currency_id = fields.Many2one('res.currency', help='The currency used to enter statement', string="Currency", oldname='currency') - company_id = fields.Many2one('res.company', string='Company', required=True, index=True, default=lambda self: self.env.user.company_id, + company_id = fields.Many2one('res.company', string='Company', required=True, index=True, default=lambda self: self.env.company_id, help="Company related to this journal") refund_sequence = fields.Boolean(string='Dedicated Credit Note Sequence', help="Check this box if you don't want to share the same sequence for invoices and credit notes made from this journal", default=False) @@ -760,7 +760,7 @@ class AccountJournal(models.Model): @api.model def create(self, vals): - company_id = vals.get('company_id', self.env.user.company_id.id) + company_id = vals.get('company_id', self.env.company_id.id) if vals.get('type') in ('bank', 'cash'): # For convenience, the name can be inferred from account number if not vals.get('name') and 'bank_acc_number' in vals: @@ -832,16 +832,16 @@ class AccountJournal(models.Model): @api.depends('company_id') def _belong_to_company(self): for journal in self: - journal.belong_to_company = (journal.company_id.id == self.env.user.company_id.id) + journal.belong_to_company = (journal.company_id.id == self.env.company_id.id) @api.multi def _search_company_journals(self, operator, value): if value: - recs = self.search([('company_id', operator, self.env.user.company_id.id)]) + recs = self.search([('company_id', operator, self.env.company_id.id)]) elif operator == '=': - recs = self.search([('company_id', '!=', self.env.user.company_id.id)]) + recs = self.search([('company_id', '!=', self.env.company_id.id)]) else: - recs = self.search([('company_id', operator, self.env.user.company_id.id)]) + recs = self.search([('company_id', operator, self.env.company_id.id)]) return [('id', 'in', [x.id for x in recs])] @api.multi @@ -899,7 +899,7 @@ class AccountTax(models.Model): amount_type = fields.Selection(default='percent', string="Tax Computation", required=True, oldname='type', selection=[('group', 'Group of Taxes'), ('fixed', 'Fixed'), ('percent', 'Percentage of Price'), ('division', 'Percentage of Price Tax Included')]) active = fields.Boolean(default=True, help="Set active to false to hide the tax without removing it.") - company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.user.company_id) + company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company_id) children_tax_ids = fields.Many2many('account.tax', 'account_tax_filiation_rel', 'parent_tax', 'child_tax', string='Children Taxes') sequence = fields.Integer(required=True, default=1, help="The sequence field is used to define order in which the tax lines are applied.") @@ -1080,7 +1080,7 @@ class AccountTax(models.Model): }] } """ if len(self) == 0: - company_id = self.env.user.company_id + company_id = self.env.company_id else: company_id = self[0].company_id if not currency: diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py index 487477dee6a..631a053b905 100644 --- a/addons/account/models/account_bank_statement.py +++ b/addons/account/models/account_bank_statement.py @@ -101,7 +101,7 @@ class AccountBankStatement(models.Model): @api.model def _default_journal(self): journal_type = self.env.context.get('journal_type', False) - company_id = self.env['res.company']._company_default_get('account.bank.statement').id + company_id = self.env.company_id.id if journal_type: journals = self.env['account.journal'].search([('type', '=', journal_type), ('company_id', '=', company_id)]) if journals: @@ -145,7 +145,7 @@ class AccountBankStatement(models.Model): journal_id = fields.Many2one('account.journal', string='Journal', required=True, states={'confirm': [('readonly', True)]}, default=_default_journal) journal_type = fields.Selection(related='journal_id.type', help="Technical field used for usability purposes", readonly=False) company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', store=True, readonly=True, - default=lambda self: self.env['res.company']._company_default_get('account.bank.statement')) + default=lambda self: self.env.company_id) total_entry_encoding = fields.Monetary('Transactions Subtotal', compute='_end_balance', store=True, help="Total of transaction lines.") balance_end = fields.Monetary('Computed Balance', compute='_end_balance', store=True, help='Balance as calculated based on Opening Balance and transaction lines') diff --git a/addons/account/models/account_fiscal_year.py b/addons/account/models/account_fiscal_year.py index 8e664c2ea72..e5af53a2eb0 100644 --- a/addons/account/models/account_fiscal_year.py +++ b/addons/account/models/account_fiscal_year.py @@ -17,7 +17,7 @@ class AccountFiscalYear(models.Model): date_to = fields.Date(string='End Date', required=True, help='Ending Date, included in the fiscal year.') company_id = fields.Many2one('res.company', string='Company', required=True, - default=lambda self: self.env.user.company_id) + default=lambda self: self.env.company_id) @api.constrains('date_from', 'date_to', 'company_id') def _check_dates(self): diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py index e639196597f..8b1e00c86ca 100644 --- a/addons/account/models/account_invoice.py +++ b/addons/account/models/account_invoice.py @@ -49,7 +49,7 @@ class AccountInvoice(models.Model): def _get_default_incoterm(self): - return self.env.user.company_id.incoterm_id + return self.env.company_id.incoterm_id @api.one @api.depends('invoice_line_ids.price_subtotal', 'tax_line_ids.amount', 'tax_line_ids.amount_rounding', @@ -82,7 +82,7 @@ class AccountInvoice(models.Model): return self.env['account.journal'].browse(self._context.get('default_journal_id')) inv_type = self._context.get('type', 'out_invoice') inv_types = inv_type if isinstance(inv_type, list) else [inv_type] - company_id = self._context.get('company_id', self.env.user.company_id.id) + company_id = self._context.get('company_id', self.env.company_id.id) domain = [ ('type', 'in', [TYPE2JOURNAL[ty] for ty in inv_types if ty in TYPE2JOURNAL]), ('company_id', '=', company_id), @@ -96,12 +96,12 @@ class AccountInvoice(models.Model): @api.model def _default_currency(self): journal = self._default_journal() - return journal.currency_id or journal.company_id.currency_id or self.env.user.company_id.currency_id + return journal.currency_id or journal.company_id.currency_id or self.env.company_id.currency_id def _default_comment(self): invoice_type = self.env.context.get('type', 'out_invoice') if invoice_type == 'out_invoice' and self.env['ir.config_parameter'].sudo().get_param('account.use_invoice_terms'): - return self.env.user.company_id.invoice_terms + return self.env.company_id.invoice_terms def _get_aml_for_amount_residual(self): """ Get the aml to consider to compute the amount residual of invoices """ @@ -367,7 +367,7 @@ class AccountInvoice(models.Model): domain="[('type', 'in', {'out_invoice': ['sale'], 'out_refund': ['sale'], 'in_refund': ['purchase'], 'in_invoice': ['purchase']}.get(type, [])), ('company_id', '=', company_id)]") company_id = fields.Many2one('res.company', string='Company', change_default=True, required=True, readonly=True, states={'draft': [('readonly', False)]}, - default=lambda self: self.env['res.company']._company_default_get('account.invoice')) + default=lambda self: self.env.company_id) reconciled = fields.Boolean(string='Paid/Reconciled', store=True, readonly=True, compute='_compute_residual', help="It indicates that the invoice has been paid and the journal entry of the invoice has been reconciled with one or several journal entries of payment.") @@ -734,7 +734,7 @@ class AccountInvoice(models.Model): def message_post(self, **kwargs): if self.env.context.get('mark_invoice_as_sent'): self.filtered(lambda inv: not inv.sent).write({'sent': True}) - self.env.user.company_id.set_onboarding_step_done('account_onboarding_sample_invoice_state') + self.env.company_id.set_onboarding_step_done('account_onboarding_sample_invoice_state') return super(AccountInvoice, self.with_context(mail_post_autofollow=True)).message_post(**kwargs) @api.model @@ -1746,7 +1746,7 @@ class AccountInvoiceLine(models.Model): if self.invoice_id.currency_id and self.invoice_id.currency_id != self.invoice_id.company_id.currency_id: currency = self.invoice_id.currency_id date = self.invoice_id._get_currency_rate_date() - price_subtotal_signed = currency._convert(price_subtotal_signed, self.invoice_id.company_id.currency_id, self.company_id or self.env.user.company_id, date or fields.Date.today()) + price_subtotal_signed = currency._convert(price_subtotal_signed, self.invoice_id.company_id.currency_id, self.company_id or self.env.company_id, date or fields.Date.today()) sign = self.invoice_id.type in ['in_refund', 'out_refund'] and -1 or 1 self.price_subtotal_signed = price_subtotal_signed * sign @@ -1848,7 +1848,7 @@ class AccountInvoiceLine(models.Model): taxes = self.product_id.supplier_taxes_id or self.account_id.tax_ids or self.invoice_id.company_id.account_purchase_tax_id # Keep only taxes of the company - company_id = self.company_id or self.env.user.company_id + company_id = self.company_id or self.env.company_id taxes = taxes.filtered(lambda r: r.company_id == company_id) self.invoice_line_tax_ids = fp_taxes = self.invoice_id.fiscal_position_id.map_tax(taxes, self.product_id, self.invoice_id.partner_id) diff --git a/addons/account/models/account_journal_dashboard.py b/addons/account/models/account_journal_dashboard.py index 11306b4a5a6..afb4e24c059 100644 --- a/addons/account/models/account_journal_dashboard.py +++ b/addons/account/models/account_journal_dashboard.py @@ -281,7 +281,7 @@ class account_journal(models.Model): curr_cache = {} if curr_cache is None else curr_cache for result in results_dict: cur = self.env['res.currency'].browse(result.get('currency')) - company = self.env['res.company'].browse(result.get('company_id')) or self.env.user.company_id + company = self.env['res.company'].browse(result.get('company_id')) or self.env.company_id rslt_count += 1 date = result.get('date_invoice') or fields.Date.today() diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index eaa18ec5e4d..a5d60435ff1 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -26,7 +26,7 @@ class AccountMove(models.Model): def default_get(self, fields): rec = super(AccountMove, self).default_get(fields) if not rec.get('journal_id'): - rec.update({'journal_id': self.env['account.journal'].search([('type', '=', 'general'), ('company_id', '=', self.env.user.company_id.id)], limit=1).id}) + rec.update({'journal_id': self.env['account.journal'].search([('type', '=', 'general'), ('company_id', '=', self.env.company_id.id)], limit=1).id}) return rec @api.multi @@ -90,12 +90,12 @@ class AccountMove(models.Model): @api.one @api.depends('company_id') def _compute_currency(self): - self.currency_id = self.company_id.currency_id or self.env.user.company_id.currency_id + self.currency_id = self.company_id.currency_id or self.env.company_id.currency_id @api.multi def _get_default_journal(self): if self.env.context.get('default_journal_type'): - return self.env['account.journal'].search([('company_id', '=', self.env.user.company_id.id), ('type', '=', self.env.context['default_journal_type'])], limit=1).id + return self.env['account.journal'].search([('company_id', '=', self.env.company_id.id), ('type', '=', self.env.context['default_journal_type'])], limit=1).id @api.multi @api.depends('line_ids.partner_id') @@ -402,7 +402,7 @@ class AccountMove(models.Model): def assert_balanced(self): if not self.ids: return True - prec = self.env.user.company_id.currency_id.decimal_places + prec = self.env.company_id.currency_id.decimal_places self._cr.execute("""\ SELECT move_id @@ -484,7 +484,7 @@ class AccountMove(models.Model): ('reverse_entry_id', '=', False)]) for move in records: date = None - if move.reverse_date and (not self.env.user.company_id.period_lock_date or move.reverse_date > self.env.user.company_id.period_lock_date): + if move.reverse_date and (not self.env.company_id.period_lock_date or move.reverse_date > self.env.company_id.period_lock_date): date = move.reverse_date move.reverse_moves(date=date, auto=True) @@ -1348,7 +1348,7 @@ class AccountMoveLine(models.Model): currency_id = False date = self.env.context.get('date') or fields.Date.today() company = self.env.context.get('company_id') - company = self.env['res.company'].browse(company) if company else self.env.user.company_id + company = self.env['res.company'].browse(company) if company else self.env.company_id if src_currency and src_currency != company_currency: amount_currency = amount amount = src_currency._convert(amount, company_currency, company, date) @@ -1404,7 +1404,7 @@ class AccountMoveLine(models.Model): 'move_id': move_line.id, 'user_id': move_line.invoice_id.user_id.id or self._uid, 'partner_id': move_line.partner_id.id, - 'company_id': move_line.analytic_account_id.company_id.id or self.env.user.company_id.id, + 'company_id': move_line.analytic_account_id.company_id.id or self.env.company_id.id, }) return result @@ -1429,7 +1429,7 @@ class AccountMoveLine(models.Model): 'ref': self.ref, 'move_id': self.id, 'user_id': self.invoice_id.user_id.id or self._uid, - 'company_id': distribution.account_id.company_id.id or self.env.user.company_id.id, + 'company_id': distribution.account_id.company_id.id or self.env.company_id.id, } @api.model diff --git a/addons/account/models/account_payment.py b/addons/account/models/account_payment.py index baca985def8..bc20a820c9b 100644 --- a/addons/account/models/account_payment.py +++ b/addons/account/models/account_payment.py @@ -72,7 +72,7 @@ class account_payment(models.Model): partner_id = fields.Many2one('res.partner', string='Partner', tracking=True, readonly=True, states={'draft': [('readonly', False)]}) amount = fields.Monetary(string='Payment Amount', required=True, readonly=True, states={'draft': [('readonly', False)]}, tracking=True) - currency_id = fields.Many2one('res.currency', string='Currency', required=True, readonly=True, states={'draft': [('readonly', False)]}, default=lambda self: self.env.user.company_id.currency_id) + currency_id = fields.Many2one('res.currency', string='Currency', required=True, readonly=True, states={'draft': [('readonly', False)]}, default=lambda self: self.env.company_id.currency_id) payment_date = fields.Date(string='Payment Date', default=fields.Date.context_today, required=True, readonly=True, states={'draft': [('readonly', False)]}, copy=False, tracking=True) communication = fields.Char(string='Memo', readonly=True, states={'draft': [('readonly', False)]}) journal_id = fields.Many2one('account.journal', string='Payment Journal', required=True, readonly=True, states={'draft': [('readonly', False)]}, tracking=True, domain=[('type', 'in', ('bank', 'cash'))]) @@ -304,7 +304,7 @@ class account_payment(models.Model): if payment_currency == currency: total += amount_total else: - total += payment_currency._convert(amount_total, currency, self.env.user.company_id, self.payment_date or fields.Date.today()) + total += payment_currency._convert(amount_total, currency, self.env.company_id, self.payment_date or fields.Date.today()) return total @api.multi @@ -693,7 +693,7 @@ class payment_register(models.TransientModel): if 'invoice_ids' not in rec: rec['invoice_ids'] = [(6, 0, invoices.ids)] if 'journal_id' not in rec: - rec['journal_id'] = self.env['account.journal'].search([('company_id', '=', self.env.user.company_id.id), ('type', 'in', ('bank', 'cash'))], limit=1).id + rec['journal_id'] = self.env['account.journal'].search([('company_id', '=', self.env.company_id.id), ('type', 'in', ('bank', 'cash'))], limit=1).id if 'payment_method_id' not in rec: if invoices[0].type in ('out_invoice', 'in_refund'): domain = [('payment_type', '=', 'inbound')] diff --git a/addons/account/models/account_payment_term.py b/addons/account/models/account_payment_term.py index 05e06310c16..4756b1ec22c 100644 --- a/addons/account/models/account_payment_term.py +++ b/addons/account/models/account_payment_term.py @@ -42,7 +42,7 @@ class AccountPaymentTerm(models.Model): if self.env.context.get('currency_id'): currency = self.env['res.currency'].browse(self.env.context['currency_id']) else: - currency = self.env.user.company_id.currency_id + currency = self.env.company_id.currency_id for line in self.line_ids: if line.value == 'fixed': amt = sign * currency.round(line.value_amount) diff --git a/addons/account/models/account_reconcile_model.py b/addons/account/models/account_reconcile_model.py index 5ab6865831a..53280b2732f 100644 --- a/addons/account/models/account_reconcile_model.py +++ b/addons/account/models/account_reconcile_model.py @@ -13,7 +13,7 @@ class AccountReconcileModel(models.Model): # Base fields. name = fields.Char(string='Name', required=True) sequence = fields.Integer(required=True, default=10) - company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.user.company_id) + company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company_id) rule_type = fields.Selection(selection=[ ('writeoff_button', _('Manually create a write-off on clicked button.')), diff --git a/addons/account/models/chart_template.py b/addons/account/models/chart_template.py index dc339adc005..55dec0dfae2 100644 --- a/addons/account/models/chart_template.py +++ b/addons/account/models/chart_template.py @@ -165,13 +165,10 @@ class AccountChartTemplate(models.Model): """ self.ensure_one() # do not use `request.env` here, it can cause deadlocks - if request and request.session.uid: - current_user = self.env['res.users'].browse(request.uid) - company = current_user.company_id + if request and 'allowed_company_ids' in dir(request): + company = self.env['res.company'].browse(request.allowed_company_ids[0]) else: - # fallback to company of current user, most likely __system__ - # (won't work well for multi-company) - company = self.env.user.company_id + company = self.env.company_id # If we don't have any chart of account on this company, install this chart of account if not company.chart_template_id and not self.existing_accounting(company): self.load_for_current_company(15.0, 15.0) @@ -186,13 +183,10 @@ class AccountChartTemplate(models.Model): """ self.ensure_one() # do not use `request.env` here, it can cause deadlocks - if request and request.session.uid: - current_user = self.env['res.users'].browse(request.uid) - company = current_user.company_id + if request and 'allowed_company_ids' in dir(request): + company = self.env['res.company'].browse(request.allowed_company_ids[0]) else: - # fallback to company of current user, most likely __system__ - # (won't work well for multi-company) - company = self.env.user.company_id + company = self.env.company_id # Ensure everything is translated to the company's language, not the user's one. self = self.with_context(lang=company.partner_id.lang) if not self.env.user._is_admin(): diff --git a/addons/account/models/company.py b/addons/account/models/company.py index abff7bbd861..093730ebf31 100644 --- a/addons/account/models/company.py +++ b/addons/account/models/company.py @@ -313,7 +313,7 @@ Best Regards,''')) @api.model def setting_init_fiscal_year_action(self): """ Called by the 'Fiscal Year Opening' button of the setup bar.""" - company = self.env.user.company_id + company = self.env.company_id company.create_op_move_if_non_existant() new_wizard = self.env['account.financial.year.op'].create({'company_id': company.id}) view_id = self.env.ref('account.setup_financial_year_opening_form').id @@ -331,7 +331,7 @@ Best Regards,''')) @api.model def setting_chart_of_accounts_action(self): """ Called by the 'Chart of Accounts' button of the setup bar.""" - company = self.env.user.company_id + company = self.env.company_id company.set_onboarding_step_done('account_setup_coa_state') # If an opening move has already been posted, we open the tree view showing all the accounts @@ -455,25 +455,25 @@ Best Regards,''')) @api.model def action_close_account_invoice_onboarding(self): """ Mark the invoice onboarding panel as closed. """ - self.env.user.company_id.account_invoice_onboarding_state = 'closed' + self.env.company_id.account_invoice_onboarding_state = 'closed' @api.model def action_close_account_dashboard_onboarding(self): """ Mark the dashboard onboarding panel as closed. """ - self.env.user.company_id.account_dashboard_onboarding_state = 'closed' + self.env.company_id.account_dashboard_onboarding_state = 'closed' @api.model def action_open_account_onboarding_invoice_layout(self): """ Onboarding step for the invoice layout. """ action = self.env.ref('account.action_open_account_onboarding_invoice_layout').read()[0] - action['res_id'] = self.env.user.company_id.id + action['res_id'] = self.env.company_id.id return action @api.model def action_open_account_onboarding_sale_tax(self): """ Onboarding step for the invoice layout. """ action = self.env.ref('account.action_open_account_onboarding_sale_tax').read()[0] - action['res_id'] = self.env.user.company_id.id + action['res_id'] = self.env.company_id.id return action @api.model @@ -482,7 +482,7 @@ Best Regards,''')) # use current user as partner partner = self.env.user.partner_id - company_id = self.env.user.company_id.id + company_id = self.env.company_id.id # try to find an existing sample invoice sample_invoice = self.env['account.invoice'].search( [('company_id', '=', company_id), @@ -490,7 +490,7 @@ Best Regards,''')) if len(sample_invoice) == 0: # If there are no existing accounts or no journal, fail - account = self.env.user.company_id.get_chart_of_accounts_or_fail() + account = self.env.company_id.get_chart_of_accounts_or_fail() journal = self.env['account.journal'].search([('company_id', '=', company_id)], limit=1) if len(journal) == 0: diff --git a/addons/account/models/partner.py b/addons/account/models/partner.py index 85ec5f9bb66..b5df07cf8f5 100644 --- a/addons/account/models/partner.py +++ b/addons/account/models/partner.py @@ -204,7 +204,7 @@ class ResPartner(models.Model): @api.multi def _credit_debit_get(self): - tables, where_clause, where_params = self.env['account.move.line'].with_context(company_id=self.env.user.company_id.id)._query_get() + tables, where_clause, where_params = self.env['account.move.line'].with_context(company_id=self.env.company_id.id)._query_get() where_params = [tuple(self.ids)] + where_params if where_clause: where_clause = 'AND ' + where_clause @@ -263,7 +263,7 @@ class ResPartner(models.Model): self.total_invoiced = 0.0 return True - user_currency_id = self.env.user.company_id.currency_id.id + user_currency_id = self.env.company_id.currency_id.id all_partners_and_children = {} all_partner_ids = [] for partner in self: @@ -309,7 +309,7 @@ class ResPartner(models.Model): partner.contracts_count = AccountAnalyticAccount.search_count([('partner_id', '=', partner.id)]) def get_followup_lines_domain(self, date, overdue_only=False, only_unblocked=False): - domain = [('reconciled', '=', False), ('account_id.deprecated', '=', False), ('account_id.internal_type', '=', 'receivable'), '|', ('debit', '!=', 0), ('credit', '!=', 0), ('company_id', '=', self.env.user.company_id.id)] + domain = [('reconciled', '=', False), ('account_id.deprecated', '=', False), ('account_id.internal_type', '=', 'receivable'), '|', ('debit', '!=', 0), ('credit', '!=', 0), ('company_id', '=', self.env.company_id.id)] if only_unblocked: domain += [('blocked', '=', False)] if self.ids: @@ -362,14 +362,14 @@ class ResPartner(models.Model): @api.multi def mark_as_reconciled(self): self.env['account.partial.reconcile'].check_access_rights('write') - return self.sudo().with_context(company_id=self.env.user.company_id.id).write({'last_time_entries_checked': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}) + return self.sudo().with_context(company_id=self.env.company_id.id).write({'last_time_entries_checked': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}) @api.one def _get_company_currency(self): if self.company_id: self.currency_id = self.sudo().company_id.currency_id else: - self.currency_id = self.env.user.company_id.currency_id + self.currency_id = self.env.company_id.currency_id credit = fields.Monetary(compute='_credit_debit_get', search=_credit_search, string='Total Receivable', help="Total amount this customer owes you.") @@ -448,7 +448,7 @@ class ResPartner(models.Model): if self.company_id: company = self.company_id else: - company = self.env.user.company_id + company = self.env.company_id return {'domain': {'property_account_position_id': [('company_id', 'in', [company.id, False])]}} def can_edit_vat(self): diff --git a/addons/account/models/product.py b/addons/account/models/product.py index 43ea3d90b7a..ec818721697 100644 --- a/addons/account/models/product.py +++ b/addons/account/models/product.py @@ -23,9 +23,9 @@ class ProductTemplate(models.Model): _inherit = "product.template" taxes_id = fields.Many2many('account.tax', 'product_taxes_rel', 'prod_id', 'tax_id', help="Default taxes used when selling the product.", string='Customer Taxes', - domain=[('type_tax_use', '=', 'sale')], default=lambda self: self.env.user.company_id.account_sale_tax_id) + domain=[('type_tax_use', '=', 'sale')], default=lambda self: self.env.company_id.account_sale_tax_id) supplier_taxes_id = fields.Many2many('account.tax', 'product_supplier_taxes_rel', 'prod_id', 'tax_id', string='Vendor Taxes', help='Default taxes used when buying the product.', - domain=[('type_tax_use', '=', 'purchase')], default=lambda self: self.env.user.company_id.account_purchase_tax_id) + domain=[('type_tax_use', '=', 'purchase')], default=lambda self: self.env.company_id.account_purchase_tax_id) property_account_income_id = fields.Many2one('account.account', company_dependent=True, string="Income Account", oldname="property_account_income", domain=[('deprecated', '=', False)], diff --git a/addons/account/models/reconciliation_widget.py b/addons/account/models/reconciliation_widget.py index 4683afab86f..0e267d706ed 100644 --- a/addons/account/models/reconciliation_widget.py +++ b/addons/account/models/reconciliation_widget.py @@ -361,7 +361,7 @@ class AccountReconciliation(models.AbstractModel): is_partner and ' ' or "AND at.type <> 'payable' AND at.type <> 'receivable'", account_type and "AND at.type = %(account_type)s" or '', res_ids and 'AND ' + res_alias + '.id in %(res_ids)s' or '', - self.env.user.company_id.id, + self.env.company_id.id, is_partner and 'AND l.partner_id = p.id' or ' ', aml_ids and 'AND l.id IN %(aml_ids)s' or '', is_partner and 'l.partner_id, p.id,' or ' ', diff --git a/addons/account/models/res_config_settings.py b/addons/account/models/res_config_settings.py index 0e0ac37ae44..c54dc0b2f3a 100644 --- a/addons/account/models/res_config_settings.py +++ b/addons/account/models/res_config_settings.py @@ -142,7 +142,7 @@ class ResConfigSettings(models.TransientModel): def _onchange_tax_exigibility(self): res = {} tax = self.env['account.tax'].search([ - ('company_id', '=', self.env.user.company_id.id), ('tax_exigibility', '=', 'on_payment') + ('company_id', '=', self.env.company_id.id), ('tax_exigibility', '=', 'on_payment') ], limit=1) if not self.tax_exigibility and tax: self.tax_exigibility = True diff --git a/addons/account/report/account_aged_partner_balance.py b/addons/account/report/account_aged_partner_balance.py index 08d0b976263..36070e760b7 100644 --- a/addons/account/report/account_aged_partner_balance.py +++ b/addons/account/report/account_aged_partner_balance.py @@ -46,7 +46,7 @@ class ReportAgedPartnerBalance(models.AbstractModel): total = [] partner_clause = '' cr = self.env.cr - user_company = self.env.user.company_id + user_company = self.env.company_id user_currency = user_company.currency_id company_ids = self._context.get('company_ids') or [user_company.id] move_state = ['draft', 'posted'] @@ -140,7 +140,7 @@ class ReportAgedPartnerBalance(models.AbstractModel): if partial_line.max_date <= date_from: line_amount -= partial_line.company_id.currency_id._convert(partial_line.amount, user_currency, user_company, date_from) - if not self.env.user.company_id.currency_id.is_zero(line_amount): + if not self.env.company_id.currency_id.is_zero(line_amount): partners_amount[partner_id] += line_amount lines.setdefault(partner_id, []) lines[partner_id].append({ @@ -178,7 +178,7 @@ class ReportAgedPartnerBalance(models.AbstractModel): for partial_line in line.matched_credit_ids: if partial_line.max_date <= date_from: line_amount -= partial_line.company_id.currency_id._convert(partial_line.amount, user_currency, user_company, date_from) - if not self.env.user.company_id.currency_id.is_zero(line_amount): + if not self.env.company_id.currency_id.is_zero(line_amount): undue_amounts[partner_id] += line_amount lines.setdefault(partner_id, []) lines[partner_id].append({ @@ -198,7 +198,7 @@ class ReportAgedPartnerBalance(models.AbstractModel): total[6] = total[6] + undue_amt values['direction'] = undue_amt - if not float_is_zero(values['direction'], precision_rounding=self.env.user.company_id.currency_id.rounding): + if not float_is_zero(values['direction'], precision_rounding=self.env.company_id.currency_id.rounding): at_least_one_amount = True for i in range(5): @@ -208,7 +208,7 @@ class ReportAgedPartnerBalance(models.AbstractModel): # Adding counter total[(i)] = total[(i)] + (during and during[0] or 0) values[str(i)] = during and during[0] or 0.0 - if not float_is_zero(values[str(i)], precision_rounding=self.env.user.company_id.currency_id.rounding): + if not float_is_zero(values[str(i)], precision_rounding=self.env.company_id.currency_id.rounding): at_least_one_amount = True values['total'] = sum([values['direction']] + [values[str(i)] for i in range(5)]) ## Add for total diff --git a/addons/account/report/account_invoice_report.py b/addons/account/report/account_invoice_report.py index 7861644525a..e431a183259 100644 --- a/addons/account/report/account_invoice_report.py +++ b/addons/account/report/account_invoice_report.py @@ -15,10 +15,10 @@ class AccountInvoiceReport(models.Model): def _compute_amounts_in_user_currency(self): """Compute the amounts in the currency of the user """ - user_currency_id = self.env.user.company_id.currency_id + user_currency_id = self.env.company_id.currency_id currency_rate_id = self.env['res.currency.rate'].search([ ('rate', '=', 1), - '|', ('company_id', '=', self.env.user.company_id.id), ('company_id', '=', False)], limit=1) + '|', ('company_id', '=', self.env.company_id.id), ('company_id', '=', False)], limit=1) base_currency_id = currency_rate_id.currency_id for record in self: date = record.date or fields.Date.today() diff --git a/addons/account/security/account_security.xml b/addons/account/security/account_security.xml index bad495b9290..16be4f2d247 100644 --- a/addons/account/security/account_security.xml +++ b/addons/account/security/account_security.xml @@ -86,104 +86,104 @@ Account Entry - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Entry lines - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Journal multi-company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Journal multi-company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Account multi-company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Tax multi-company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Invoice multi-company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Invoice Analysis multi-company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Account fiscal Mapping company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Invoice Line company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Account bank statement company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Account bank statement line company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Account reconcile model template company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Account payment company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Account payment term company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] diff --git a/addons/account/tests/account_test_classes.py b/addons/account/tests/account_test_classes.py index f8f33356da4..57441be8652 100644 --- a/addons/account/tests/account_test_classes.py +++ b/addons/account/tests/account_test_classes.py @@ -27,7 +27,7 @@ class AccountingTestCase(HttpCase): :param property_name: The name of the property. ''' - company_id = self.env.user.company_id + company_id = self.env.company_id field_id = self.env['ir.model.fields'].search( [('model', '=', 'product.template'), ('name', '=', property_name)], limit=1) property_id = self.env['ir.property'].search([ diff --git a/addons/account/tests/test_account_all_l10n.py b/addons/account/tests/test_account_all_l10n.py index b8a6e5811b7..23fb0616a64 100644 --- a/addons/account/tests/test_account_all_l10n.py +++ b/addons/account/tests/test_account_all_l10n.py @@ -40,5 +40,5 @@ class TestAllL10n(SingleTransactionCase): comp = self.env['res.company'].create({ 'name': cname, }) - self.env.user.company_id = comp + self.env.company_id = comp coa.try_loading_for_current_company() diff --git a/addons/account/tests/test_account_customer_invoice.py b/addons/account/tests/test_account_customer_invoice.py index 03ca61aecf5..b3fe591092b 100644 --- a/addons/account/tests/test_account_customer_invoice.py +++ b/addons/account/tests/test_account_customer_invoice.py @@ -108,7 +108,7 @@ class TestAccountCustomerInvoice(AccountTestUsers): def test_customer_invoice_tax(self): - self.env.user.company_id.tax_calculation_rounding_method = 'round_globally' + self.env.company_id.tax_calculation_rounding_method = 'round_globally' payment_term = self.env.ref('account.account_payment_term_advance') journalrec = self.env['account.journal'].search([('type', '=', 'sale')])[0] @@ -169,7 +169,7 @@ class TestAccountCustomerInvoice(AccountTestUsers): self.assertEquals(invoice.amount_untaxed, sum([x.base for x in invoice.tax_line_ids])) def test_customer_invoice_tax_refund(self): - company = self.env.user.company_id + company = self.env.company_id tax_account = self.env['account.account'].create({ 'name': 'TAX', 'code': 'TAX', diff --git a/addons/account/tests/test_bank_statement_reconciliation.py b/addons/account/tests/test_bank_statement_reconciliation.py index 0311f278a4b..dd3554839fb 100644 --- a/addons/account/tests/test_bank_statement_reconciliation.py +++ b/addons/account/tests/test_bank_statement_reconciliation.py @@ -70,7 +70,7 @@ class TestBankStatementReconciliation(AccountingTestCase): vals = {'partner_id': self.partner.id, 'type': 'out_invoice', 'name': '-', - 'currency_id': self.env.user.company_id.currency_id.id, + 'currency_id': self.env.company_id.currency_id.id, } # new creates a temporary record to apply the on_change afterwards invoice = self.i_model.new(vals) diff --git a/addons/account/tests/test_reconciliation.py b/addons/account/tests/test_reconciliation.py index 0fc4c2bc7dd..c3064a03b32 100644 --- a/addons/account/tests/test_reconciliation.py +++ b/addons/account/tests/test_reconciliation.py @@ -912,7 +912,7 @@ class TestReconciliationExec(TestReconciliation): account_type = ['receivable'] report_date_to = time.strftime('%Y') + '-07-17' partner = self.env['res.partner'].create({'name': 'AgedPartner'}) - currency = self.env.user.company_id.currency_id + currency = self.env.company_id.currency_id invoice = self.create_invoice_partner(currency_id=currency.id, partner_id=partner.id) journal = self.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'THE'}) @@ -1021,7 +1021,7 @@ class TestReconciliationExec(TestReconciliation): AgedReport = self.env['report.account.report_agedpartnerbalance'].with_context(include_nullified_amount=True) account_type = ['receivable'] partner = self.env['res.partner'].create({'name': 'AgedPartner'}) - currency = self.env.user.company_id.currency_id + currency = self.env.company_id.currency_id invoice = self.create_invoice_partner(currency_id=currency.id, partner_id=partner.id) journal = self.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'THE'}) @@ -1523,7 +1523,7 @@ class TestReconciliationExec(TestReconciliation): def test_reconciliation_to_check(self): partner = self.env['res.partner'].create({'name': 'UncertainPartner'}) - currency = self.env.user.company_id.currency_id + currency = self.env.company_id.currency_id invoice = self.create_invoice_partner(currency_id=currency.id, partner_id=partner.id) journal = self.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'THE', 'update_posted':True}) diff --git a/addons/account/wizard/account_invoice_send.py b/addons/account/wizard/account_invoice_send.py index 54fbd7ff4be..5525b908af3 100644 --- a/addons/account/wizard/account_invoice_send.py +++ b/addons/account/wizard/account_invoice_send.py @@ -10,8 +10,8 @@ class AccountInvoiceSend(models.TransientModel): _inherits = {'mail.compose.message':'composer_id'} _description = 'Account Invoice Send' - is_email = fields.Boolean('Email', default=lambda self: self.env.user.company_id.invoice_is_email) - is_print = fields.Boolean('Print', default=lambda self: self.env.user.company_id.invoice_is_print) + is_email = fields.Boolean('Email', default=lambda self: self.env.company_id.invoice_is_email) + is_print = fields.Boolean('Print', default=lambda self: self.env.company_id.invoice_is_print) printed = fields.Boolean('Is Printed', default=False) invoice_ids = fields.Many2many('account.invoice', 'account_invoice_account_invoice_send_rel', string='Invoices') composer_id = fields.Many2one('mail.compose.message', string='Composer', required=True, ondelete='cascade') diff --git a/addons/account/wizard/account_report_common.py b/addons/account/wizard/account_report_common.py index f5e5814c814..8e3ecee1700 100644 --- a/addons/account/wizard/account_report_common.py +++ b/addons/account/wizard/account_report_common.py @@ -7,7 +7,7 @@ class AccountCommonReport(models.TransientModel): _name = "account.common.report" _description = "Account Common Report" - company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.user.company_id) + company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company_id) journal_ids = fields.Many2many('account.journal', string='Journals', required=True, default=lambda self: self.env['account.journal'].search([('company_id', '=', self.company_id.id)])) date_from = fields.Date(string='Start Date') date_to = fields.Date(string='End Date') diff --git a/addons/account/wizard/setup_wizards.py b/addons/account/wizard/setup_wizards.py index cb4820d4a0f..88b1f5b5657 100644 --- a/addons/account/wizard/setup_wizards.py +++ b/addons/account/wizard/setup_wizards.py @@ -42,7 +42,7 @@ class FinancialYearOpeningWizard(models.TransientModel): @api.multi def action_save_onboarding_fiscal_year(self): - self.env.user.company_id.set_onboarding_step_done('account_setup_fy_data_state') + self.env.company_id.set_onboarding_step_done('account_setup_fy_data_state') class SetupBarBankConfigWizard(models.TransientModel): @@ -71,7 +71,7 @@ class SetupBarBankConfigWizard(models.TransientModel): def _onchange_new_journal_code(self): for record in self: if not record.linked_journal_id: - record.new_journal_code = self.env['account.journal'].get_next_bank_cash_default_code('bank', self.env['res.company']._company_default_get('account.journal').id) + record.new_journal_code = self.env['account.journal'].get_next_bank_cash_default_code('bank', self.env.company_id.id) else: record.new_journal_code = self.linked_journal_id.code @@ -81,7 +81,7 @@ class SetupBarBankConfigWizard(models.TransientModel): company, so we always inject the corresponding partner when creating the model. """ - vals['partner_id'] = self.env.user.company_id.partner_id.id + vals['partner_id'] = self.env.company_id.partner_id.id return super(SetupBarBankConfigWizard, self).create(vals) @api.onchange('linked_journal_id') @@ -105,7 +105,7 @@ class SetupBarBankConfigWizard(models.TransientModel): for record in self: selected_journal = record.linked_journal_id if record.num_journals_without_account == 0: - company = self.env['res.company']._company_default_get('account.journal') + company = self.env.company_id selected_journal = self.env['account.journal'].create({ 'name': record.new_journal_name, 'code': record.new_journal_code, diff --git a/addons/account/wizard/wizard_tax_adjustments.py b/addons/account/wizard/wizard_tax_adjustments.py index 91a0edc7cf4..2ebae475fe4 100644 --- a/addons/account/wizard/wizard_tax_adjustments.py +++ b/addons/account/wizard/wizard_tax_adjustments.py @@ -19,7 +19,7 @@ class TaxAdjustments(models.TransientModel): credit_account_id = fields.Many2one('account.account', string='Credit account', required=True, domain=[('deprecated', '=', False)]) amount = fields.Monetary(currency_field='company_currency_id', required=True) adjustment_type = fields.Selection([('debit', 'Applied on debit journal item'), ('credit', 'Applied on credit journal item')], string="Adjustment Type", store=False, required=True) - company_currency_id = fields.Many2one('res.currency', readonly=True, default=lambda self: self.env.user.company_id.currency_id) + company_currency_id = fields.Many2one('res.currency', readonly=True, default=lambda self: self.env.company_id.currency_id) tax_id = fields.Many2one('account.tax', string='Adjustment Tax', ondelete='restrict', domain=[('type_tax_use', '=', 'adjustment')], required=True) @api.multi diff --git a/addons/account_analytic_default/security/account_analytic_default_security.xml b/addons/account_analytic_default/security/account_analytic_default_security.xml index 5183a7fb2d9..513146cd564 100644 --- a/addons/account_analytic_default/security/account_analytic_default_security.xml +++ b/addons/account_analytic_default/security/account_analytic_default_security.xml @@ -6,7 +6,7 @@ Analytic Default multi company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] diff --git a/addons/account_bank_statement_import/account_bank_statement_import.py b/addons/account_bank_statement_import/account_bank_statement_import.py index 34ac575431c..6a4ef086808 100644 --- a/addons/account_bank_statement_import/account_bank_statement_import.py +++ b/addons/account_bank_statement_import/account_bank_statement_import.py @@ -129,7 +129,7 @@ class AccountBankStatementImport(models.TransientModel): """ Look for a res.currency and account.journal using values extracted from the statement and make sure it's consistent. """ - company_currency = self.env.user.company_id.currency_id + company_currency = self.env.company_id.currency_id journal_obj = self.env['account.journal'] currency = None sanitized_account_number = sanitize_account_number(account_number) diff --git a/addons/account_facturx/models/account_invoice.py b/addons/account_facturx/models/account_invoice.py index 50dc6f29c81..911f6a917a2 100644 --- a/addons/account_facturx/models/account_invoice.py +++ b/addons/account_facturx/models/account_invoice.py @@ -118,7 +118,7 @@ class AccountInvoice(models.Model): if elements[0].attrib.get('currencyID'): currency_str = elements[0].attrib['currencyID'] currency = self.env.ref('base.%s' % currency_str.upper(), raise_if_not_found=False) - if currency != self.env.user.company_id.currency_id and currency.active: + if currency != self.env.company_id.currency_id and currency.active: invoice_form.currency_id = currency # Store xml total amount. diff --git a/addons/account_tax_python/models/account_tax.py b/addons/account_tax_python/models/account_tax.py index 632b7375f40..f9058e6f512 100644 --- a/addons/account_tax_python/models/account_tax.py +++ b/addons/account_tax_python/models/account_tax.py @@ -29,7 +29,7 @@ class AccountTaxPython(models.Model): def _compute_amount(self, base_amount, price_unit, quantity=1.0, product=None, partner=None): self.ensure_one() if self.amount_type == 'code': - company = self.env.user.company_id + company = self.env.company_id localdict = {'base_amount': base_amount, 'price_unit':price_unit, 'quantity': quantity, 'product':product, 'partner':partner, 'company': company} safe_eval(self.python_compute, localdict, mode="exec", nocopy=True) return localdict['result'] @@ -38,7 +38,7 @@ class AccountTaxPython(models.Model): @api.multi def compute_all(self, price_unit, currency=None, quantity=1.0, product=None, partner=None): taxes = self.filtered(lambda r: r.amount_type != 'code') - company = self.env.user.company_id + company = self.env.company_id for tax in self.filtered(lambda r: r.amount_type == 'code'): localdict = self._context.get('tax_computation_context', {}) localdict.update({'price_unit': price_unit, 'quantity': quantity, 'product': product, 'partner': partner, 'company': company}) diff --git a/addons/account_voucher/models/account_voucher.py b/addons/account_voucher/models/account_voucher.py index d868a1de62f..2aadf6fe2fb 100644 --- a/addons/account_voucher/models/account_voucher.py +++ b/addons/account_voucher/models/account_voucher.py @@ -16,7 +16,7 @@ class AccountVoucher(models.Model): @api.model def _default_journal(self): voucher_type = self._context.get('voucher_type', 'sale') - company_id = self._context.get('company_id', self.env.user.company_id.id) + company_id = self._context.get('company_id', self.env.company_id.id) domain = [ ('type', '=', voucher_type), ('company_id', '=', company_id), @@ -25,7 +25,7 @@ class AccountVoucher(models.Model): @api.model def _default_payment_journal(self): - company_id = self._context.get('company_id', self.env.user.company_id.id) + company_id = self._context.get('company_id', self.env.company_id.id) domain = [ ('type', 'in', ('bank', 'cash')), ('company_id', '=', company_id), @@ -96,11 +96,11 @@ class AccountVoucher(models.Model): journal = self.env['account.journal'].browse(self.env.context.get('default_journal_id', False)) if journal.currency_id: return journal.currency_id.id - return self.env.user.company_id.currency_id.id + return self.env.company_id.currency_id.id @api.model def _get_company(self): - return self._context.get('company_id', self.env.user.company_id.id) + return self._context.get('company_id', self.env.company_id.id) @api.constrains('company_id', 'currency_id') def _check_company_id(self): @@ -274,7 +274,7 @@ class AccountVoucher(models.Model): :return: Tuple build as (remaining amount not allocated on voucher lines, list of account_move_line created in this method) :rtype: tuple(float, list of int) ''' - tax_calculation_rounding_method = self.env.user.company_id.tax_calculation_rounding_method + tax_calculation_rounding_method = self.env.company_id.tax_calculation_rounding_method tax_lines_vals = [] for line in self.line_ids: #create one move line per voucher line where amount is not 0.0 diff --git a/addons/account_voucher/security/account_voucher_security.xml b/addons/account_voucher/security/account_voucher_security.xml index c32e720f67e..6c0d836c0c0 100644 --- a/addons/account_voucher/security/account_voucher_security.xml +++ b/addons/account_voucher/security/account_voucher_security.xml @@ -5,13 +5,13 @@ Voucher multi-company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Voucher Line multi-company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] diff --git a/addons/analytic/models/analytic_account.py b/addons/analytic/models/analytic_account.py index 91815380304..92d038ab732 100644 --- a/addons/analytic/models/analytic_account.py +++ b/addons/analytic/models/analytic_account.py @@ -93,7 +93,7 @@ class AccountAnalyticAccount(models.Model): if self._context.get('company_ids'): domain.append(('company_id', 'in', self._context['company_ids'])) - user_currency = self.env.user.company_id.currency_id + user_currency = self.env.company_id.currency_id credit_groups = analytic_line_obj.read_group( domain=domain + [('amount', '>=', 0.0)], fields=['account_id', 'currency_id', 'amount'], @@ -103,7 +103,7 @@ class AccountAnalyticAccount(models.Model): data_credit = defaultdict(float) for l in credit_groups: data_credit[l['account_id'][0]] += Curr.browse(l['currency_id'][0])._convert( - l['amount'], user_currency, self.env.user.company_id, fields.Date.today()) + l['amount'], user_currency, self.env.company_id, fields.Date.today()) debit_groups = analytic_line_obj.read_group( domain=domain + [('amount', '<', 0.0)], @@ -114,7 +114,7 @@ class AccountAnalyticAccount(models.Model): data_debit = defaultdict(float) for l in debit_groups: data_debit[l['account_id'][0]] += Curr.browse(l['currency_id'][0])._convert( - l['amount'], user_currency, self.env.user.company_id, fields.Date.today()) + l['amount'], user_currency, self.env.company_id, fields.Date.today()) for account in self: account.debit = abs(data_debit.get(account.id, 0.0)) @@ -129,7 +129,7 @@ class AccountAnalyticAccount(models.Model): line_ids = fields.One2many('account.analytic.line', 'account_id', string="Analytic Lines") - company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id) + company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company_id) # use auto_join to speed up name_search call partner_id = fields.Many2one('res.partner', string='Customer', auto_join=True, tracking=True) @@ -186,7 +186,7 @@ class AccountAnalyticLine(models.Model): partner_id = fields.Many2one('res.partner', string='Partner') user_id = fields.Many2one('res.users', string='User', default=_default_user) tag_ids = fields.Many2many('account.analytic.tag', 'account_analytic_line_tag_rel', 'line_id', 'tag_id', string='Tags', copy=True) - company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True, default=lambda self: self.env.user.company_id) + company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True, default=lambda self: self.env.company_id) currency_id = fields.Many2one(related="company_id.currency_id", string="Currency", readonly=True, store=True, compute_sudo=True) group_id = fields.Many2one('account.analytic.group', related='account_id.group_id', store=True, readonly=True, compute_sudo=True) diff --git a/addons/analytic/security/analytic_security.xml b/addons/analytic/security/analytic_security.xml index 5e66d317f5c..696beb03dc8 100644 --- a/addons/analytic/security/analytic_security.xml +++ b/addons/analytic/security/analytic_security.xml @@ -6,28 +6,28 @@ Analytic multi company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Analytic line multi company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Analytic line multi company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Analytic line multi company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] diff --git a/addons/base_setup/models/res_config_settings.py b/addons/base_setup/models/res_config_settings.py index 73da6f2a076..49dccf49bc5 100644 --- a/addons/base_setup/models/res_config_settings.py +++ b/addons/base_setup/models/res_config_settings.py @@ -9,8 +9,9 @@ class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' group_multi_company = fields.Boolean("Manage multiple companies", implied_group='base.group_multi_company') + group_toggle_company = fields.Boolean("Toggle multiple companies", implied_group='base.group_toggle_company') company_id = fields.Many2one('res.company', string='Company', required=True, - default=lambda self: self.env.user.company_id) + default=lambda self: self.env.company_id) user_default_rights = fields.Boolean( "Default Access Rights", config_parameter='base_setup.default_user_rights', @@ -67,7 +68,7 @@ class ResConfigSettings(models.TransientModel): 'view_type': 'form', 'view_mode': 'form', 'res_model': 'res.company', - 'res_id': self.env.user.company_id.id, + 'res_id': self.env.company_id.id, 'target': 'current', } @api.multi @@ -103,7 +104,7 @@ class ResConfigSettings(models.TransientModel): 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', - 'res_id': self.env.user.company_id.id, + 'res_id': self.env.company_id.id, 'res_model': 'res.company', 'views': [(template.id, 'form')], 'view_id': template.id, diff --git a/addons/base_setup/views/res_config_settings_views.xml b/addons/base_setup/views/res_config_settings_views.xml index 8aff13e062b..8dcbda44ed5 100644 --- a/addons/base_setup/views/res_config_settings_views.xml +++ b/addons/base_setup/views/res_config_settings_views.xml @@ -141,6 +141,18 @@ +
+
+ +
+
+
+
diff --git a/addons/base_vat/models/res_partner.py b/addons/base_vat/models/res_partner.py index c5118cd476b..c25c8641bb8 100644 --- a/addons/base_vat/models/res_partner.py +++ b/addons/base_vat/models/res_partner.py @@ -155,7 +155,7 @@ class ResPartner(models.Model): if self.env.context.get('company_id'): company = self.env['res.company'].browse(self.env.context['company_id']) else: - company = self.env.user.company_id + company = self.env.company_id if company.vat_check_vies: # force full VIES online check check_func = self.vies_vat_check @@ -182,7 +182,7 @@ class ResPartner(models.Model): if self.env.context.get('company_id'): company = self.env['res.company'].browse(self.env.context['company_id']) else: - company = self.env.user.company_id + company = self.env.company_id if company.vat_check_vies: return '\n' + _('The VAT number [%s] for partner [%s] either failed the VIES VAT validation check or did not respect the expected format %s.') % (self.vat, self.name, vat_no) return '\n' + _('The VAT number [%s] for partner [%s] does not seem to be valid. \nNote: the expected format is %s') % (self.vat, self.name, vat_no) diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py index 008725eb595..cd6f402e579 100644 --- a/addons/crm/models/crm_lead.py +++ b/addons/crm/models/crm_lead.py @@ -124,7 +124,7 @@ class Lead(models.Model): mobile = fields.Char('Mobile') function = fields.Char('Job Position') title = fields.Many2one('res.partner.title') - company_id = fields.Many2one('res.company', string='Company', index=True, default=lambda self: self.env.user.company_id.id) + company_id = fields.Many2one('res.company', string='Company', index=True, default=lambda self: self.env.company_id.id) meeting_count = fields.Integer('# Meetings', compute='_compute_meeting_count') lost_reason = fields.Many2one('crm.lost.reason', string='Lost Reason', index=True, tracking=True) @@ -1082,7 +1082,7 @@ class Lead(models.Model): result['done']['target'] = self.env.user.target_sales_done result['won']['target'] = self.env.user.target_sales_won - result['currency_id'] = self.env.user.company_id.currency_id.id + result['currency_id'] = self.env.company_id.currency_id.id return result diff --git a/addons/crm/security/crm_security.xml b/addons/crm/security/crm_security.xml index 450b0e3646c..e96c6f1809a 100644 --- a/addons/crm/security/crm_security.xml +++ b/addons/crm/security/crm_security.xml @@ -35,7 +35,7 @@ CRM Lead Multi-Company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] @@ -70,7 +70,7 @@ CRM Lead Multi-Company - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] diff --git a/addons/crm/tests/test_new_lead_notification.py b/addons/crm/tests/test_new_lead_notification.py index 16228fcc55c..1b0f4c3a14c 100644 --- a/addons/crm/tests/test_new_lead_notification.py +++ b/addons/crm/tests/test_new_lead_notification.py @@ -43,7 +43,7 @@ class NewLeadNotification(TestCrmCases): self.assertTrue(lead_user.message_needaction) def test_new_lead_from_email_multicompany(self): - company0 = self.env.user.company_id + company0 = self.env.company_id company1 = self.env['res.company'].create({'name': 'new_company'}) self.env.user.write({ diff --git a/addons/crm_iap_lead_website/models/crm_reveal_rule.py b/addons/crm_iap_lead_website/models/crm_reveal_rule.py index 1b063d95c75..4e0e2c0c831 100644 --- a/addons/crm_iap_lead_website/models/crm_reveal_rule.py +++ b/addons/crm_iap_lead_website/models/crm_reveal_rule.py @@ -273,7 +273,7 @@ class CRMRevealRule(models.Model): } def _get_rules_payload(self): - company_country = self.env.user.company_id.country_id + company_country = self.env.company_id.country_id rule_payload = {} for rule in self: data = { diff --git a/addons/delivery/models/stock_picking.py b/addons/delivery/models/stock_picking.py index 6444f110d38..66512fdf384 100644 --- a/addons/delivery/models/stock_picking.py +++ b/addons/delivery/models/stock_picking.py @@ -74,7 +74,7 @@ class StockPicking(models.Model): carrier_price = fields.Float(string="Shipping Cost") delivery_type = fields.Selection(related='carrier_id.delivery_type', readonly=True) - carrier_id = fields.Many2one("delivery.carrier", string="Carrier") + carrier_id = fields.Many2one("delivery.carrier", string="Carrier", domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") volume = fields.Float(copy=False) weight = fields.Float(compute='_cal_weight', digits=dp.get_precision('Stock Weight'), store=True, help="Total weight of the products in the picking.") carrier_tracking_ref = fields.Char(string='Tracking Reference', copy=False) diff --git a/addons/delivery/security/delivery_carrier_security.xml b/addons/delivery/security/delivery_carrier_security.xml index db718fbf361..e9e22c47088 100644 --- a/addons/delivery/security/delivery_carrier_security.xml +++ b/addons/delivery/security/delivery_carrier_security.xml @@ -5,7 +5,7 @@ Delivery Carrier multi-company - ['|',('company_id','=',user.company_id.id),('company_id','=',False)] + ['|', ('company_id', 'in', company_ids), ('company_id', '=', False)] diff --git a/addons/delivery/tests/test_delivery_cost.py b/addons/delivery/tests/test_delivery_cost.py index 71d0ab0ae98..a57e617d946 100644 --- a/addons/delivery/tests/test_delivery_cost.py +++ b/addons/delivery/tests/test_delivery_cost.py @@ -32,7 +32,7 @@ class TestDeliveryCost(common.TransactionCase): # that the company actually uses USD self.env.cr.execute( "UPDATE res_company SET currency_id = %s WHERE id = %s", - [self.env.ref('base.USD').id, self.env.user.company_id.id]) + [self.env.ref('base.USD').id, self.env.company_id.id]) self.pricelist.currency_id = self.env.ref('base.USD').id def test_00_delivery_cost(self): diff --git a/addons/digest/models/digest.py b/addons/digest/models/digest.py index 1d10c59d504..f7eb085a5b3 100644 --- a/addons/digest/models/digest.py +++ b/addons/digest/models/digest.py @@ -33,7 +33,7 @@ class Digest(models.Model): default=lambda self: self.env.ref('digest.digest_mail_template'), required=True) currency_id = fields.Many2one(related="company_id.currency_id", string='Currency', readonly=False) - company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id.id) + company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company_id.id) available_fields = fields.Char(compute='_compute_available_fields') is_subscribed = fields.Boolean('Is user subscribed', compute='_compute_is_subscribed') state = fields.Selection([('activated', 'Activated'), ('deactivated', 'Deactivated')], string='Status', readonly=True, default='activated') diff --git a/addons/event/models/event.py b/addons/event/models/event.py index 328abb783d9..0095452a69d 100644 --- a/addons/event/models/event.py +++ b/addons/event/models/event.py @@ -101,12 +101,12 @@ class EventEvent(models.Model): readonly=False, states={'done': [('readonly', True)]}) company_id = fields.Many2one( 'res.company', string='Company', change_default=True, - default=lambda self: self.env['res.company']._company_default_get('event.event'), + default=lambda self: self.env.company_id, required=False, readonly=False, states={'done': [('readonly', True)]}) organizer_id = fields.Many2one( 'res.partner', string='Organizer', tracking=True, - default=lambda self: self.env.user.company_id.partner_id) + default=lambda self: self.env.company_id.partner_id) event_type_id = fields.Many2one( 'event.type', string='Category', readonly=False, states={'done': [('readonly', True)]}, @@ -165,7 +165,7 @@ class EventEvent(models.Model): is_online = fields.Boolean('Online Event') address_id = fields.Many2one( 'res.partner', string='Location', - default=lambda self: self.env.user.company_id.partner_id, + default=lambda self: self.env.company_id.partner_id, readonly=False, states={'done': [('readonly', True)]}, tracking=True) country_id = fields.Many2one('res.country', 'Country', related='address_id.country_id', store=True, readonly=False) diff --git a/addons/event/security/event_security.xml b/addons/event/security/event_security.xml index cf87135ddbe..08dd739cf52 100644 --- a/addons/event/security/event_security.xml +++ b/addons/event/security/event_security.xml @@ -32,7 +32,7 @@ ['|', ('company_id', '=', False), - ('company_id', 'child_of', [user.company_id.id]), + ('company_id', 'in', company_ids), ] @@ -42,7 +42,7 @@ ['|', ('company_id', '=', False), - ('company_id', 'child_of', [user.company_id.id]), + ('company_id', 'in', company_ids), ] diff --git a/addons/event_sale/models/sale_order.py b/addons/event_sale/models/sale_order.py index fac1730bead..c2f0feb9398 100644 --- a/addons/event_sale/models/sale_order.py +++ b/addons/event_sale/models/sale_order.py @@ -80,7 +80,7 @@ class SaleOrderLine(models.Model): @api.onchange('event_ticket_id') def _onchange_event_ticket_id(self): - company = self.event_id.company_id or self.env.user.company_id + company = self.event_id.company_id or self.env.company_id currency = company.currency_id self.price_unit = currency._convert( self.event_ticket_id.price, self.order_id.currency_id, self.order_id.company_id, self.order_id.date_order or fields.Date.today()) diff --git a/addons/fleet/models/fleet_vehicle.py b/addons/fleet/models/fleet_vehicle.py index 773d10050ca..0d4ebd157f4 100644 --- a/addons/fleet/models/fleet_vehicle.py +++ b/addons/fleet/models/fleet_vehicle.py @@ -19,7 +19,7 @@ class FleetVehicle(models.Model): name = fields.Char(compute="_compute_vehicle_name", store=True) active = fields.Boolean('Active', default=True, tracking=True) - company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env['res.company']._company_default_get()) + company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env.company_id) currency_id = fields.Many2one('res.currency', related='company_id.currency_id') license_plate = fields.Char(tracking=True, help='License plate number of the vehicle (i = plate number for a car)') diff --git a/addons/fleet/models/fleet_vehicle_cost.py b/addons/fleet/models/fleet_vehicle_cost.py index fa5bd4bf418..453b7a8b1c7 100644 --- a/addons/fleet/models/fleet_vehicle_cost.py +++ b/addons/fleet/models/fleet_vehicle_cost.py @@ -32,7 +32,7 @@ class FleetVehicleCost(models.Model): contract_id = fields.Many2one('fleet.vehicle.log.contract', 'Contract', help='Contract attached to this cost') auto_generated = fields.Boolean('Automatically Generated', readonly=True) description = fields.Char("Cost Description") - company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env['res.company']._company_default_get()) + company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env.company_id) currency_id = fields.Many2one('res.currency', related='company_id.currency_id') def _get_odometer(self): diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index dfb850897c8..05f7059cbbd 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -66,7 +66,7 @@ class GoalDefinition(models.Model): items = [] if goal.monetary: - items.append(self.env.user.company_id.currency_id.symbol or u'¤') + items.append(self.env.company_id.currency_id.symbol or u'¤') if goal.suffix: items.append(goal.suffix) diff --git a/addons/gamification/security/gamification_security.xml b/addons/gamification/security/gamification_security.xml index 3eecfb2e98c..4629c8776b2 100644 --- a/addons/gamification/security/gamification_security.xml +++ b/addons/gamification/security/gamification_security.xml @@ -31,7 +31,7 @@ Multicompany rule on challenges - [('user_id.company_id', 'child_of', [user.company_id.id])] + [('user_id.company_id', 'in', company_ids)] diff --git a/addons/hr/models/hr.py b/addons/hr/models/hr.py index cccb266981b..7660c755471 100644 --- a/addons/hr/models/hr.py +++ b/addons/hr/models/hr.py @@ -47,7 +47,7 @@ class Job(models.Model): description = fields.Text(string='Job Description') requirements = fields.Text('Requirements') department_id = fields.Many2one('hr.department', string='Department') - company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id) + company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company_id) state = fields.Selection([ ('recruit', 'Recruitment in Progress'), ('open', 'Not Recruiting') @@ -379,7 +379,7 @@ class Department(models.Model): name = fields.Char('Department Name', required=True) complete_name = fields.Char('Complete Name', compute='_compute_complete_name', store=True) active = fields.Boolean('Active', default=True) - company_id = fields.Many2one('res.company', string='Company', index=True, default=lambda self: self.env.user.company_id) + company_id = fields.Many2one('res.company', string='Company', index=True, default=lambda self: self.env.company_id) parent_id = fields.Many2one('hr.department', string='Parent Department', index=True) child_ids = fields.One2many('hr.department', 'parent_id', string='Child Departments') manager_id = fields.Many2one('hr.employee', string='Manager', tracking=True) diff --git a/addons/hr/models/res_partner.py b/addons/hr/models/res_partner.py index 9258c1ac5da..62f7c3f949a 100644 --- a/addons/hr/models/res_partner.py +++ b/addons/hr/models/res_partner.py @@ -16,8 +16,7 @@ class Partner(models.Model): try: employee_group = self.env.ref('base.group_user') - hr_suggestions = [{'id': user.partner_id.id, 'name': user.name, 'email': user.email} - for user in employee_group.users] + hr_suggestions = [{'id': user.partner_id.id, 'name': user.name, 'email': user.email} for user in employee_group.users] suggestions.append(hr_suggestions) return suggestions except AccessError: diff --git a/addons/hr/security/hr_security.xml b/addons/hr/security/hr_security.xml index 8d435e67463..c735d05b1ce 100644 --- a/addons/hr/security/hr_security.xml +++ b/addons/hr/security/hr_security.xml @@ -30,21 +30,21 @@ Employee multi company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Department multi company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Job multi company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] diff --git a/addons/hr_attendance_presence/models/hr_employee.py b/addons/hr_attendance_presence/models/hr_employee.py index 3fac86ce6c4..af259d7fc4f 100644 --- a/addons/hr_attendance_presence/models/hr_employee.py +++ b/addons/hr_attendance_presence/models/hr_employee.py @@ -16,7 +16,7 @@ class Employee(models.Model): action = super(Employee, self)._action_open_presence_view() if self.env['ir.config_parameter'].sudo().get_param('hr_presence.hr_presence_control_attendance'): - company = self.env.user.company_id + company = self.env.company_id employees = self.env['hr.employee'].search([ ('department_id.company_id', '=', company.id), ('user_id', '!=', False), diff --git a/addons/hr_contract/models/hr_contract.py b/addons/hr_contract/models/hr_contract.py index f41d4faba71..4f333a3c4b4 100644 --- a/addons/hr_contract/models/hr_contract.py +++ b/addons/hr_contract/models/hr_contract.py @@ -66,7 +66,7 @@ class Contract(models.Model): help="End date of the trial period (if there is one).") resource_calendar_id = fields.Many2one( 'resource.calendar', 'Working Schedule', - default=lambda self: self.env['res.company']._company_default_get().resource_calendar_id.id) + default=lambda self: self.env.company_id.resource_calendar_id.id) wage = fields.Monetary('Wage', digits=(16, 2), required=True, tracking=True, help="Employee's monthly gross wage.") advantages = fields.Text('Advantages') notes = fields.Text('Notes') @@ -79,7 +79,7 @@ class Contract(models.Model): ('cancel', 'Cancelled') ], string='Status', group_expand='_expand_states', tracking=True, help='Status of the contract', default='draft') - company_id = fields.Many2one('res.company', default=lambda self: self.env.user.company_id) + company_id = fields.Many2one('res.company', default=lambda self: self.env.company_id) currency_id = fields.Many2one(string="Currency", related='company_id.currency_id', readonly=True) permit_no = fields.Char('Work Permit No', related="employee_id.permit_no", readonly=False) visa_no = fields.Char('Visa No', related="employee_id.visa_no", readonly=False) diff --git a/addons/hr_contract/security/security.xml b/addons/hr_contract/security/security.xml index d592b820a16..4a3cf359d8e 100644 --- a/addons/hr_contract/security/security.xml +++ b/addons/hr_contract/security/security.xml @@ -21,7 +21,7 @@ HR Contract: Multi Company - ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])] + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py index b0a8c584c67..a4fc1c58338 100644 --- a/addons/hr_expense/models/hr_expense.py +++ b/addons/hr_expense/models/hr_expense.py @@ -56,8 +56,8 @@ class HrExpense(models.Model): untaxed_amount = fields.Float("Subtotal", store=True, compute='_compute_amount', digits=dp.get_precision('Account')) total_amount = fields.Monetary("Total", compute='_compute_amount', store=True, currency_field='currency_id', digits=dp.get_precision('Account')) total_amount_company = fields.Monetary("Total (Company Currency)", compute='_compute_total_amount_company', store=True, currency_field='company_currency_id', digits=dp.get_precision('Account')) - company_id = fields.Many2one('res.company', string='Company', readonly=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, default=lambda self: self.env.user.company_id) - currency_id = fields.Many2one('res.currency', string='Currency', readonly=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, default=lambda self: self.env.user.company_id.currency_id) + company_id = fields.Many2one('res.company', string='Company', readonly=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, default=lambda self: self.env.company_id) + currency_id = fields.Many2one('res.currency', string='Currency', readonly=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, default=lambda self: self.env.company_id.currency_id) company_currency_id = fields.Many2one('res.currency', string="Report Company Currency", related='sheet_id.currency_id', store=True, readonly=False) analytic_account_id = fields.Many2one('account.analytic.account', string='Analytic Account', states={'post': [('readonly', True)], 'done': [('readonly', True)]}, oldname='analytic_account') analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags', states={'post': [('readonly', True)], 'done': [('readonly', True)]}) @@ -224,7 +224,7 @@ class HrExpense(models.Model): journal = expense.sheet_id.bank_journal_id if expense.payment_mode == 'company_account' else expense.sheet_id.journal_id move = self.env['account.move'].create({ 'journal_id': journal.id, - 'company_id': self.env.user.company_id.id, + 'company_id': self.env.company_id.id, 'date': account_date, 'ref': expense.sheet_id.name, # force the name to the default value, to avoid an eventual 'default_name' in the context @@ -595,8 +595,8 @@ class HrExpenseSheet(models.Model): payment_mode = fields.Selection(related='expense_line_ids.payment_mode', default='own_account', readonly=True, string="Paid By") user_id = fields.Many2one('res.users', 'Manager', readonly=True, copy=False, states={'draft': [('readonly', False)]}, tracking=True, oldname='responsible_id') total_amount = fields.Monetary('Total Amount', currency_field='currency_id', compute='_compute_amount', store=True, digits=dp.get_precision('Account')) - company_id = fields.Many2one('res.company', string='Company', readonly=True, states={'draft': [('readonly', False)]}, default=lambda self: self.env.user.company_id) - currency_id = fields.Many2one('res.currency', string='Currency', readonly=True, states={'draft': [('readonly', False)]}, default=lambda self: self.env.user.company_id.currency_id) + company_id = fields.Many2one('res.company', string='Company', readonly=True, states={'draft': [('readonly', False)]}, default=lambda self: self.env.company_id) + currency_id = fields.Many2one('res.currency', string='Currency', readonly=True, states={'draft': [('readonly', False)]}, default=lambda self: self.env.company_id.currency_id) attachment_number = fields.Integer(compute='_compute_attachment_number', string='Number of Attachments') journal_id = fields.Many2one('account.journal', string='Expense Journal', states={'done': [('readonly', True)], 'post': [('readonly', True)]}, default=_default_journal_id, help="The journal used when the expense is done.") bank_journal_id = fields.Many2one('account.journal', string='Bank Journal', states={'done': [('readonly', True)], 'post': [('readonly', True)]}, default=_default_bank_journal_id, help="The payment method used when the expense is paid by the company.") @@ -697,7 +697,7 @@ class HrExpenseSheet(models.Model): raise UserError(_("Expenses must have an expense journal specified to generate accounting entries.")) expense_line_ids = self.mapped('expense_line_ids')\ - .filtered(lambda r: not float_is_zero(r.total_amount, precision_rounding=(r.currency_id or self.env.user.company_id.currency_id).rounding)) + .filtered(lambda r: not float_is_zero(r.total_amount, precision_rounding=(r.currency_id or self.env.company_id.currency_id).rounding)) res = expense_line_ids.action_move_create() if not self.accounting_date: diff --git a/addons/hr_expense/security/ir_rule.xml b/addons/hr_expense/security/ir_rule.xml index 51a3a8d641d..3b13eb977a6 100644 --- a/addons/hr_expense/security/ir_rule.xml +++ b/addons/hr_expense/security/ir_rule.xml @@ -55,13 +55,13 @@ Expense multi company rule - ['|',('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])] + ['|',('company_id', '=', False), ('company_id', 'in', company_ids)] Expense Report multi company rule - ['|',('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])] + ['|',('company_id', '=', False), ('company_id', 'in', company_ids)] diff --git a/addons/hr_expense/tests/test_expenses.py b/addons/hr_expense/tests/test_expenses.py index 66a56b2f557..5ab7abe3d67 100644 --- a/addons/hr_expense/tests/test_expenses.py +++ b/addons/hr_expense/tests/test_expenses.py @@ -83,11 +83,11 @@ class TestAccountEntry(TestExpenseCommon): multi-currency. And taxes. """ # Clean-up the rates - self.cr.execute("UPDATE res_company SET currency_id = %s WHERE id = %s", [self.env.ref('base.USD').id, self.env.user.company_id.id]) + self.cr.execute("UPDATE res_company SET currency_id = %s WHERE id = %s", [self.env.ref('base.USD').id, self.env.company_id.id]) self.env['res.currency.rate'].search([]).unlink() self.env['res.currency.rate'].create({ 'currency_id': self.env.ref('base.EUR').id, - 'company_id': self.env.user.company_id.id, + 'company_id': self.env.company_id.id, 'rate': 2.0, 'name': '2010-01-01', }) @@ -142,7 +142,7 @@ class TestAccountEntry(TestExpenseCommon): self.assertEquals(self.analytic_account.line_ids, expense.account_move_id.mapped('line_ids.analytic_line_ids')) self.assertEquals(len(self.analytic_account.line_ids), 1, "Analytic Account should have only one line") self.assertAlmostEquals(self.analytic_account.line_ids[0].amount, -318.18, "Amount on the only AAL is wrong") - self.assertAlmostEquals(self.analytic_account.line_ids[0].currency_id, self.env.user.company_id.currency_id, "Currency on the only AAL is wrong") + self.assertAlmostEquals(self.analytic_account.line_ids[0].currency_id, self.env.company_id.currency_id, "Currency on the only AAL is wrong") self.assertEquals(self.analytic_account.line_ids[0].product_id, self.product_expense, "Product of AAL should be the one from the expense") def test_expense_from_email(self): diff --git a/addons/hr_expense/wizard/hr_expense_sheet_register_payment.py b/addons/hr_expense/wizard/hr_expense_sheet_register_payment.py index 76a97f6a561..2cacf083f74 100644 --- a/addons/hr_expense/wizard/hr_expense_sheet_register_payment.py +++ b/addons/hr_expense/wizard/hr_expense_sheet_register_payment.py @@ -23,7 +23,7 @@ class HrExpenseSheetRegisterPaymentWizard(models.TransientModel): company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', readonly=True, required=True) payment_method_id = fields.Many2one('account.payment.method', string='Payment Type', required=True) amount = fields.Monetary(string='Payment Amount', required=True) - currency_id = fields.Many2one('res.currency', string='Currency', required=True, default=lambda self: self.env.user.company_id.currency_id) + currency_id = fields.Many2one('res.currency', string='Currency', required=True, default=lambda self: self.env.company_id.currency_id) payment_date = fields.Date(string='Payment Date', default=fields.Date.context_today, required=True) communication = fields.Char(string='Memo') hide_payment_method = fields.Boolean(compute='_compute_hide_payment_method', diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index 443d01f4729..942b83dbe2a 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -278,7 +278,7 @@ class HolidaysRequest(models.Model): self.date_to = False return - domain = [('calendar_id', '=', self.employee_id.resource_calendar_id.id or self.env.user.company_id.resource_calendar_id.id)] + domain = [('calendar_id', '=', self.employee_id.resource_calendar_id.id or self.env.company_id.resource_calendar_id.id)] attendances = self.env['resource.calendar.attendance'].search(domain, order='dayofweek, day_period DESC') # find first attendance coming after first_day @@ -341,7 +341,7 @@ class HolidaysRequest(models.Model): self.category_id = False elif self.holiday_type == 'company' and not self.mode_company_id: self.employee_id = False - self.mode_company_id = self.env.user.company_id.id + self.mode_company_id = self.env.company_id.id self.category_id = False elif self.holiday_type == 'department' and not self.department_id: self.employee_id = False @@ -376,7 +376,7 @@ class HolidaysRequest(models.Model): @api.depends('number_of_days') def _compute_number_of_hours_display(self): for holiday in self: - calendar = holiday.employee_id.resource_calendar_id or self.env.user.company_id.resource_calendar_id + calendar = holiday.employee_id.resource_calendar_id or self.env.company_id.resource_calendar_id if holiday.date_from and holiday.date_to: number_of_hours = calendar.get_work_hours_count(holiday.date_from, holiday.date_to) holiday.number_of_hours_display = number_of_hours or (holiday.number_of_days * HOURS_PER_DAY) @@ -438,12 +438,12 @@ class HolidaysRequest(models.Model): employee = self.env['hr.employee'].browse(employee_id) return employee._get_work_days_data(date_from, date_to)['days'] - today_hours = self.env.user.company_id.resource_calendar_id.get_work_hours_count( + today_hours = self.env.company_id.resource_calendar_id.get_work_hours_count( datetime.combine(date_from.date(), time.min), datetime.combine(date_from.date(), time.max), False) - return self.env.user.company_id.resource_calendar_id.get_work_hours_count(date_from, date_to) / (today_hours or HOURS_PER_DAY) + return self.env.company_id.resource_calendar_id.get_work_hours_count(date_from, date_to) / (today_hours or HOURS_PER_DAY) #################################################### # ORM Overrides methods @@ -563,6 +563,9 @@ class HolidaysRequest(models.Model): def copy_data(self, default=None): raise UserError(_('A leave cannot be duplicated.')) + def _get_mail_redirect_suggested_company(self): + return self.holiday_status_id.company_id + #################################################### # Business methods #################################################### @@ -606,7 +609,7 @@ class HolidaysRequest(models.Model): @api.multi def _prepare_holidays_meeting_values(self): self.ensure_one() - calendar = self.employee_id.resource_calendar_id or self.env.user.company_id.resource_calendar_id + calendar = self.employee_id.resource_calendar_id or self.env.company_id.resource_calendar_id meeting_values = { 'name': self.display_name, 'categ_ids': [(6, 0, [ diff --git a/addons/hr_holidays/models/hr_leave_allocation.py b/addons/hr_holidays/models/hr_leave_allocation.py index abfb441a0c9..1ad7b9fca45 100644 --- a/addons/hr_holidays/models/hr_leave_allocation.py +++ b/addons/hr_holidays/models/hr_leave_allocation.py @@ -365,6 +365,9 @@ class HolidaysAllocation(models.Model): def copy_data(self, default=None): raise UserError(_('A time off cannot be duplicated.')) + def _get_mail_redirect_suggested_company(self): + return self.holiday_status_id.company_id + #################################################### # Business methods #################################################### diff --git a/addons/hr_holidays/models/hr_leave_type.py b/addons/hr_holidays/models/hr_leave_type.py index 9b92f171d9e..fed5240b002 100644 --- a/addons/hr_holidays/models/hr_leave_type.py +++ b/addons/hr_holidays/models/hr_leave_type.py @@ -64,7 +64,7 @@ class HolidaysType(models.Model): compute='_compute_group_days_allocation', string='Days Allocated') group_days_leave = fields.Float( compute='_compute_group_days_leave', string='Group Time Off') - company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.user.company_id) + company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company_id) responsible_id = fields.Many2one('res.users', 'Responsible', domain=lambda self: [('groups_id', 'in', self.env.ref('hr_holidays.group_hr_holidays_user').id)], help="This user will be responsible for approving this type of times off" "This is only used when validation is 'hr' or 'both'",) @@ -208,7 +208,7 @@ class HolidaysType(models.Model): elif 'default_employee_id' in self._context: employee_id = self._context['default_employee_id'] else: - employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.user.id), ('company_id', '=', self.env.user.company_id.id)], limit=1).id + employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.user.id), ('company_id', '=', self.env.company_id.id)], limit=1).id return employee_id @api.multi diff --git a/addons/hr_holidays/security/hr_holidays_security.xml b/addons/hr_holidays/security/hr_holidays_security.xml index c8b10a11d7b..623438454b4 100644 --- a/addons/hr_holidays/security/hr_holidays_security.xml +++ b/addons/hr_holidays/security/hr_holidays_security.xml @@ -77,7 +77,7 @@ Time Off: multi company global rule - ['|', ('holiday_status_id.company_id', '=', False), ('holiday_status_id.company_id', 'in', [user.company_id.id])] + ['|', ('holiday_status_id.company_id', '=', False), ('holiday_status_id.company_id', 'in', company_ids)] @@ -145,7 +145,7 @@ Time Off multi company rule - ['|',('company_id','=',False),('company_id','in',[user.company_id.id])] + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] diff --git a/addons/hr_org_chart/controllers/hr_org_chart.py b/addons/hr_org_chart/controllers/hr_org_chart.py index 20f1c30047a..a82d9002d33 100644 --- a/addons/hr_org_chart/controllers/hr_org_chart.py +++ b/addons/hr_org_chart/controllers/hr_org_chart.py @@ -9,12 +9,17 @@ from odoo.http import request class HrOrgChartController(http.Controller): _managers_level = 5 # FP request - def _check_employee(self, employee_id): + def _check_employee(self, employee_id, **kw): if not employee_id: # to check return None employee_id = int(employee_id) - Employee = request.env['hr.employee'] + if ('context' in kw and 'allowed_company_ids' in kw['context']): + cids = kw['context']['allowed_company_ids'] + else: + cids = [request.env.company_id.id] + + Employee = request.env['hr.employee'].with_context(allowed_company_ids=cids) # check and raise if not Employee.check_access_rights('read', raise_exception=False): return None @@ -38,9 +43,9 @@ class HrOrgChartController(http.Controller): ) @http.route('/hr/get_org_chart', type='json', auth='user') - def get_org_chart(self, employee_id): + def get_org_chart(self, employee_id, **kw): - employee = self._check_employee(employee_id) + employee = self._check_employee(employee_id, **kw) if not employee: # to check return {} @@ -64,15 +69,14 @@ class HrOrgChartController(http.Controller): return values @http.route('/hr/get_subordinates', type='json', auth='user') - def get_subordinates(self, employee_id, subordinates_type=None): + def get_subordinates(self, employee_id, subordinates_type=None, **kw): """ Get employee subordinates. Possible values for 'subordinates_type': - 'indirect' - 'direct' """ - - employee = self._check_employee(employee_id) + employee = self._check_employee(employee_id, **kw) if not employee: # to check return {} diff --git a/addons/hr_org_chart/static/src/js/hr_org_chart.js b/addons/hr_org_chart/static/src/js/hr_org_chart.js index c4f200d1ea9..5e2ba861058 100644 --- a/addons/hr_org_chart/static/src/js/hr_org_chart.js +++ b/addons/hr_org_chart/static/src/js/hr_org_chart.js @@ -5,6 +5,7 @@ var AbstractField = require('web.AbstractField'); var concurrency = require('web.concurrency'); var core = require('web.core'); var field_registry = require('web.field_registry'); +var session = require('web.session'); var QWeb = core.qweb; var _t = core._t; @@ -41,7 +42,8 @@ var FieldOrgChart = AbstractField.extend({ return this.dm.add(this._rpc({ route: '/hr/get_org_chart', params: { - employee_id: employee_id + employee_id: employee_id, + context: session.user_context, }, })).then(function (data) { self.orgData = data; @@ -59,7 +61,8 @@ var FieldOrgChart = AbstractField.extend({ route: '/hr/get_subordinates', params: { employee_id: employee_id, - subordinates_type: type + subordinates_type: type, + context: session.user_context, }, })); }, diff --git a/addons/hr_presence/models/hr_employee.py b/addons/hr_presence/models/hr_employee.py index 0fedc553c86..3c27bf4874c 100644 --- a/addons/hr_presence/models/hr_employee.py +++ b/addons/hr_presence/models/hr_employee.py @@ -28,7 +28,7 @@ class ResCompany(models.Model): @api.model def _check_presence(self): - company = self.env.user.company_id + company = self.env.company_id if not company.hr_presence_last_compute_date or \ company.hr_presence_last_compute_date.day != Datetime.now().day: self.env['hr.employee'].search([ diff --git a/addons/hr_recruitment/models/hr_job.py b/addons/hr_recruitment/models/hr_job.py index a7c13066500..50f63374447 100644 --- a/addons/hr_recruitment/models/hr_job.py +++ b/addons/hr_recruitment/models/hr_job.py @@ -10,7 +10,7 @@ class Job(models.Model): @api.model def _default_address_id(self): - return self.env.user.company_id.partner_id + return self.env.company_id.partner_id def _get_default_favorite_user_ids(self): return [(6, 0, [self.env.uid])] diff --git a/addons/hr_recruitment/models/hr_recruitment.py b/addons/hr_recruitment/models/hr_recruitment.py index 87b93a7a165..4c9c6f63f5b 100644 --- a/addons/hr_recruitment/models/hr_recruitment.py +++ b/addons/hr_recruitment/models/hr_recruitment.py @@ -110,7 +110,7 @@ class Applicant(models.Model): department = self.env['hr.department'].browse(self._context['default_department_id']) company_id = department.company_id.id if not company_id: - company_id = self.env['res.company']._company_default_get('hr.applicant') + company_id = self.env.company_id return company_id name = fields.Char("Subject / Application Name", required=True) diff --git a/addons/hr_recruitment/security/hr_recruitment_security.xml b/addons/hr_recruitment/security/hr_recruitment_security.xml index 85949b967dd..50d5f825ca4 100644 --- a/addons/hr_recruitment/security/hr_recruitment_security.xml +++ b/addons/hr_recruitment/security/hr_recruitment_security.xml @@ -10,7 +10,7 @@ Applicant multi company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] diff --git a/addons/hr_timesheet/models/hr_timesheet.py b/addons/hr_timesheet/models/hr_timesheet.py index 7d1edf4b2b0..c7f31dee0bb 100644 --- a/addons/hr_timesheet/models/hr_timesheet.py +++ b/addons/hr_timesheet/models/hr_timesheet.py @@ -90,7 +90,7 @@ class AccountAnalyticLine(models.Model): @api.model def _apply_timesheet_label(self, view_arch): doc = etree.XML(view_arch) - encoding_uom = self.env.user.company_id.timesheet_encode_uom_id + encoding_uom = self.env.company_id.timesheet_encode_uom_id # Here, we select only the unit_amount field having no string set to give priority to # custom inheretied view stored in database. Even if normally, no xpath can be done on # 'string' attribute. @@ -159,7 +159,7 @@ class AccountAnalyticLine(models.Model): cost = timesheet.employee_id.timesheet_cost or 0.0 amount = -timesheet.unit_amount * cost amount_converted = timesheet.employee_id.currency_id._convert( - amount, timesheet.account_id.currency_id, self.env.user.company_id, timesheet.date) + amount, timesheet.account_id.currency_id, self.env.company_id, timesheet.date) result[timesheet.id].update({ 'amount': amount_converted, }) diff --git a/addons/hr_timesheet/models/ir_http.py b/addons/hr_timesheet/models/ir_http.py index a0694d71d1b..d20ad2f9d7a 100644 --- a/addons/hr_timesheet/models/ir_http.py +++ b/addons/hr_timesheet/models/ir_http.py @@ -13,7 +13,7 @@ class Http(models.AbstractModel): """ result = super(Http, self).session_info() - company = self.env.user.company_id + company = self.env.company_id encoding_uom = company.timesheet_encode_uom_id result['timesheet_uom'] = encoding_uom.read(['name', 'rounding', 'timesheet_widget'])[0] diff --git a/addons/hr_timesheet/models/project.py b/addons/hr_timesheet/models/project.py index 94f94e13f1d..9a554313cca 100644 --- a/addons/hr_timesheet/models/project.py +++ b/addons/hr_timesheet/models/project.py @@ -49,7 +49,7 @@ class Project(models.Model): if allow_timesheets and not values.get('analytic_account_id'): analytic_account = self.env['account.analytic.account'].create({ 'name': values.get('name', _('Unknown Analytic Account')), - 'company_id': values.get('company_id', self.env.user.company_id.id), + 'company_id': values.get('company_id', self.env.company_id.id), 'partner_id': values.get('partner_id'), 'active': True, }) diff --git a/addons/iap/models/iap.py b/addons/iap/models/iap.py index af375d5050b..122aab66b35 100644 --- a/addons/iap/models/iap.py +++ b/addons/iap/models/iap.py @@ -158,11 +158,11 @@ class IapAccount(models.Model): service_name = fields.Char() account_token = fields.Char(default=lambda s: uuid.uuid4().hex) - company_id = fields.Many2one('res.company', default=lambda self: self.env.user.company_id) + company_id = fields.Many2one('res.company', default=lambda self: self.env.company_id) @api.model def get(self, service_name, force_create=True): - account = self.search([('service_name', '=', service_name), ('company_id', 'in', [self.env.user.company_id.id, False])]) + account = self.search([('service_name', '=', service_name), ('company_id', 'in', [self.env.company_id.id, False])]) if not account and force_create: account = self.create({'service_name': service_name}) # Since the account did not exist yet, we will encounter a NoCreditError, diff --git a/addons/iap/security/ir_rule.xml b/addons/iap/security/ir_rule.xml index 2935ce2b746..05e8dcd4b72 100644 --- a/addons/iap/security/ir_rule.xml +++ b/addons/iap/security/ir_rule.xml @@ -5,9 +5,7 @@ - [ - ('company_id', 'in', [user.company_id.id, False]), - ] + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] \ No newline at end of file diff --git a/addons/l10n_de/models/chart_template.py b/addons/l10n_de/models/chart_template.py index 0ba279d14e8..fb830340b33 100644 --- a/addons/l10n_de/models/chart_template.py +++ b/addons/l10n_de/models/chart_template.py @@ -17,7 +17,7 @@ class AccountChartTemplate(models.Model): # Write paperformat and report template used on company def load_for_current_company(self, sale_tax_rate, purchase_tax_rate): res = super(AccountChartTemplate, self).load_for_current_company(sale_tax_rate, purchase_tax_rate) - company = self.env.user.company_id + company = self.env.company_id if company.country_id.code == 'DE': company.write({'external_report_layout_id': self.env.ref('l10n_de.external_layout_din5008').id, 'paperformat_id': self.env.ref('l10n_de.paperformat_euro_din').id}) diff --git a/addons/l10n_do/models/chart_template.py b/addons/l10n_do/models/chart_template.py index 7d85be1847b..892cb8582e5 100644 --- a/addons/l10n_do/models/chart_template.py +++ b/addons/l10n_do/models/chart_template.py @@ -9,7 +9,7 @@ class AccountChartTemplate(models.Model): @api.model def _get_default_bank_journals_data(self): - if self.env.user.company_id.country_id and self.env.user.company_id.country_id.code.upper() == 'DO': + if self.env.company_id.country_id and self.env.company_id.country_id.code.upper() == 'DO': return [ {'acc_name': _('Cash'), 'account_type': 'cash'}, {'acc_name': _('Caja Chica'), 'account_type': 'cash'}, diff --git a/addons/l10n_eu_service/wizard/wizard.py b/addons/l10n_eu_service/wizard/wizard.py index 0a96599a28d..2e90c94ecea 100644 --- a/addons/l10n_eu_service/wizard/wizard.py +++ b/addons/l10n_eu_service/wizard/wizard.py @@ -18,7 +18,7 @@ class l10n_eu_service(models.TransientModel): return eu_group def _get_default_company_id(self): - return self.env.user.company_id.id + return self.env.company_id.id def _default_fiscal_position_id(self): user = self.env.user diff --git a/addons/l10n_fr_certification/data/account_move.xml b/addons/l10n_fr_certification/data/account_move.xml index c4d735d2b14..cb72a999561 100644 --- a/addons/l10n_fr_certification/data/account_move.xml +++ b/addons/l10n_fr_certification/data/account_move.xml @@ -5,7 +5,7 @@ ir.actions.server code - action = env['account.move']._check_hash_integrity(env.user.company_id.id) + action = env['account.move']._check_hash_integrity(env.company_id.id) diff --git a/addons/l10n_fr_certification/models/account.py b/addons/l10n_fr_certification/models/account.py index 208b5238967..a85eaebfebc 100644 --- a/addons/l10n_fr_certification/models/account.py +++ b/addons/l10n_fr_certification/models/account.py @@ -117,7 +117,7 @@ class AccountMove(models.Model): order="l10n_fr_secure_sequence_number ASC") if not moves: - raise UserError(_('There isn\'t any journal entry flagged for data inalterability yet for the company %s. This mechanism only runs for journal entries generated after the installation of the module France - Certification CGI 286 I-3 bis.') % self.env.user.company_id.name) + raise UserError(_('There isn\'t any journal entry flagged for data inalterability yet for the company %s. This mechanism only runs for journal entries generated after the installation of the module France - Certification CGI 286 I-3 bis.') % self.env.company_id.name) previous_hash = u'' start_move_info = [] for move in moves: diff --git a/addons/l10n_fr_fec/wizard/account_fr_fec.py b/addons/l10n_fr_fec/wizard/account_fr_fec.py index 0a6459a0953..0c0ec49558e 100644 --- a/addons/l10n_fr_fec/wizard/account_fr_fec.py +++ b/addons/l10n_fr_fec/wizard/account_fr_fec.py @@ -65,7 +65,7 @@ class AccountFrFec(models.TransientModel): sql_query += ''' AND am.state = 'posted' ''' - company = self.env.user.company_id + company = self.env.company_id formatted_date_from = fields.Date.to_string(self.date_from).replace('-', '') date_from = self.date_from formatted_date_year = date_from.year @@ -108,7 +108,7 @@ class AccountFrFec(models.TransientModel): # 2) CSV files are easier to read/use for a regular accountant. # So it will be easier for the accountant to check the file before # sending it to the fiscal administration - company = self.env.user.company_id + company = self.env.company_id company_legal_data = self._get_company_legal_data(company) header = [ diff --git a/addons/l10n_fr_pos_cert/data/pos_inalterability.xml b/addons/l10n_fr_pos_cert/data/pos_inalterability.xml index 377204b73c6..1026c9b90d2 100644 --- a/addons/l10n_fr_pos_cert/data/pos_inalterability.xml +++ b/addons/l10n_fr_pos_cert/data/pos_inalterability.xml @@ -10,7 +10,7 @@ ir.actions.server code -action = env['pos.order']._check_hash_integrity(env.user.company_id.id) +action = env['pos.order']._check_hash_integrity(env.company_id.id) diff --git a/addons/l10n_fr_pos_cert/models/pos.py b/addons/l10n_fr_pos_cert/models/pos.py index d74641e3c88..89d027b0123 100644 --- a/addons/l10n_fr_pos_cert/models/pos.py +++ b/addons/l10n_fr_pos_cert/models/pos.py @@ -154,7 +154,7 @@ class pos_order(models.Model): order="l10n_fr_secure_sequence_number ASC") if not orders: - raise UserError(_('There isn\'t any order flagged for data inalterability yet for the company %s. This mechanism only runs for point of sale orders generated after the installation of the module France - Certification CGI 286 I-3 bis. - POS') % self.env.user.company_id.name) + raise UserError(_('There isn\'t any order flagged for data inalterability yet for the company %s. This mechanism only runs for point of sale orders generated after the installation of the module France - Certification CGI 286 I-3 bis. - POS') % self.env.company_id.name) previous_hash = u'' start_order_info = [] for order in orders: diff --git a/addons/l10n_fr_sale_closing/security/account_closing_intercompany.xml b/addons/l10n_fr_sale_closing/security/account_closing_intercompany.xml index 6a8215852aa..a316014794e 100644 --- a/addons/l10n_fr_sale_closing/security/account_closing_intercompany.xml +++ b/addons/l10n_fr_sale_closing/security/account_closing_intercompany.xml @@ -2,7 +2,7 @@ Sale Closing multi-company - [('company_id','child_of',[user.company_id.id])] + [('company_id', 'in', company_ids)] diff --git a/addons/l10n_generic_coa/data/account_bank_statement_demo.xml b/addons/l10n_generic_coa/data/account_bank_statement_demo.xml index 3f620cb4bb2..8a34bad5be1 100644 --- a/addons/l10n_generic_coa/data/account_bank_statement_demo.xml +++ b/addons/l10n_generic_coa/data/account_bank_statement_demo.xml @@ -4,7 +4,7 @@ + ('company_id', '=', obj().env.company_id.id)]"/> 8998.2 @@ -18,7 +18,7 @@ + ('company_id', '=', obj().env.company_id.id)]"/> 1275.0 @@ -31,7 +31,7 @@ Bank fees + ('company_id', '=', obj().env.company_id.id)]"/> -32.58 @@ -43,7 +43,7 @@ Prepayment + ('company_id', '=', obj().env.company_id.id)]"/> 650.0 @@ -56,7 +56,7 @@ + ('company_id', '=', obj().env.company_id.id)]"/> 2000.0 @@ -69,7 +69,7 @@ Last Year Interests + ('company_id', '=', obj().env.company_id.id)]"/> 102.78 @@ -81,7 +81,7 @@ + ('company_id', '=', obj().env.company_id.id)]"/> 750.0 diff --git a/addons/l10n_generic_coa/data/account_invoice_demo.xml b/addons/l10n_generic_coa/data/account_invoice_demo.xml index 667c2445054..47cefa73854 100644 --- a/addons/l10n_generic_coa/data/account_invoice_demo.xml +++ b/addons/l10n_generic_coa/data/account_invoice_demo.xml @@ -168,7 +168,7 @@ + ('company_id', '=', obj().env.company_id.id)]"/> @@ -189,12 +189,12 @@ + ('company_id', '=', obj().env.company_id.id)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -209,7 +209,7 @@ + ('company_id', '=', obj().env.company_id.id)]"/> diff --git a/addons/l10n_in/data/account_invoice_demo.xml b/addons/l10n_in/data/account_invoice_demo.xml index 9fa88d1a6ad..a740c459694 100644 --- a/addons/l10n_in/data/account_invoice_demo.xml +++ b/addons/l10n_in/data/account_invoice_demo.xml @@ -23,7 +23,7 @@ eval="[(6, 0, obj().search([ ('type_tax_use', '=', 'sale'), ('children_tax_ids.amount','=', 14), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -37,7 +37,7 @@ eval="[(6, 0, obj().search([ ('type_tax_use', '=', 'sale'), ('children_tax_ids.amount','=', 9), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -50,7 +50,7 @@ + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -103,7 +103,7 @@ eval="[(6, 0, obj().search([ ('type_tax_use', '=', 'sale'), ('children_tax_ids.amount','=', 9), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -117,7 +117,7 @@ eval="[(6, 0, obj().search([ ('type_tax_use', '=', 'sale'), ('children_tax_ids.amount','=', 2.5), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -131,7 +131,7 @@ eval="[(6, 0, obj().search([ ('type_tax_use', '=', 'sale'), ('children_tax_ids.amount','=', 2.5), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -164,7 +164,7 @@ ('type_tax_use', '=', 'sale'), ('tax_group_id', '=', obj().env.ref('l10n_in.igst_group').id), ('amount','=', 18), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -187,7 +187,7 @@ eval="obj().search([ ('type', '=', 'sale'), ('l10n_in_import_export', '=', True), - ('company_id', '=', obj().env['res.company']._company_default_get('account.journal').id)], limit=1).id + ('company_id', '=', obj().env.company_id.id)], limit=1).id or obj().search([('type', '=', 'sale')], limit=1).id"/> 999704 @@ -207,7 +207,7 @@ ('type_tax_use', '=', 'sale'), ('tax_group_id', '=', obj().env.ref('l10n_in.igst_group').id), ('amount','=', 18), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -239,7 +239,7 @@ eval="[(6, 0, obj().search([ ('type_tax_use', '=', 'sale'), ('tax_group_id', '=', obj().env.ref('l10n_in.exempt_group').id), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -253,7 +253,7 @@ eval="[(6, 0, obj().search([ ('type_tax_use', '=', 'sale'), ('tax_group_id', '=', obj().env.ref('l10n_in.nil_rated_group').id), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -289,7 +289,7 @@ eval="[(6, 0, obj().search([ ('type_tax_use', '=', 'sale'), ('children_tax_ids.amount','=', 14), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -303,7 +303,7 @@ eval="[(6, 0, obj().search([ ('type_tax_use', '=', 'sale'), ('children_tax_ids.amount','=', 9), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -316,7 +316,7 @@ + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> @@ -389,7 +389,7 @@ eval="[(6, 0, obj().search([ ('type_tax_use', '=', 'sale'), ('children_tax_ids.amount','=', 9), - ('company_id', '=', obj().env['res.company']._company_default_get('account.tax').id)], limit=1).ids)]"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).ids)]"/> diff --git a/addons/l10n_in/data/account_payment_demo.xml b/addons/l10n_in/data/account_payment_demo.xml index 86e881746bf..bc2f31b8bb7 100644 --- a/addons/l10n_in/data/account_payment_demo.xml +++ b/addons/l10n_in/data/account_payment_demo.xml @@ -11,11 +11,11 @@ + ('company_id', '=', obj().env.company_id.id)], limit=1).id"/> + ('company_id', '=', obj().env.company_id.id)], limit=1).inbound_payment_method_ids[0].id"/> diff --git a/addons/l10n_it_edi/models/account_invoice.py b/addons/l10n_it_edi/models/account_invoice.py index b0f801558aa..6b027bc6354 100644 --- a/addons/l10n_it_edi/models/account_invoice.py +++ b/addons/l10n_it_edi/models/account_invoice.py @@ -271,16 +271,16 @@ class AccountInvoice(models.Model): message = self.env['mail.message'].create({ 'subject': _('Sending file: %s') % (self.l10n_it_einvoice_id.name), - 'body': _('Sending file: %s to ES: %s') % (self.l10n_it_einvoice_id.name, self.env.user.company_id.l10n_it_address_recipient_fatturapa), + 'body': _('Sending file: %s to ES: %s') % (self.l10n_it_einvoice_id.name, self.env.company_id.l10n_it_address_recipient_fatturapa), 'author_id': self.env.user.partner_id.id, - 'email_from': self.env.user.company_id.l10n_it_address_send_fatturapa, - 'mail_server_id': self.env.user.company_id.l10n_it_mail_pec_server_id.id, + 'email_from': self.env.company_id.l10n_it_address_send_fatturapa, + 'mail_server_id': self.env.company_id.l10n_it_mail_pec_server_id.id, 'attachment_ids': [(6, 0, self.l10n_it_einvoice_id.ids)], }) mail_fattura = self.env['mail.mail'].create({ 'mail_message_id': message.id, - 'email_to': self.env.user.company_id.l10n_it_address_recipient_fatturapa, + 'email_to': self.env.company_id.l10n_it_address_recipient_fatturapa, }) try: mail_fattura.send(raise_exception=True) @@ -332,15 +332,15 @@ class AccountInvoice(models.Model): if company: self_ctx = self_ctx.with_context(company_id=company.id) else: - company = self.env.user.company_id + company = self.env.company_id if elements: _logger.info(_('Company not found with codice fiscale: %s. The company\'s user is set by default.') % elements[0].text) else: _logger.info(_('Company not found. The company\'s user is set by default.')) if not self.env.user._is_superuser(): - if self.env.user.company_id != company: - raise UserError(_("You can only import invoice concern your current company: %s") % self.env.user.company_id.display_name) + if self.env.company_id != company: + raise UserError(_("You can only import invoice concern your current company: %s") % self.env.company_id.display_name) journal_id = self_ctx._default_journal().id self_ctx = self_ctx.with_context(journal_id=journal_id) @@ -395,7 +395,7 @@ class AccountInvoice(models.Model): if elements: currency_str = elements[0].text currency = self.env.ref('base.%s' % currency_str.upper(), raise_if_not_found=False) - if currency != self.env.user.company_id.currency_id and currency.active: + if currency != self.env.company_id.currency_id and currency.active: invoice_form.currency_id = currency # Date. <2.1.1.3> diff --git a/addons/l10n_nl/models/account_chart_template.py b/addons/l10n_nl/models/account_chart_template.py index 483ce15650c..d7a4a2ae75d 100644 --- a/addons/l10n_nl/models/account_chart_template.py +++ b/addons/l10n_nl/models/account_chart_template.py @@ -9,8 +9,8 @@ class AccountChartTemplate(models.Model): def load_for_current_company(self, sale_tax_rate, purchase_tax_rate): # Add tag to 999999 account res = super(AccountChartTemplate, self).load_for_current_company(sale_tax_rate, purchase_tax_rate) - if self.env.user.company_id.country_id.code == 'NL': - account = self.env['account.account'].search([('code', '=', '999999'), ('company_id', '=', self.env.user.company_id.id)]) + if self.env.company_id.country_id.code == 'NL': + account = self.env['account.account'].search([('code', '=', '999999'), ('company_id', '=', self.env.company_id.id)]) if account: account.tag_ids = [(4, self.env.ref('l10n_nl.account_tag_12').id)] return res diff --git a/addons/lunch/models/lunch_cashmove.py b/addons/lunch/models/lunch_cashmove.py index dab6faccbd1..d04d3b79d32 100644 --- a/addons/lunch/models/lunch_cashmove.py +++ b/addons/lunch/models/lunch_cashmove.py @@ -11,7 +11,7 @@ class LunchCashMove(models.Model): _description = 'Lunch Cashmove' _order = 'date desc' - currency_id = fields.Many2one('res.currency', default=lambda self: self.env['res.company']._company_default_get()) + currency_id = fields.Many2one('res.currency', default=lambda self: self.env.company_id) user_id = fields.Many2one('res.users', 'User', default=lambda self: self.env.uid) date = fields.Date('Date', required=True, default=fields.Date.context_today) diff --git a/addons/lunch/models/lunch_order.py b/addons/lunch/models/lunch_order.py index ee3f01c6d44..ba447ab394e 100644 --- a/addons/lunch/models/lunch_order.py +++ b/addons/lunch/models/lunch_order.py @@ -36,7 +36,7 @@ class LunchOrder(models.Model): ('confirmed', 'Received'), ('cancelled', 'Cancelled')], 'Status', readonly=True, index=True, default='new') - company_id = fields.Many2one('res.company', related='user_id.company_id', store=True) + company_id = fields.Many2one('res.company', default=lambda self: self.env.company_id.id) currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True, store=True) quantity = fields.Float('Quantity', required=True, default=1) diff --git a/addons/lunch/models/lunch_product.py b/addons/lunch/models/lunch_product.py index 6d4132d9bde..5623bce8de1 100644 --- a/addons/lunch/models/lunch_product.py +++ b/addons/lunch/models/lunch_product.py @@ -13,7 +13,7 @@ class LunchProductCategory(models.Model): _description = 'Lunch Product Category' name = fields.Char('Product Category', required=True) - company_id = fields.Many2one('res.company', default=lambda self: self.env['res.company']._company_default_get()) + company_id = fields.Many2one('res.company', default=lambda self: self.env.company_id) currency_id = fields.Many2one('res.currency', related='company_id.currency_id') topping_label_1 = fields.Char('Topping Label 1', required=True, default='Supplements') topping_label_2 = fields.Char('Topping Label 2', required=True, default='Beverages') @@ -60,14 +60,14 @@ class LunchTopping(models.Model): _description = 'Lunch Toppings' name = fields.Char('Name', required=True) - company_id = fields.Many2one('res.company', default=lambda self: self.env['res.company']._company_default_get()) + company_id = fields.Many2one('res.company', default=lambda self: self.env.company_id) currency_id = fields.Many2one('res.currency', related='company_id.currency_id') price = fields.Float('Price', digits=dp.get_precision('Account'), required=True) category_id = fields.Many2one('lunch.product.category') topping_category = fields.Integer('Topping Category', help="This field is a technical field", required=True, default=1) def name_get(self): - currency_id = self.env.user.company_id.currency_id + currency_id = self.env.company_id.currency_id res = dict(super(LunchTopping, self).name_get()) for topping in self: price = formatLang(self.env, topping.price, currency_obj=currency_id) @@ -88,7 +88,7 @@ class LunchProduct(models.Model): supplier_id = fields.Many2one('lunch.supplier', 'Vendor', required=True) active = fields.Boolean(default=True) - company_id = fields.Many2one('res.company', default=lambda self: self.env['res.company']._company_default_get()) + company_id = fields.Many2one('res.company', default=lambda self: self.env.company_id) currency_id = fields.Many2one('res.currency', related='company_id.currency_id') # image: all image fields are base64 encoded and PIL-supported diff --git a/addons/lunch/wizard/lunch_line_wizard.py b/addons/lunch/wizard/lunch_line_wizard.py index 2006144e582..989d3a0acc8 100644 --- a/addons/lunch/wizard/lunch_line_wizard.py +++ b/addons/lunch/wizard/lunch_line_wizard.py @@ -21,7 +21,7 @@ class LunchOrderWizard(models.TransientModel): order="date desc, id desc", limit=1) return last_time_ordered - currency_id = fields.Many2one('res.currency', default=lambda self: self.env.user.company_id.currency_id) + currency_id = fields.Many2one('res.currency', default=lambda self: self.env.company_id.currency_id) product_id = fields.Many2one('lunch.product', string='Product ID') product_description = fields.Text('Description', related='product_id.description') diff --git a/addons/mail/controllers/main.py b/addons/mail/controllers/main.py index 6b8cf59ccdc..611db76e980 100644 --- a/addons/mail/controllers/main.py +++ b/addons/mail/controllers/main.py @@ -52,6 +52,7 @@ class MailController(http.Controller): # access_token and kwargs are used in the portal controller override for the Send by email or Share Link # to give access to the record to a recipient that has normally no access. uid = request.session.uid + user = request.env['res.users'].sudo().browse(uid) # no model / res_id, meaning no possible record -> redirect to login if not model or not res_id or model not in request.env: @@ -69,7 +70,33 @@ class MailController(http.Controller): if not RecordModel.sudo(uid).check_access_rights('read', raise_exception=False): return cls._redirect_to_messaging() try: - record_sudo.sudo(uid).check_access_rule('read') + # We need here to extend the "allowed_company_ids" to allow a redirection + # to any record that the user can access, regardless of currently visible + # records based on the "currently allowed companies". + cids = request.httprequest.cookies.get('cids', str(request.env.user.company_id)) + cids = [int(cid) for cid in cids.split(',')] + try: + record_sudo.sudo(uid).with_context(allowed_company_ids=cids).check_access_rule('read') + except AccessError: + # In case the allowed_company_ids from the cookies (i.e. the last user configuration + # on his browser) is not sufficient to avoid an ir.rule access error, try to following + # heuristic: + # - Guess the supposed necessary company to access the record via the method + # _get_mail_redirect_suggested_company + # - If no company, then redirect to the messaging + # - If the multi company per tag group is activated, merge the suggested company + # withe the companies on the cookie + # - else, use this company as enabled company + # - Make a new access test if it succeeds, redirect to the record. Otherwise, + # redirect to the messaging. + suggested_company = record_sudo._get_mail_redirect_suggested_company() + if not suggested_company: + raise AccessError() + if user.has_group('base.group_toggle_company'): + cids += [suggested_company] + else: + cids = [suggested_company] + record_sudo.sudo(uid).with_context(allowed_company_ids=cids).check_access_rule('read') except AccessError: return cls._redirect_to_messaging() else: @@ -98,6 +125,7 @@ class MailController(http.Controller): if view_id: url_params['view_id'] = view_id + url_params['cids'] = ','.join([str(cid) for cid in cids]) url = '/web?#%s' % url_encode(url_params) return werkzeug.utils.redirect(url) diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index ba3108d61f6..f59f26e0a66 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -1225,7 +1225,7 @@ class Message(models.Model): if self.env.user.partner_id.email: email_from = formataddr((self.env.user.partner_id.name, self.env.user.partner_id.email)) else: - email_from = self.env.user.company_id.catchall + email_from = self.env.company_id.catchall body_html = tools.append_content_to_html('
%s
' % tools.ustr(comment), msg.body) vals = { diff --git a/addons/mail/models/mail_template.py b/addons/mail/models/mail_template.py index 5a6d21b825f..c3caa10c33b 100644 --- a/addons/mail/models/mail_template.py +++ b/addons/mail/models/mail_template.py @@ -535,7 +535,7 @@ class MailTemplate(models.Model): template_ctx = { 'message': self.env['mail.message'].sudo().new(dict(body=values['body_html'], record_name=record.display_name)), 'model_description': self.env['ir.model']._get(record._name).display_name, - 'company': 'company_id' in record and record['company_id'] or self.env.user.company_id, + 'company': 'company_id' in record and record['company_id'] or self.env.company_id, } body = template.render(template_ctx, engine='ir.qweb', minimal_qcontext=True) values['body_html'] = self.env['mail.thread']._replace_local_links(body) diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 81f1dc0510b..dc8e2db4a62 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -867,7 +867,7 @@ class MailThread(models.AbstractModel): result_email.update(dict((rid, '%s@%s' % (catchall, alias_domain)) for rid in left_ids)) # compute name of reply-to - TDE tocheck: quotes and stuff like that - company_name = company.name if company else self.env.user.company_id.name + company_name = company.name if company else self.env.company_id.name for res_id in result_email.keys(): name = '%s%s%s' % (company_name, ' ' if doc_names.get(res_id) else '', doc_names.get(res_id, '')) result[res_id] = formataddr((name, result_email[res_id])) @@ -1260,7 +1260,7 @@ class MailThread(models.AbstractModel): body = self.env.ref('mail.mail_bounce_catchall').render({ 'message': message, }, engine='ir.qweb') - self._routing_create_bounce_email(email_from, body, message, reply_to=self.env.user.company_id.email) + self._routing_create_bounce_email(email_from, body, message, reply_to=self.env.company_id.email) return [] dest_aliases = Alias.search([('alias_name', 'in', rcpt_tos_localparts)]) @@ -2435,3 +2435,17 @@ class MailThread(models.AbstractModel): self._message_auto_subscribe_notify(pids, template) return True + + def _get_mail_redirect_suggested_company(self): + """ Return the suggested company to be set on the context + in case of a mail redirection to the record. To avoid multi + company issues when clicking on a link sent by email, this + could be called to try setting the most suited company on + the allowed_company_ids in the context. This method can be + overriden, for example on the hr.leave model, where the + most suited company is the company of the leave type, as + specified by the ir.rule. + """ + if 'company_id' in self: + return self.company_id + return False diff --git a/addons/maintenance/models/maintenance.py b/addons/maintenance/models/maintenance.py index 6f7ace29554..4961b367fbf 100644 --- a/addons/maintenance/models/maintenance.py +++ b/addons/maintenance/models/maintenance.py @@ -32,7 +32,7 @@ class MaintenanceEquipmentCategory(models.Model): name = fields.Char('Category Name', required=True, translate=True) company_id = fields.Many2one('res.company', string='Company', - default=lambda self: self.env.user.company_id) + default=lambda self: self.env.company_id) technician_user_id = fields.Many2one('res.users', 'Responsible', tracking=True, default=lambda self: self.env.uid, oldname='user_id') color = fields.Integer('Color Index') note = fields.Text('Comments', translate=True) @@ -123,7 +123,7 @@ class MaintenanceEquipment(models.Model): name = fields.Char('Equipment Name', required=True, translate=True) company_id = fields.Many2one('res.company', string='Company', - default=lambda self: self.env.user.company_id) + default=lambda self: self.env.company_id) active = fields.Boolean(default=True) technician_user_id = fields.Many2one('res.users', string='Technician', tracking=True, oldname='user_id') owner_user_id = fields.Many2one('res.users', string='Owner', tracking=True) @@ -277,14 +277,14 @@ class MaintenanceRequest(models.Model): def _get_default_team_id(self): MT = self.env['maintenance.team'] - team = MT.search([('company_id', '=', self.env.user.company_id.id)], limit=1) + team = MT.search([('company_id', '=', self.env.company_id.id)], limit=1) if not team: team = MT.search([], limit=1) return team.id name = fields.Char('Subjects', required=True) company_id = fields.Many2one('res.company', string='Company', - default=lambda self: self.env.user.company_id) + default=lambda self: self.env.company_id) description = fields.Text('Description') request_date = fields.Date('Request Date', tracking=True, default=fields.Date.context_today, help="Date requested for the maintenance to happen") @@ -404,7 +404,7 @@ class MaintenanceTeam(models.Model): name = fields.Char(required=True, translate=True) active = fields.Boolean(default=True) company_id = fields.Many2one('res.company', string='Company', - default=lambda self: self.env.user.company_id) + default=lambda self: self.env.company_id) member_ids = fields.Many2many('res.users', 'maintenance_team_users_rel', string="Team Members") color = fields.Integer("Color Index", default=0) request_ids = fields.One2many('maintenance.request', 'maintenance_team_id', copy=False) diff --git a/addons/maintenance/security/maintenance.xml b/addons/maintenance/security/maintenance.xml index 75a53c685d3..047c5c9ef45 100644 --- a/addons/maintenance/security/maintenance.xml +++ b/addons/maintenance/security/maintenance.xml @@ -41,28 +41,28 @@ Maintenance Request Multi-company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Maintenance Equipment Multi-company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Maintenance Team Multi-company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] Maintenance Equipment Category Multi-company rule - ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + ['|',('company_id','=',False),('company_id', 'in', company_ids)] diff --git a/addons/maintenance/tests/test_maintenance_multicompany.py b/addons/maintenance/tests/test_maintenance_multicompany.py index e9c3df06e54..39b4be27a8d 100644 --- a/addons/maintenance/tests/test_maintenance_multicompany.py +++ b/addons/maintenance/tests/test_maintenance_multicompany.py @@ -34,10 +34,10 @@ class TestEquipmentMulticompany(TransactionCase): company_b = ResCompany.create({ 'name': 'Company B', 'currency_id': self.env.ref('base.USD').id, - 'parent_id': company_a.id, }) # Create equipment manager. + cids = [company_a.id, company_b.id] equipment_manager = ResUsers.create({ 'name': 'Equipment Manager', 'company_id': company_a.id, @@ -63,7 +63,7 @@ class TestEquipmentMulticompany(TransactionCase): 'company_id': company_a.id, }) # create a maintenance team for company B user - teamb = MaintenanceTeam.sudo(equipment_manager).create({ + teamb = MaintenanceTeam.sudo(equipment_manager).with_context(allowed_company_ids=cids).create({ 'name': 'Subcontractor', 'company_id': company_b.id, }) @@ -77,14 +77,14 @@ class TestEquipmentMulticompany(TransactionCase): }) # create equipment category for equipment manager - category_1 = Category.sudo(equipment_manager).create({ + category_1 = Category.sudo(equipment_manager).with_context(allowed_company_ids=cids).create({ 'name': 'Monitors', 'company_id': company_b.id, 'technician_user_id': equipment_manager.id, }) # create equipment category for equipment manager - Category.sudo(equipment_manager).create({ + Category.sudo(equipment_manager).with_context(allowed_company_ids=cids).create({ 'name': 'Computers', 'company_id': company_b.id, 'technician_user_id': equipment_manager.id, @@ -98,7 +98,7 @@ class TestEquipmentMulticompany(TransactionCase): }) # Check category for user equipment_manager and user - self.assertEquals(Category.sudo(equipment_manager).search_count([]), 3) + self.assertEquals(Category.sudo(equipment_manager).with_context(allowed_company_ids=cids).search_count([]), 3) self.assertEquals(Category.sudo(user).search_count([]), 2) # User should not able to create equipment. @@ -111,16 +111,16 @@ class TestEquipmentMulticompany(TransactionCase): 'owner_user_id': user.id, }) - Equipment.sudo(equipment_manager).create({ - 'name': 'Acer Laptop', - 'category_id': category_1.id, - 'assign_date': time.strftime('%Y-%m-%d'), - 'company_id': company_b.id, - 'owner_user_id': user.id, - }) + Equipment.sudo(equipment_manager).with_context(allowed_company_ids=cids).create({ + 'name': 'Acer Laptop', + 'category_id': category_1.id, + 'assign_date': time.strftime('%Y-%m-%d'), + 'company_id': company_b.id, + 'owner_user_id': user.id, + }) # create an equipment for user - Equipment.sudo(equipment_manager).create({ + Equipment.sudo(equipment_manager).with_context(allowed_company_ids=cids).create({ 'name': 'HP Laptop', 'category_id': category_1.id, 'assign_date': time.strftime('%Y-%m-%d'), @@ -128,7 +128,7 @@ class TestEquipmentMulticompany(TransactionCase): 'owner_user_id': equipment_manager.id, }) # Now there are total 2 equipments created and can view by equipment_manager user - self.assertEquals(Equipment.sudo(equipment_manager).search_count([]), 2) + self.assertEquals(Equipment.sudo(equipment_manager).with_context(allowed_company_ids=cids).search_count([]), 2) # And there is total 1 equipment can be view by Normal User ( Which user is followers) self.assertEquals(Equipment.sudo(user).search_count([]), 1) @@ -171,5 +171,5 @@ class TestEquipmentMulticompany(TransactionCase): }) # Now here is total 1 maintenance request can be view by Normal User - self.assertEquals(MaintenanceRequest.sudo(equipment_manager).search_count([]), 2) + self.assertEquals(MaintenanceRequest.sudo(equipment_manager).with_context(allowed_company_ids=cids).search_count([]), 2) self.assertEquals(MaintenanceRequest.sudo(user).search_count([]), 1) diff --git a/addons/mrp/models/mrp_bom.py b/addons/mrp/models/mrp_bom.py index 4aa6117ac35..35469a354f1 100644 --- a/addons/mrp/models/mrp_bom.py +++ b/addons/mrp/models/mrp_bom.py @@ -59,7 +59,7 @@ class MrpBom(models.Model): "to define stock rules which trigger different manufacturing orders with different BoMs.") company_id = fields.Many2one( 'res.company', 'Company', - default=lambda self: self.env['res.company']._company_default_get('mrp.bom'), + default=lambda self: self.env.company_id, required=True) consumption = fields.Selection([ ('strict', 'Strict'), diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 86ddf6bc6fc..dee10ac4f15 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -23,7 +23,7 @@ class MrpProduction(models.Model): def _get_default_picking_type(self): return self.env['stock.picking.type'].search([ ('code', '=', 'mrp_operation'), - ('warehouse_id.company_id', 'in', [self.env.context.get('company_id', self.env.user.company_id.id), False])], + ('warehouse_id.company_id', 'in', [self.env.context.get('company_id', self.env.company_id.id), False])], limit=1).id @api.model @@ -36,7 +36,7 @@ class MrpProduction(models.Model): try: location.check_access_rule('read') except (AttributeError, AccessError): - location = self.env['stock.warehouse'].search([('company_id', '=', self.env.user.company_id.id)], limit=1).lot_stock_id + location = self.env['stock.warehouse'].search([('company_id', '=', self.env.company_id.id)], limit=1).lot_stock_id return location and location.id or False @api.model @@ -49,7 +49,7 @@ class MrpProduction(models.Model): try: location.check_access_rule('read') except (AttributeError, AccessError): - location = self.env['stock.warehouse'].search([('company_id', '=', self.env.user.company_id.id)], limit=1).lot_stock_id + location = self.env['stock.warehouse'].search([('company_id', '=', self.env.company_id.id)], limit=1).lot_stock_id return location and location.id or False name = fields.Char( @@ -180,7 +180,7 @@ class MrpProduction(models.Model): user_id = fields.Many2one('res.users', 'Responsible', default=lambda self: self._uid) company_id = fields.Many2one( 'res.company', 'Company', - default=lambda self: self.env['res.company']._company_default_get('mrp.production'), + default=lambda self: self.env.company_id, required=True) qty_produced = fields.Float(compute="_get_produced_qty", string="Quantity Produced") @@ -420,7 +420,7 @@ class MrpProduction(models.Model): try: location.check_access_rule('read') except (AttributeError, AccessError): - location = self.env['stock.warehouse'].search([('company_id', '=', self.env.user.company_id.id)], limit=1).lot_stock_id + location = self.env['stock.warehouse'].search([('company_id', '=', self.env.company_id.id)], limit=1).lot_stock_id self.move_raw_ids.update({'picking_type_id': self.picking_type_id}) self.location_src_id = self.picking_type_id.default_location_src_id.id or location.id self.location_dest_id = self.picking_type_id.default_location_dest_id.id or location.id diff --git a/addons/mrp/models/mrp_routing.py b/addons/mrp/models/mrp_routing.py index 3c907802074..e2149c8b516 100644 --- a/addons/mrp/models/mrp_routing.py +++ b/addons/mrp/models/mrp_routing.py @@ -22,7 +22,7 @@ class MrpRouting(models.Model): copy=True, oldname='workcenter_lines') company_id = fields.Many2one( 'res.company', 'Company', - default=lambda self: self.env['res.company']._company_default_get('mrp.routing')) + default=lambda self: self.env.company_id) @api.model def create(self, vals): diff --git a/addons/mrp/models/mrp_unbuild.py b/addons/mrp/models/mrp_unbuild.py index 2bac0c1d0f7..0b907d38d37 100644 --- a/addons/mrp/models/mrp_unbuild.py +++ b/addons/mrp/models/mrp_unbuild.py @@ -18,7 +18,7 @@ class MrpUnbuild(models.Model): stock_location.check_access_rule('read') return stock_location.id except (AttributeError, AccessError): - return self.env['stock.warehouse'].search([('company_id', '=', self.env.user.company_id.id)], limit=1).lot_stock_id.id + return self.env['stock.warehouse'].search([('company_id', '=', self.env.company_id.id)], limit=1).lot_stock_id.id def _get_default_location_dest_id(self): stock_location = self.env.ref('stock.stock_location_stock', raise_if_not_found=False) @@ -26,7 +26,7 @@ class MrpUnbuild(models.Model): stock_location.check_access_rule('read') return stock_location.id except (AttributeError, AccessError): - return self.env['stock.warehouse'].search([('company_id', '=', self.env.user.company_id.id)], limit=1).lot_stock_id.id + return self.env['stock.warehouse'].search([('company_id', '=', self.env.company_id.id)], limit=1).lot_stock_id.id name = fields.Char('Reference', copy=False, readonly=True, default=lambda x: _('New')) product_id = fields.Many2one( diff --git a/addons/mrp/report/mrp_report_bom_structure.py b/addons/mrp/report/mrp_report_bom_structure.py index b95c1bcf658..1ac6cee9dce 100644 --- a/addons/mrp/report/mrp_report_bom_structure.py +++ b/addons/mrp/report/mrp_report_bom_structure.py @@ -58,7 +58,7 @@ class ReportBomStructure(models.AbstractModel): lines = self._get_operation_line(bom.routing_id, float_round(qty / bom.product_qty, precision_rounding=1, rounding_method='UP'), level) values = { 'bom_id': bom_id, - 'currency': self.env.user.company_id.currency_id, + 'currency': self.env.company_id.currency_id, 'operations': lines, } return self.env.ref('mrp.report_mrp_operation_line').render({'data': values}) @@ -111,7 +111,7 @@ class ReportBomStructure(models.AbstractModel): 'bom': bom, 'bom_qty': bom_quantity, 'bom_prod_name': product.display_name, - 'currency': self.env.user.company_id.currency_id, + 'currency': self.env.company_id.currency_id, 'product': product, 'code': bom and bom.display_name or '', 'price': product.uom_id._compute_price(product.standard_price, bom.product_uom_id) * bom_quantity, @@ -140,14 +140,14 @@ class ReportBomStructure(models.AbstractModel): sub_total = self._get_price(line.child_bom_id, factor, line.product_id) else: sub_total = price - sub_total = self.env.user.company_id.currency_id.round(sub_total) + sub_total = self.env.company_id.currency_id.round(sub_total) components.append({ 'prod_id': line.product_id.id, 'prod_name': line.product_id.display_name, 'code': line.child_bom_id and line.child_bom_id.display_name or '', 'prod_qty': line_quantity, 'prod_uom': line.product_uom_id.name, - 'prod_cost': self.env.user.company_id.currency_id.round(price), + 'prod_cost': self.env.company_id.currency_id.round(price), 'parent_id': bom.id, 'line_id': line.id, 'level': level or 0, @@ -173,7 +173,7 @@ class ReportBomStructure(models.AbstractModel): 'operation': operation, 'name': operation.name + ' - ' + operation.workcenter_id.name, 'duration_expected': duration_expected, - 'total': self.env.user.company_id.currency_id.round(total), + 'total': self.env.company_id.currency_id.round(total), }) return operations @@ -200,7 +200,7 @@ class ReportBomStructure(models.AbstractModel): else: prod_qty = line.product_qty * factor not_rounded_price = line.product_id.uom_id._compute_price(line.product_id.standard_price, line.product_uom_id) * prod_qty - price += self.env.user.company_id.currency_id.round(not_rounded_price) + price += self.env.company_id.currency_id.round(not_rounded_price) return price def _get_pdf_line(self, bom_id, product_id=False, qty=1, child_bom_ids=[], unfolded=False): diff --git a/addons/mrp/security/mrp_security.xml b/addons/mrp/security/mrp_security.xml index cc5a3562435..6c346375b9f 100644 --- a/addons/mrp/security/mrp_security.xml +++ b/addons/mrp/security/mrp_security.xml @@ -35,35 +35,35 @@ mrp_production multi-company - ['|',('company_id','child_of',[user.company_id.id]),('company_id','=',False)] + ['|',('company_id', 'in', company_ids),('company_id','=',False)] mrp_workcenter multi-company - ['|',('company_id','child_of',[user.company_id.id]),('company_id','=',False)] + ['|',('company_id', 'in', company_ids),('company_id','=',False)] mrp_bom multi-company - ['|',('company_id','child_of',[user.company_id.id]),('company_id','=',False)] + ['|',('company_id', 'in', company_ids),('company_id','=',False)] mrp_routing multi-company - ['|',('company_id','child_of',[user.company_id.id]),('company_id','=',False)] + ['|',('company_id', 'in', company_ids),('company_id','=',False)] mrp_routing_workcenter multi-company - ['|',('company_id','child_of',[user.company_id.id]),('company_id','=',False)] + ['|',('company_id', 'in', company_ids),('company_id','=',False)] diff --git a/addons/mrp_subcontracting/models/res_partner.py b/addons/mrp_subcontracting/models/res_partner.py index d4d565120e6..08cac056884 100644 --- a/addons/mrp_subcontracting/models/res_partner.py +++ b/addons/mrp_subcontracting/models/res_partner.py @@ -49,7 +49,7 @@ class ResPartner(models.Model): def write(self, vals): if vals.get('type') == 'subcontractor': - subcontracting_location = self.env.user.company_id.subcontracting_location_id + subcontracting_location = self.env.company_id.subcontracting_location_id if not vals.get('property_stock_supplier') and not vals.get('property_stock_customer'): vals['property_stock_supplier'] = subcontracting_location.id vals['property_stock_customer'] = subcontracting_location.id diff --git a/addons/pad/models/pad.py b/addons/pad/models/pad.py index 6e3476099fd..22cfe84af72 100644 --- a/addons/pad/models/pad.py +++ b/addons/pad/models/pad.py @@ -22,7 +22,7 @@ class PadCommon(models.AbstractModel): @api.model def pad_is_configured(self): - return bool(self.env.user.company_id.pad_server) + return bool(self.env.company_id.pad_server) @api.model def pad_generate_url(self): diff --git a/addons/partner_autocomplete/models/res_partner.py b/addons/partner_autocomplete/models/res_partner.py index 9d357fec6d8..a15d1626258 100644 --- a/addons/partner_autocomplete/models/res_partner.py +++ b/addons/partner_autocomplete/models/res_partner.py @@ -90,8 +90,8 @@ class ResPartner(models.Model): params.update({ 'db_uuid': self.env['ir.config_parameter'].sudo().get_param('database.uuid'), 'account_token': account.account_token, - 'country_code': self.env.user.company_id.country_id.code, - 'zip': self.env.user.company_id.zip, + 'country_code': self.env.company_id.country_id.code, + 'zip': self.env.company_id.zip, }) try: return jsonrpc(url=url, params=params, timeout=timeout), False diff --git a/addons/partner_autocomplete/static/src/js/partner_autocomplete_fieldchar.js b/addons/partner_autocomplete/static/src/js/partner_autocomplete_fieldchar.js index f1dd023b885..c1fab81a194 100644 --- a/addons/partner_autocomplete/static/src/js/partner_autocomplete_fieldchar.js +++ b/addons/partner_autocomplete/static/src/js/partner_autocomplete_fieldchar.js @@ -127,9 +127,6 @@ var FieldAutocomplete = FieldChar.extend(AutocompleteMixin, { }); } - self._setOne2ManyField('child_ids', data.company.child_ids); - delete data.company.child_ids; - self._setOne2ManyField('bank_ids', data.company.bank_ids); delete data.company.bank_ids; diff --git a/addons/payment/controllers/portal.py b/addons/payment/controllers/portal.py index 55a4d08e4b9..3d9ac23861b 100644 --- a/addons/payment/controllers/portal.py +++ b/addons/payment/controllers/portal.py @@ -106,7 +106,7 @@ class WebsitePayment(http.Controller): def payment_method(self, **kwargs): acquirers = list(request.env['payment.acquirer'].search([ ('website_published', '=', True), ('registration_view_template_id', '!=', False), - ('payment_flow', '=', 's2s'), ('company_id', '=', request.env.user.company_id.id) + ('payment_flow', '=', 's2s'), ('company_id', '=', request.env.company_id.id) ])) partner = request.env.user.partner_id payment_tokens = partner.payment_token_ids diff --git a/addons/payment/models/payment_acquirer.py b/addons/payment/models/payment_acquirer.py index 9de056039df..087899880f2 100644 --- a/addons/payment/models/payment_acquirer.py +++ b/addons/payment/models/payment_acquirer.py @@ -72,7 +72,7 @@ class PaymentAcquirer(models.Model): default='manual', required=True) company_id = fields.Many2one( 'res.company', 'Company', - default=lambda self: self.env.user.company_id.id, required=True) + default=lambda self: self.env.company_id.id, required=True) view_template_id = fields.Many2one( 'ir.ui.view', 'Form Button Template', default=_get_default_view_template_id) @@ -267,7 +267,7 @@ class PaymentAcquirer(models.Model): acquirer_names = [a.name.split('_')[1] for a in acquirer_modules] # Search for acquirers having no journal - company = company or self.env.user.company_id + company = company or self.env.company_id acquirers = self.env['payment.acquirer'].search( [('provider', 'in', acquirer_names), ('journal_id', '=', False), ('company_id', '=', company.id)]) @@ -328,7 +328,7 @@ class PaymentAcquirer(models.Model): * pms: record set of stored credit card data (aka payment.token) connected to a given partner to allow customers to reuse them """ if not company: - company = self.env.user.company_id + company = self.env.company_id if not partner: partner = self.env.user.partner_id active_acquirers = self.sudo().search([('website_published', '=', True), ('company_id', '=', company.id)]) @@ -384,7 +384,7 @@ class PaymentAcquirer(models.Model): if currency_id: currency = self.env['res.currency'].browse(currency_id) else: - currency = self.env.user.company_id.currency_id + currency = self.env.company_id.currency_id values['currency'] = currency # Fill partner_* using values['partner_id'] or partner_id argument @@ -569,7 +569,7 @@ class PaymentTransaction(models.Model): @api.model def _get_default_partner_country_id(self): - return self.env['res.company']._company_default_get('payment.transaction').country_id.id + return self.env.company_id.country_id.id date = fields.Datetime('Validation Date', readonly=True) acquirer_id = fields.Many2one('payment.acquirer', string='Acquirer', readonly=True, required=True) diff --git a/addons/payment/models/res_company.py b/addons/payment/models/res_company.py index de21668f496..a98ea1aac14 100644 --- a/addons/payment/models/res_company.py +++ b/addons/payment/models/res_company.py @@ -20,7 +20,7 @@ class ResCompany(models.Model): def action_open_payment_onboarding_payment_acquirer(self): """ Called by onboarding panel above the customer invoice list.""" # Fail if there are no existing accounts - self.env.user.company_id.get_chart_of_accounts_or_fail() + self.env.company_id.get_chart_of_accounts_or_fail() action = self.env.ref('payment.action_open_payment_onboarding_payment_acquirer_wizard').read()[0] return action diff --git a/addons/payment/views/payment_portal_templates.xml b/addons/payment/views/payment_portal_templates.xml index c6a81cbe55b..2b0c147260e 100644 --- a/addons/payment/views/payment_portal_templates.xml +++ b/addons/payment/views/payment_portal_templates.xml @@ -33,7 +33,7 @@