Tuesday, August 26, 2025
20 changes · saas-18.2
Enhancements to existing features
This update speeds up accounting localization test runs by temporarily adding database indexes during heavy account cleanup. It reduces test infrastructure time and load without changing customer-facing accounting behavior.
Original PR description
During the second half of `test_all_l10n`, we keep deleting `account.account` records (hundreds to low thousand every iteration). This deletion turns out to account (heh) for about 15% of the test's…
During the second half of `test_all_l10n`, we keep deleting `account.account` records (hundreds to low thousand every iteration). This deletion turns out to account (heh) for about 15% of the test's run time running locally (5mn out of 30). And per the explain, this is largely from executing `ON DELETE` constraints: since accounts are rarely deleted, the forward-only M2Os (used to go from a record to an account) are not generally indexes, which causes a full scan of the non-account table on deletion of accounts, which... can be quite slow if the non-account table is large, e.g. sample `EXPLAIN ANALYZE` for one of the `DELETE FROM account_account`:
Trigger for constraint account_fiscal_position_account_account_src_id_fkey on account_account: time=30.040 calls=1000
Trigger for constraint account_fiscal_position_account_account_dest_id_fkey on account_account: time=20.977 calls=1000
Trigger for constraint account_account_tax_default_rel_account_id_fkey on account_account: time=16.423 calls=1000
Trigger for constraint account_account_res_company_rel_account_account_id_fkey on account_account: time=18.848 calls=1000
Trigger for constraint account_account_account_tag_account_account_id_fkey on account_account: time=12.396 calls=1000
Trigger for constraint account_journal_default_account_id_fkey on account_account: time=207.759 calls=1000
Trigger for constraint account_journal_suspense_account_id_fkey on account_account: time=131.019 calls=1000
Trigger for constraint account_journal_non_deductible_account_id_fkey on account_account: time=126.656 calls=1000
Trigger for constraint account_journal_profit_account_id_fkey on account_account: time=128.753 calls=1000
Trigger for constraint account_journal_loss_account_id_fkey on account_account: time=125.281 calls=1000
Trigger for constraint res_company_transfer_account_id_fkey on account_account: time=85.604 calls=1000
Trigger for constraint res_company_default_cash_difference_income_account_id_fkey on account_account: time=75.154 calls=1000
Trigger for constraint res_company_default_cash_difference_expense_account_id_fkey on account_account: time=73.173 calls=1000
Trigger for constraint res_company_account_journal_suspense_account_id_fkey on account_account: time=73.336 calls=1000
Trigger for constraint res_company_account_journal_early_pay_discount_gain_accoun_fkey on account_account: time=73.741 calls=1000
Trigger for constraint res_company_account_journal_early_pay_discount_loss_accoun_fkey on account_account: time=73.402 calls=1000
Trigger for constraint res_company_income_currency_exchange_account_id_fkey on account_account: time=74.586 calls=1000
Trigger for constraint res_company_expense_currency_exchange_account_id_fkey on account_account: time=74.678 calls=1000
Trigger for constraint res_company_account_default_pos_receivable_account_id_fkey on account_account: time=77.105 calls=1000
Trigger for constraint res_company_expense_accrual_account_id_fkey on account_account: time=77.000 calls=1000
Trigger for constraint res_company_revenue_accrual_account_id_fkey on account_account: time=76.399 calls=1000
Trigger for constraint res_company_account_cash_basis_base_account_id_fkey on account_account: time=77.996 calls=1000
Trigger for constraint res_company_account_discount_income_allocation_id_fkey on account_account: time=77.799 calls=1000
Trigger for constraint res_company_account_discount_expense_allocation_id_fkey on account_account: time=78.145 calls=1000
Trigger for constraint res_company_income_account_id_fkey on account_account: time=79.625 calls=1000
Trigger for constraint res_company_expense_account_id_fkey on account_account: time=79.421 calls=1000
Trigger for constraint account_tax_group_tax_payable_account_id_fkey on account_account: time=103.659 calls=1000
Trigger for constraint account_tax_group_tax_receivable_account_id_fkey on account_account: time=75.211 calls=1000
Trigger for constraint account_tax_group_advance_tax_payment_account_id_fkey on account_account: time=72.384 calls=1000
Trigger for constraint account_tax_cash_basis_transition_account_id_fkey on account_account: time=954.139 calls=1000
Trigger for constraint account_tax_repartition_line_account_id_fkey on account_account: time=1445.578 calls=1000
Trigger for constraint account_reconcile_model_line_account_id_fkey on account_account: time=71.619 calls=1000
Trigger for constraint account_move_line_account_id_fkey on account_account: time=140.720 calls=1000
Trigger for constraint account_payment_outstanding_account_id_fkey on account_account: time=17.682 calls=1000
Trigger for constraint account_payment_destination_account_id_fkey on account_account: time=6.791 calls=1000
Trigger for constraint account_payment_method_line_payment_account_id_fkey on account_account: time=75.530 calls=1000
Trigger for constraint account_analytic_line_general_account_id_fkey on account_account: time=81.989 calls=1000
Trigger for constraint account_automatic_entry_wizard_destination_account_id_fkey on account_account: time=8.967 calls=1000
Trigger for constraint account_payment_register_writeoff_account_id_fkey on account_account: time=9.166 calls=1000
Trigger for constraint account_accrued_orders_wizard_account_id_fkey on account_account: time=7.863 calls=1000
Trigger for constraint account_account_account_merge_wizard_re_account_account_id_fkey on account_account: time=7.338 calls=1000
Trigger for constraint account_merge_wizard_line_account_id_fkey on account_account: time=7.706 calls=1000
Trigger for constraint res_company_deferred_expense_account_id_fkey on account_account: time=126.271 calls=1000
Trigger for constraint res_company_deferred_revenue_account_id_fkey on account_account: time=98.607 calls=1000
Trigger for constraint account_account_account_auto_reconcile__account_account_id_fkey on account_account: time=8.921 calls=1000
Trigger for constraint account_reconcile_wizard_account_id_fkey on account_account: time=8.330 calls=1000
Trigger for constraint account_model_rel_account_account_id_fkey on account_account: time=27.264 calls=1000
Trigger for constraint account_transfer_model_line_account_id_fkey on account_account: time=39.033 calls=1000
Trigger for constraint account_fiscal_position_avatax_invoice_account_id_fkey on account_account: time=83.360 calls=1000
Trigger for constraint account_fiscal_position_avatax_refund_account_id_fkey on account_account: time=60.023 calls=1000
Trigger for constraint account_account_account_import_summary__account_account_id_fkey on account_account: time=8.251 calls=1000
Trigger for constraint res_company_account_revaluation_expense_provision_account__fkey on account_account: time=107.339 calls=1000
Trigger for constraint res_company_account_revaluation_income_provision_account_i_fkey on account_account: time=100.037 calls=1000
Trigger for constraint account_account_exclude_res_currency_pr_account_account_id_fkey on account_account: time=9.025 calls=1000
Trigger for constraint account_report_budget_item_account_id_fkey on account_account: time=7.600 calls=1000
Trigger for constraint account_payment_withholding_line_account_id_fkey on account_account: time=7.814 calls=1000
Trigger for constraint res_company_withholding_tax_base_account_id_fkey on account_account: time=116.893 calls=1000
Trigger for constraint account_payment_register_withholding_outstanding_account_i_fkey on account_account: time=8.580 calls=1000
Trigger for constraint account_payment_register_withholding_line_account_id_fkey on account_account: time=8.799 calls=1000
Trigger for constraint res_company_l10n_ee_rounding_difference_loss_account_id_fkey on account_account: time=115.461 calls=1000
Trigger for constraint res_company_l10n_ee_rounding_difference_profit_account_id_fkey on account_account: time=114.827 calls=1000
Trigger for constraint account_journal_l10n_tr_default_sales_return_account_id_fkey on account_account: time=305.506 calls=1000
Trigger for constraint res_company_account_production_wip_account_id_fkey on account_account: time=125.388 calls=1000
Trigger for constraint res_company_account_production_wip_overhead_account_id_fkey on account_account: time=117.769 calls=1000
Trigger for constraint stock_location_valuation_in_account_id_fkey on account_account: time=104.378 calls=1000
Trigger for constraint stock_location_valuation_out_account_id_fkey on account_account: time=67.309 calls=1000
Trigger for constraint stock_valuation_layer_revaluation_account_id_fkey on account_account: time=8.817 calls=1000
Trigger for constraint res_company_l10n_fr_rounding_difference_loss_account_id_fkey on account_account: time=127.732 calls=1000
Trigger for constraint res_company_l10n_fr_rounding_difference_profit_account_id_fkey on account_account: time=124.773 calls=1000
Trigger for constraint res_company_l10n_in_withholding_account_id_fkey on account_account: time=124.847 calls=1000
Trigger for constraint res_company_l10n_nl_rounding_difference_loss_account_id_fkey on account_account: time=131.094 calls=1000
Trigger for constraint res_company_l10n_nl_rounding_difference_profit_account_id_fkey on account_account: time=132.013 calls=1000
Trigger for constraint mrp_workcenter_expense_account_id_fkey on account_account: time=14.578 calls=1000
Trigger for constraint mrp_account_wip_accounting_line_account_id_fkey on account_account: time=8.530 calls=1000
Trigger for constraint account_payment_force_outstanding_account_id_fkey on account_account: time=11.336 calls=1000
Trigger for constraint pos_payment_method_outstanding_account_id_fkey on account_account: time=11.554 calls=1000
Trigger for constraint pos_payment_method_receivable_account_id_fkey on account_account: time=6.654 calls=1000
Trigger for constraint pos_close_session_wizard_account_id_fkey on account_account: time=7.825 calls=1000
Trigger for constraint res_company_downpayment_account_id_fkey on account_account: time=137.312 calls=1000
Trigger for constraint res_company_l10n_bd_corporate_tax_liability_fkey on account_account: time=143.026 calls=1000
Trigger for constraint res_company_l10n_bd_corporate_tax_expense_fkey on account_account: time=141.801 calls=1000
Trigger for constraint account_move_l10n_de_datev_main_account_id_fkey on account_account: time=3874.682 calls=1000
Trigger for constraint stock_landed_cost_lines_account_id_fkey on account_account: time=14.898 calls=1000
Trigger for constraint account_account_account_asset_rel_account_account_id_fkey on account_account: time=9.640 calls=1000
Trigger for constraint account_asset_account_asset_id_fkey on account_account: time=11.687 calls=1000
Trigger for constraint account_asset_account_depreciation_id_fkey on account_account: time=6.551 calls=1000
Trigger for constraint account_asset_account_depreciation_expense_id_fkey on account_account: time=6.300 calls=1000
Trigger for constraint res_company_gain_account_id_fkey on account_account: time=210.699 calls=1000
Trigger for constraint res_company_loss_account_id_fkey on account_account: time=180.965 calls=1000
Trigger for constraint asset_modify_account_asset_id_fkey on account_account: time=10.665 calls=1000
Trigger for constraint asset_modify_account_asset_counterpart_id_fkey on account_account: time=5.466 calls=1000
Trigger for constraint asset_modify_account_depreciation_id_fkey on account_account: time=5.353 calls=1000
Trigger for constraint asset_modify_account_depreciation_expense_id_fkey on account_account: time=5.438 calls=1000
Trigger for constraint res_company_l10n_ae_tax_report_liabilities_account_fkey on account_account: time=176.808 calls=1000
Trigger for constraint res_company_l10n_ae_tax_report_expenses_account_fkey on account_account: time=172.302 calls=1000
Trigger for constraint res_company_l10n_ae_tax_report_asset_account_fkey on account_account: time=170.480 calls=1000
Trigger for constraint res_company_l10n_ar_tax_base_account_id_fkey on account_account: time=171.774 calls=1000
Trigger for constraint soda_account_mapping_account_id_fkey on account_account: time=9.239 calls=1000
Trigger for constraint res_company_l10n_ec_tax_base_sale_account_id_fkey on account_account: time=176.779 calls=1000
Trigger for constraint res_company_l10n_ec_tax_base_purchase_account_id_fkey on account_account: time=175.159 calls=1000
Trigger for constraint account_loan_long_term_account_id_fkey on account_account: time=13.823 calls=1000
Trigger for constraint account_loan_short_term_account_id_fkey on account_account: time=7.044 calls=1000
Trigger for constraint account_loan_expense_account_id_fkey on account_account: time=5.934 calls=1000
Trigger for constraint res_company_l10n_cl_factoring_counterpart_account_id_fkey on account_account: time=193.722 calls=1000
Trigger for constraint res_company_exemption_doctor_master_account_id_fkey on account_account: time=201.309 calls=1000
Trigger for constraint res_company_exemption_bachelor_account_id_fkey on account_account: time=200.476 calls=1000
Trigger for constraint res_company_exemption_bachelor_capping_account_id_fkey on account_account: time=200.465 calls=1000
Trigger for constraint res_company_partner_id_fkey on res_company: time=0.208 calls=10
Trigger for constraint res_company_currency_id_fkey on res_company: time=0.018 calls=10
Trigger for constraint res_company_paperformat_id_fkey on res_company: time=0.014 calls=10
Trigger for constraint res_company_create_uid_fkey on res_company: time=0.015 calls=10
Trigger for constraint res_company_write_uid_fkey on res_company: time=0.009 calls=10
Trigger for constraint res_company_resource_calendar_id_fkey on res_company: time=0.023 calls=10
Trigger for constraint res_company_transfer_account_id_fkey on res_company: time=0.002 calls=9
Trigger for constraint res_company_default_cash_difference_income_account_id_fkey on res_company: time=0.055 calls=10
Trigger for constraint res_company_default_cash_difference_expense_account_id_fkey on res_company: time=0.030 calls=10
Trigger for constraint res_company_account_journal_suspense_account_id_fkey on res_company: time=0.002 calls=8
Trigger for constraint res_company_account_journal_early_pay_discount_gain_accoun_fkey on res_company: time=0.002 calls=7
Trigger for constraint res_company_account_journal_early_pay_discount_loss_accoun_fkey on res_company: time=0.001 calls=4
Trigger for constraint res_company_income_currency_exchange_account_id_fkey on res_company: time=0.029 calls=10
Trigger for constraint res_company_expense_currency_exchange_account_id_fkey on res_company: time=0.001 calls=5
Trigger for constraint res_company_batch_payment_sequence_id_fkey on res_company: time=0.016 calls=10
Trigger for constraint res_company_account_default_pos_receivable_account_id_fkey on res_company: time=0.001 calls=2
Trigger for constraint res_company_account_fiscal_country_id_fkey on res_company: time=0.015 calls=10
Trigger for constraint res_company_income_account_id_fkey on res_company: time=0.002 calls=6
Trigger for constraint res_company_expense_account_id_fkey on res_company: time=0.001 calls=3
Trigger for constraint res_company_deferred_expense_account_id_fkey on res_company: time=0.000 calls=1
Trigger for constraint res_company_nomenclature_id_fkey on res_company: time=0.012 calls=10
Trigger for constraint res_company_internal_transit_location_id_fkey on res_company: time=0.014 calls=10
Trigger for constraint res_company_stock_mail_confirmation_template_id_fkey on res_company: time=0.013 calls=10
Trigger for constraint res_company_documents_fleet_folder_fkey on res_company: time=0.016 calls=10
Trigger for constraint res_company_documents_hr_folder_fkey on res_company: time=0.010 calls=10
Trigger for constraint res_company_documents_employee_folder_id_fkey on res_company: time=0.011 calls=10
Trigger for constraint res_company_documents_project_folder_id_fkey on res_company: time=0.009 calls=10
Trigger for constraint res_company_stock_sms_confirmation_template_id_fkey on res_company: time=0.012 calls=10
Trigger for constraint res_company_recruitment_folder_id_fkey on res_company: time=0.010 calls=10
Trigger for constraint res_company_project_time_mode_id_fkey on res_company: time=0.019 calls=10
Trigger for constraint res_company_timesheet_encode_uom_id_fkey on res_company: time=0.011 calls=10
Trigger for constraint res_company_internal_project_id_fkey on res_company: time=0.015 calls=10
Trigger for constraint res_company_leave_timesheet_task_id_fkey on res_company: time=0.015 calls=10
Trigger for constraint res_company_rental_loc_id_fkey on res_company: time=0.011 calls=10
Trigger for constraint res_company_l10n_ch_delegate_country_id_fkey on res_company: time=0.013 calls=10
Trigger for constraint res_company_l10n_eg_annual_leave_type_id_fkey on res_company: time=0.014 calls=10
Accumulated across the entire test:
account_account_account_asset_rel_account_account_id_fkey: 367.89
account_account_account_auto_reconcile__account_account_id_fkey: 369.314
account_account_account_import_summary__account_account_id_fkey: 308.894
account_account_account_merge_wizard_re_account_account_id_fkey: 258.345
account_account_account_tag_account_account_id_fkey: 437.58
account_account_exclude_res_currency_pr_account_account_id_fkey: 364.079
account_account_res_company_rel_account_account_id_fkey: 676.195
account_account_tax_default_rel_account_id_fkey: 616.155
account_accrued_orders_wizard_account_id_fkey: 281.117
account_analytic_line_general_account_id_fkey: 2920.52
account_asset_account_asset_id_fkey: 435.021
account_asset_account_depreciation_expense_id_fkey: 225.966
account_asset_account_depreciation_id_fkey: 243.045
account_automatic_entry_wizard_destination_account_id_fkey: 333.281
account_fiscal_position_account_account_dest_id_fkey: 764.004
account_fiscal_position_account_account_src_id_fkey: 1127.7
account_fiscal_position_avatax_invoice_account_id_fkey: 2903.72
account_fiscal_position_avatax_refund_account_id_fkey: 2243.92
account_journal_default_account_id_fkey: 8123.53
account_journal_l10n_tr_default_sales_return_account_id_fkey: 13035
account_journal_loss_account_id_fkey: 4810.37
account_journal_non_deductible_account_id_fkey: 5057.85
account_journal_profit_account_id_fkey: 5063.26
account_journal_suspense_account_id_fkey: 5492.64
account_loan_expense_account_id_fkey: 222.776
account_loan_long_term_account_id_fkey: 553.955
account_loan_short_term_account_id_fkey: 259.905
account_merge_wizard_line_account_id_fkey: 265.135
account_model_rel_account_account_id_fkey: 927.993
account_move_l10n_de_datev_main_account_id_fkey: 122923
account_move_line_account_id_fkey: 4000.68
account_payment_destination_account_id_fkey: 265.653
account_payment_force_outstanding_account_id_fkey: 459.209
account_payment_method_line_payment_account_id_fkey: 2660.46
account_payment_outstanding_account_id_fkey: 575.21
account_payment_register_withholding_line_account_id_fkey: 319.363
account_payment_register_withholding_outstanding_account_i_fkey: 383.508
account_payment_register_writeoff_account_id_fkey: 341.615
account_payment_withholding_line_account_id_fkey: 286.658
account_reconcile_model_line_account_id_fkey: 2608.16
account_reconcile_wizard_account_id_fkey: 309.389
account_report_budget_item_account_id_fkey: 300.099
account_tax_cash_basis_transition_account_id_fkey: 31329.6
account_tax_group_advance_tax_payment_account_id_fkey: 2629.35
account_tax_group_tax_payable_account_id_fkey: 3554.27
account_tax_group_tax_receivable_account_id_fkey: 2772.1
account_tax_repartition_line_account_id_fkey: 47923.3
account_transfer_model_line_account_id_fkey: 1309.84
asset_modify_account_asset_counterpart_id_fkey: 207.683
asset_modify_account_asset_id_fkey: 454.126
asset_modify_account_depreciation_expense_id_fkey: 189.258
asset_modify_account_depreciation_id_fkey: 192.029
mrp_account_wip_accounting_line_account_id_fkey: 305.605
mrp_workcenter_expense_account_id_fkey: 565.317
pos_close_session_wizard_account_id_fkey: 285.536
pos_payment_method_outstanding_account_id_fkey: 432.131
pos_payment_method_receivable_account_id_fkey: 249.401
res_company_account_cash_basis_base_account_id_fkey: 5195.51
res_company_account_default_pos_receivable_account_id_fkey: 5357.29
res_company_account_discount_expense_allocation_id_fkey: 5113.98
res_company_account_discount_income_allocation_id_fkey: 5151.48
res_company_account_fiscal_country_id_fkey: 1
res_company_account_journal_early_pay_discount_gain_accoun_fkey: 5640.61
res_company_account_journal_early_pay_discount_loss_accoun_fkey: 5489.35
res_company_account_journal_suspense_account_id_fkey: 5811.88
res_company_account_production_wip_account_id_fkey: 8351.27
res_company_account_production_wip_overhead_account_id_fkey: 7914.54
res_company_account_revaluation_expense_provision_account__fkey: 8858.1
res_company_account_revaluation_income_provision_account_i_fkey: 8169.02
res_company_batch_payment_sequence_id_fkey: 0.995
res_company_create_uid_fkey: 2.96
res_company_currency_id_fkey: 1.081
res_company_default_cash_difference_expense_account_id_fkey: 6060.06
res_company_default_cash_difference_income_account_id_fkey: 6404.5
res_company_deferred_expense_account_id_fkey: 10447.3
res_company_deferred_revenue_account_id_fkey: 8923.24
res_company_documents_employee_folder_id_fkey: 0.875
res_company_documents_fleet_folder_fkey: 1.374
res_company_documents_hr_folder_fkey: 0.829
res_company_documents_project_folder_id_fkey: 0.779
res_company_downpayment_account_id_fkey: 8009.08
res_company_exemption_bachelor_account_id_fkey: 10964.3
res_company_exemption_bachelor_capping_account_id_fkey: 10860.6
res_company_exemption_doctor_master_account_id_fkey: 11117
res_company_expense_account_id_fkey: 5124.13
res_company_expense_accrual_account_id_fkey: 5246.67
res_company_expense_currency_exchange_account_id_fkey: 5352.77
res_company_external_report_layout_id_fkey: 0.308
res_company_gain_account_id_fkey: 14196.4
res_company_income_account_id_fkey: 5136.8
res_company_income_currency_exchange_account_id_fkey: 5441.56
res_company_internal_project_id_fkey: 1.151
res_company_internal_transit_location_id_fkey: 1.019
res_company_l10n_ae_tax_report_asset_account_fkey: 10908.2
res_company_l10n_ae_tax_report_expenses_account_fkey: 11365.8
res_company_l10n_ae_tax_report_liabilities_account_fkey: 11898.4
res_company_l10n_ar_tax_base_account_id_fkey: 10648.4
res_company_l10n_bd_corporate_tax_expense_fkey: 8098.52
res_company_l10n_bd_corporate_tax_liability_fkey: 8176.24
res_company_l10n_ch_delegate_country_id_fkey: 0.864
res_company_l10n_cl_factoring_counterpart_account_id_fkey: 10872.3
res_company_l10n_ec_tax_base_purchase_account_id_fkey: 10358.2
res_company_l10n_ec_tax_base_sale_account_id_fkey: 10547
res_company_l10n_ee_rounding_difference_loss_account_id_fkey: 8158.92
res_company_l10n_ee_rounding_difference_profit_account_id_fkey: 7896.55
res_company_l10n_eg_annual_leave_type_id_fkey: 0.887
res_company_l10n_fr_rounding_difference_loss_account_id_fkey: 8227.23
res_company_l10n_fr_rounding_difference_profit_account_id_fkey: 7965.89
res_company_l10n_in_withholding_account_id_fkey: 7820.82
res_company_l10n_nl_rounding_difference_loss_account_id_fkey: 7982.45
res_company_l10n_nl_rounding_difference_profit_account_id_fkey: 7874.47
res_company_leave_timesheet_task_id_fkey: 1.153
res_company_loss_account_id_fkey: 12688.6
res_company_nomenclature_id_fkey: 0.828
res_company_paperformat_id_fkey: 0.941
res_company_partner_id_fkey: 5.739
res_company_project_time_mode_id_fkey: 1.273
res_company_recruitment_folder_id_fkey: 0.816
res_company_rental_loc_id_fkey: 0.851
res_company_resource_calendar_id_fkey: 1.515
res_company_revenue_accrual_account_id_fkey: 5175.54
res_company_stock_mail_confirmation_template_id_fkey: 0.9
res_company_stock_sms_confirmation_template_id_fkey: 0.861
res_company_timesheet_encode_uom_id_fkey: 0.78
res_company_transfer_account_id_fkey: 7072.12
res_company_withholding_tax_base_account_id_fkey: 8502.05
res_company_write_uid_fkey: 0.743
soda_account_mapping_account_id_fkey: 398.04
stock_landed_cost_lines_account_id_fkey: 658.493
stock_location_valuation_in_account_id_fkey: 3940.27
stock_location_valuation_out_account_id_fkey: 2818.23
stock_valuation_layer_revaluation_account_id_fkey: 340.648
for a total of 661283ms = 11mn[^0].
This commit adds temporary indexes for every m2o field to account which is not already indexed[^1][^2] after all the l10n modules are installed, those indexes are then deleted at the end of the test to avoid polluting the database for the split tests.
This removes most of the cost of deleting accounts (not going to bother with the detail, the entire thing comes out at under a second), at a very minor cost (a few seconds) to create the indices though an increased overall load (due to having to update indexes).
Saves around 5mn on an unloaded 30mn build, and because it avoids a significant amount of parallelized seq scans it saves even more when running on a loaded runbot where parallel postgres workers are CPU starved (10~15mn out of 50~55).
Note: patched `load_file` because `l10n_tr` enables `tr_TR`, and then the tx subsystem complains about pretty much every module being installed because few to none of them have a tr_TR po file.
Backport of #217690
[^0]: `EXPLAIN ANALYZE`-ing everything slows down the test by a factor
of 2x, which is why this takes 11mn instead of the original 5, and
the test itself takes 1h instead of the original 30mn
[^1]: Kinda, currently it just checks if the field is `index` on the
Odoo side, so it's going to miss things like manual partial
indexes, or compound index (though in that case we should only
take in account cases where the account field is the first one),
etc...
[^2]: The specific missing indexes could have been enumerated and
created specifically but it doesn't seem worth the hassle, the
gain from trimming down the list would only be a fraction of a
second from creating a few less indexes, with the risk of missing
new missing indexes. A blacklist might make sense to avoid
creating indexes for constraints with extremely low costs (either
empty tables or already indexed) e.g. constraints with under 250ms
total runtime[^3].
[^3]: Note that the numbers above are full dumps of the trigger times,
a fair number of triggers in the dumps are *not* on accounts but
are due to ancillary deletions or deletion cascades. Pretty much
every trigger below triple digit (ms) runtime is a non-account
trigger, and this PR is not creating indexes for any of those.New automated checks were added to confirm that barcode lookup information is fetched correctly and used to create products across sales, inventory, point of sale, and website flows. This improves confidence that barcode-based product creation keeps working reliably in common business scenarios.
Original PR description
*: pos_barcodelookup, stock_barcode_barcodelookup, website_product_barcodelookup In this commit: ------------------- - Added tests for barcodelookup to check whether the data fetched and set properly. - Added tests in respective modules to check the flow and creation of the products using barcodelookup. task - 3920661 Forward-Port-Of: odoo/enterprise#69120
Resolved issues and error corrections
This fixes a layout problem in the Employee app where very wide resume entries could push the skills table over key resume controls. Users can now view and manage resume information without Add or Delete buttons being hidden.
Original PR description
Steps to reproduce:
1- Go on employee app
2- Click on resume section
3- Click on Add on resume tab
4- Put on description a big table with at least 20 columns
5- Save
The resume table and the buttons "add", "delete" with be hidden by the skill table.
Reason:
The skill table element is too wide
Solution:
The skill table's width is fixed and is contained in resume section element
task-4881917
Description of the issue/feature this PR addresses:
Current behavior before PR:
Desired behavior after PR is merged:
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#217926This fix prevents an error when users merge contacts and then select multiple records in contact-related screens. It ensures Peppol-related partner information is calculated separately for each contact, keeping contact management workflows from being interrupted.
Original PR description
**Steps to Reproduce:** 1. Install `account_peppol` and `contacts`. 2. Open the Contacts app (list view). 3. Select any two contacts and click on "Merge" from the "Actions" menu. 4. Open any of the merged contacts in form view. 5. Close the form view and click on "Add a line". 6. Select multiple records. **Error:** ValueError - Expected singleton: res.partner(11, 9) **Cause:** The method `_compute_available_peppol_eas` accesses `self.available_peppol_eas` directly. When multiple `res.partner` records were involved, it will raised a singleton error. **Fix:** Loop over each partner to compute `available_peppol_eas` for each. This prevents the singleton error when multiple records are processed. sentry-6807787390 Forward-Port-Of: odoo/odoo#223547
The Italian localization now uses the updated €100 threshold for the VP7 line in the monthly VAT report instead of the previous €25.82 amount. This keeps Italian tax reporting aligned with the latest requirement and helps avoid incorrect report values.
Original PR description
While implementing the modulo tag of the tax report xml export, it came to light that the vp7 line of that report which previously used a 25,82€ threshold has been changed for one at 100,00€. This commit adapts the amount across the module. --- Enterprise PR: https://github.com/odoo/enterprise/pull/86642 task-4826511 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#223955 Forward-Port-Of: odoo/odoo#216887
List views now show a plus sign when a domain-based selection exceeds the counting limit, such as "10,000+". This makes it clearer to users that more records are selected than the displayed number can precisely count.
Original PR description
In ListView domain selection mode, a '+' is now shown (e.g., 10,000+) when the number of selected records exceeds the count_limit. This visually indicates that the selection goes beyond a certain limit Closes: #217094 X-original-commit: ddf3d77 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged:
When a new recruitment candidate or applicant is created, the linked contact will now display the candidate’s actual name instead of falling back to their email address. This improves clarity for recruiters and keeps candidate records easier to recognize in the contacts database.
Original PR description
after this commit when a candidate or applicant is created, the corresponding contact should display the candidate’s name correctly, rather than defaulting to the email address. task-4687196 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#205286
This fixes an intermittent failure in automated tests for two-factor authentication by waiting until the web client is fully ready before continuing. It helps keep release validation stable and reduces false test failures without changing the user-facing login experience.
Original PR description
Code and issue at hand are very similar to odoo/odoo#212102 so implement the same "fix" to synchronise the tour on the web client being ready, though technically the first two calls are just "wait a bit" then "wait a bit more" (wait until DOMContentLoaded, then until next frame, then until next event loop). At which point we wait until the event bus has fully connected to the server before moving on to interact with the client for real. It does seem to reliably wait sufficiently long for the issue to go away so works for me... Backport of #224066 https://runbot.odoo.com/odoo/error/181862
Discount information on Dutch electronic invoices is now formatted with the required reason text instead of a reason code. This prevents validation warnings under NLCIUS rules and helps businesses send compliant invoices and refunds.
Original PR description
NLCIUS rule BR-NL-32 triggers a warning if the AllowanceChargeReasonCode rather than the AllowanceChargeReason is present on an invoice line AllowanceCharge. We don't handle this correctly at the moment for discounts, because in that case the UBL 2.0 builder adds an reason code but not a reason. This commit ensures that the reason rather than the reason code is specified in NLCIUS in the case of a discount. opw-4997704 Forward-Port-Of: odoo/odoo#223072
Fixes an issue that could block users from removing a bank account from a customer or partner record. This improves reliability in accounting workflows by preventing invalid empty duplicate records from triggering an error.
Original PR description
Currently an error occurs when we try to remove bank accounts from a partner. **Steps to reproduce:** - Install `accountant` (with demo), Go to customers and create a new one with random name. -…
Currently an error occurs when we try to remove bank accounts from a partner.
**Steps to reproduce:**
- Install `accountant` (with demo), Go to customers and create a new one with random name.
- Under accounting tab add a new bank account with an acc number, bank and save.
- Now remove the bank account record.
**Error:**
`AttributeError: 'NoneType' object has no attribute 'origin'`
**Cause:**
- The error occurs because of the SQL query [1] returning None values in the `id2duplicates` dict, somewhat like `{1: [None]}`, this caused the browse [2] to assign `None` to the `duplicate_bank_partner_ids`.
- While recording snapshots for diff checking in onchange system the none value will be stored like`None: {display_name:{}}` and when the line [3] tries to access `id_.origin` where `id_` is None and causes the error.
**Solution:**
- Added a condition which makes sure null values are not accounted. (The Join is added to makes sure that the correct `partner_id` is fetched.)
[1]: https://github.com/odoo/odoo/blob/04ba4e4a51843701dd42a3f0243add50b3ac0c79/addons/account/models/res_partner_bank.py#L71-L85
[2]: https://github.com/odoo/odoo/blob/04ba4e4a51843701dd42a3f0243add50b3ac0c79/addons/account/models/res_partner_bank.py#L88
[3]: https://github.com/odoo/odoo/blob/04ba4e4a51843701dd42a3f0243add50b3ac0c79/addons/web/models/models.py#L1173
sentry-6748249363
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#219455This fixes an unstable automated test in the Point of Sale area by handling page unloads more predictably. It helps reduce false test failures, improving confidence in future updates without changing day-to-day user functionality.
Original PR description
Use expectUnloadPage key in tour to fix undeterministic behavior. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Work entry validation now skips schedule checks when an employee has a fully flexible working schedule with no calendar set. This prevents unexpected errors when creating, updating, or validating work entries for those employees.
Original PR description
When we validate/write/create a work entry for an employee with a fully flexible working schedule, we can encounter a traceback when trying to call `_attendance_intervals_batch` on a non-existing calendar. To rectify this issue, we continue in the loop when no calendar is set. opw-4979974 opw-4968312 Forward-Port-Of: odoo/odoo#222752
The Time Off allocation kanban view now shows the New button on mobile. This lets managers create allocation requests from the standard mobile view without switching views or using a workaround.
Original PR description
On mobile the "new" button in the time off allocation is not present Steps to reproduce: ------------------- * Open Time_off app * Select Management>Allocations * Open Kanban view (If you are on phone it's the standard view) * Issue : "New" button is missing Observation: The create "0" don't allow to create on kanban view https://github.com/odoo/odoo/blob/2b109261bc6e7550b23a0d444a4e7c63496e4c55/addons/hr_holidays/views/hr_leave_allocation_views.xml#L371 Why the fix: ------------ - It's misleading on phone. - Align with the change on 18.3. https://github.com/odoo/odoo/commit/944c11e61abead4f5157a7a7cb7b1f536bc14411 opw-4898359 Forward-Port-Of: odoo/odoo#221700
List views now show a plus sign when a selected record count goes beyond the display limit, such as "10,000+". This helps users understand that an action may apply to more records than the visible count and reduces confusion when working with very large lists.
Original PR description
Previously, when selection was made in domain mode, the system used the global `web.active_ids_limit` config parameter instead of the actual number of records selected (based on session limit). This caused unintended behavior. For example: - Open a list view of a model with 25,000 records. - The pager limit is initially set to 10,000. - When selecting all 10,000 visible records and performing an action (e.g., archive), the system would incorrectly apply the action to 20,000 records (based on the default value of `web.active_ids_limit`), not the selected 10,000. Forward-Port-Of: odoo/odoo#218440 Forward-Port-Of: odoo/odoo#217094
The Job Position form now correctly shows eligible recruiters and interviewers even when no company is selected. This prevents empty selection lists and helps HR teams assign recruitment responsibilities without first choosing a company.
Original PR description
In the Job Position form, the 'Recruiter' and 'Interviewers' fields were empty when no company was selected. This was due to the static domain using 'company_id' directly without taking into consideration that company_id can be False. This fix introduces computed domain fields (, ) that dynamically adapt based on the selected company. If a company is set, users belonging to that company are shown. If not, only internal users are listed regardless their companies. Related task: 4926154. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#223247 Forward-Port-Of: odoo/odoo#217884
This fix ensures appointment video call redirects are calculated correctly when multiple calendar events are processed at once. It prevents an error that could block or break video call redirection for affected appointments.
Original PR description
When computing `videocall_redirection`, the method `get_base_url()` was called directly on a recordset containing multiple `calendar.event` records. Since `get_base_url()` expects a singleton, this raised the error: Traceback: --- `ValueError: Expected singleton or no record: calendar.event(4, 6, 1, 5)` This commit ensures the computation is done per record, avoiding the singleton issue and allowing correct videocall redirection values to be set on multiple events. Reference review: https://github.com/odoo/enterprise/pull/53569#discussion_r1543135425 sentry-6819406171 Forward-Port-Of: odoo/enterprise#92717
The contract offer screen now hides the signature request button when the current user cannot access any related signature requests. This prevents users from clicking a button that would lead to an error, while still allowing authorized users such as signature administrators to access it.
Original PR description
Before this PR, when logged in as a different user from the one responsible for counter-signing the contract, the smart button still showed, and clicking on it caused an error. This PR fixes that, by hiding the smart button when there are no accessible signature requests. Note that sign admins will still be able to see the smart button; users with access to the signature request. Task-4966129 Forward-Port-Of: odoo/enterprise#90819
Swiss payroll declarations now include contact person details only when all required contact fields are filled in. This helps avoid sending partial or incomplete contact information, reducing the risk of declaration validation issues.
Original PR description
Contact person information should only be transmitted if all 3 fields are filled Forward-Port-Of: odoo/enterprise#93084
Invoice OCR now chooses the matching contact with the strongest supplier or customer history when several contacts share the same VAT number. This reduces incorrect partner selection for companies with multiple addresses or related contacts, improving invoice processing accuracy.
Original PR description
It's possible that multiple partners are sharing the same VAT number, for example, when multiple addresses are set on it (each address will be a child `res.partner` with the same VAT number). Previously, when the OCR matched such partners from their VAT number, it would select one "at random" (based on the default sort of `res.partner`). Now, it will match the one with the highest supplier/customer rank. opw-[4954057](https://www.odoo.com/odoo/49/tasks/4954057) Forward-Port-Of: odoo/enterprise#92398
Steps to reproduce: -------------------------- 1. Install `l10n_co` and activate spanish(es_419) language 2. Configure [DIAN Environment](https://www.odoo.com/documentation/18.0/applications/finance/fiscal_localizations/colombia.html#electronic-invoicing-credentials-and-dian-environment) by enabling DIAN mode 3. Create a customer invoice 4. Fill the required details in the related [customer and journal](https://www.odoo.com/documentation/18.0/applications/finance/fiscal_localizations/colomb
Original PR description
Steps to reproduce: -------------------------- 1. Install `l10n_co` and activate spanish(es_419) language 2. Configure [DIAN Environment](https://www.odoo.com/documentation/18.0/applications/finance/fiscal_localizations/colombia.html#electronic-invoicing-credentials-and-dian-environment) by enabling DIAN mode 3. Create a customer invoice 4. Fill the required details in the related [customer and journal](https://www.odoo.com/documentation/18.0/applications/finance/fiscal_localizations/colombia.html#sales-journals) record 5. Send it with DIAN box checked Issue: -------- `Payment Means` and `Payment Method` are not translated to spanish(es_419). Cause: -------- After this 88d7e5a, the `<br/>` tag was removed and its related **.pot** and **.po** files were not updated. Solution: ----------- Apply the changes to the **.pot** and **.po** files to resolve the issue. opw-4790642 Forward-Port-Of: odoo/enterprise#92099