Daily updates from Odoo
Wednesday, January 8, 2025
13 changes · 18.0
Enhancements to existing features
Peppol invoices and credit notes can now be generated without requiring a customer bank account. This prevents unnecessary blocking errors while keeping country-specific supplier bank checks, such as for the Netherlands, unchanged.
Original PR description
Removing customer bank account constraint for Peppol credit notes and invoices. What appears to be happening is that Peppol is enabled for a contact through setting their invoice format to "UBL BIS Billing 3.0.12", which in turn when generating an invoice through account_edi_ubl_cii/models/account_move_send methods refers to the 'cen_en16931_payment_account_identifier' constraint set in account_edi_xml_ubl_bis3.py through account_edi_common's _check_required_fields() method. For NL suppliers, bank account requirement is specified separately, so I reason I shouldn't touch that. task: 4316460 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Peppol invoice statuses have been renamed to use simpler, consistent wording for business users. Documents now show Pending when they are queued for sending, Error when processing did not go as expected, and Done when completed, making status tracking easier to understand.
Original PR description
Updating Peppol states to be more user-friendly so that states that represent the same concept for the end user now have the same user-facing names as follows: 'Pending' is used when the move went in the pipe and will be send at some point 'Error' is used for both 'skipped' and 'error' state indicating that the move was not processed as expected 'Done' is used when done task: 4423620 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Quality checks now automatically select the failure location when only one is available. This reduces confusion for users and helps prevent failed products from being sent to normal stock by mistake.
Original PR description
Before this Commit: -------------------------------------- - If only one failure location was available during quality checks (with control per quantity), it was not automatically selected by default. - This lack of default selection caused confusion, and as a result, products were mistakenly sent to the normal stock location instead of the failure location. After this Commit: -------------------------------------- - When only one failure location is available, it is now automatically pre-selected by default to enhance the user experience. - This change simplifies the user onboarding process by reducing the risk of products being sent to the normal stock location instead of the failure location. Task-id: 4348525
A countdown timer now appears after staff accept a delivery order, showing how much preparation time remains. This helps point-of-sale teams track timing more clearly and prepare orders within the expected window.
Original PR description
In this commit: - After accepting a delivery order, a countdown timer appears, indicating the preparation time. This timer counts down, providing the user with a timeline to prepare the order within the allotted time.  task-4049465
Resolved issues and error corrections
Fixes an accounting issue where quick invoice entry calculated incorrect tax lines for reverse charge taxes. This helps ensure invoices show balanced tax amounts and accurate totals when reverse charge tax rules are used.
Original PR description
Suppose a tax 15% +100 -100. Use the quick encoding with an amount of 100.0. => The base of the created invoice line is 86.96 and the created tax lines are +13.04 -26.08. That's wrong. Both have to produce the same amount. In 17.0, we get a base of 100 and +15 -15 as tax amounts. In 18.0, we changed the management of reverse charge so the total excluded amount is computed as 100 / 1.15 ~= 86.96. It produces tax lines computed on 86.96. 86.96 * 0.15 ~= 13.04. But at the end, the quick encoding algorithmn "fixes" the tax amount. It expect a total of 100 and it has a missing amount of 100 - 86.96 - 13.04 + 13.04 = 13.04 to reach the objective. So it adds 13.04 in the biggest tax line. opw-4428842 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The live chat chatbot now records the chosen answer directly when a visitor responds, instead of trying to infer it afterward. This prevents wrong selections when answers include special characters or similar wording, and also improves chatbot restart behavior on embedded websites after redirects.
Original PR description
The question_selection steps of the chatbot suffer from several issues. In [1], a fix was made to make the chatbot work with answers containing ampersands, but this fix broke other special characters such as "'". This step also does not handle well answers containing a subset of words, such as "X"/"not X". This occurs because the client code tries to guess which answer was selected after posting the answer. This PR updates the flow to save the answer when the message is posted. As a result, there is no need to guess which answer was selected anymore, and all these issues are fixed. [1]: https://github.com/odoo/odoo/pull/189313 opw-4369966,4436567.
This fix ensures inventory cost calculations use only records from the company currently processing the stock receipt. Branch companies will no longer have their product costs incorrectly averaged with parent company transactions, improving inventory valuation accuracy.
Original PR description
Steps to reproduce the bug: - Log in as Company A - Create a branch company: Branch 1. - Create a storable product P1 with the following configuration:: - Costing method: AVCO - Create a receipt for…
Steps to reproduce the bug:
- Log in as Company A
- Create a branch company: Branch 1.
- Create a storable product P1 with the following configuration::
- Costing method: AVCO
- Create a receipt for 1 unit of P1:
- Unit Price: $300.
- Confirm the receipt:
- The standard price of P1 is updated to $300.
- Log in as Branch 1
- The standard price of P1 is $0.
- Create a receipt for 1 unit of P1:
- Unit Price: $100.
- Confirm the reception
Problem:
The standard price of P1 is incorrectly updated to $225 → ((300 + 100) / 2) instead of $100. This happens because the stock valuation layer computation values includes records from the parent company instead of only the current company:
https://github.com/odoo/odoo/blob/989a78b3fc04e7b5b79e165fda8539be5f091b8c/addons/stock_account/models/stock_move.py#L306-L307
https://github.com/odoo/odoo/blob/41a234890c91e9b0c9771a2b0fe50d4b525079f3/addons/stock_account/models/product.py#L123-L126
https://github.com/odoo/odoo/blob/989a78b3fc04e7b5b79e165fda8539be5f091b8c/addons/stock_account/models/stock_move.py#L323-L324
This issue occurs because the search considers both the current company
and its parent companies. This happens because `self` refers to the
`product.product` model which has
"_check_company_domain = models.check_company_domain_parent_of",
On the other hand, `self.env['stock.valuation.layer']` is a model that
is limited to the current company:
https://github.com/odoo/odoo/blob/8189f053fb4bf219093279c18eebdad01c305385/addons/product/models/product_product.py#L21
opw-4417559This fixes an issue where users who left and rejoined a call could share only a black screen when trying to present again. Screen sharing now works reliably after rejoining, reducing disruption during online meetings.
Original PR description
Current behavior before PR: If a user shares their screen during a call, leaves, and then rejoins the call, attempting to share their screen again results in a black screen being shared. Desired behavior after PR is merged: Screen sharing functions correctly even after rejoining a call. task-id:[4441751](https://www.odoo.com/odoo/my-tasks/4441751) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where reloading Indian withholding tax setup could corrupt tax data after the first company was processed. It helps prevent failed upgrades or module updates for databases with multiple Indian companies.
Original PR description
# Description When we reload the chart of accounts parsed CSV data is altered after iterating the first company because we are Only updating the tags of existing taxes For existing tax, we are…
# Description
When we reload the chart of accounts parsed CSV data is altered after iterating
the first company because we are Only updating the tags of existing taxes
For existing tax, we are mapping repartition lines here https://github.com/odoo/odoo/blob/a4c14fab299ed98024b7d7148d89bf17e914ccd1/addons/account/models/chart_template.py#L359
So that data_list has been altered after for the next company
for the next iterator company, it has been eligible for obsolete here https://github.com/odoo/odoo/blob/a4c14fab299ed98024b7d7148d89bf17e914ccd1/addons/account/models/chart_template.py#L400
So, it is better to keep parsing data as it is while reloading the chart accounts for each company
TBG: [Traceback Group-1421](https://upgrade.odoo.com/web#id=1421&cids=1&menu_id=107&model=upgrade.request.traceback.group&view_type=form)
OPWS:
- [4391978](https://www.odoo.com/odoo/project/70/tasks/4391978)
- [4402365](https://www.odoo.com/odoo/70/tasks/4402365)
```py
2024-12-26 10:21:46,303 16 INFO higo_2397155_18.0 odoo.addons.base.models.ir_module: module l10n_in_withholding: no translation for language en_IN
2024-12-26 10:21:47,426 16 INFO higo_2397155_18.0 odoo.addons.l10n_in_withholding: Company Repose Foods Private Limited already has the Indian localization installed, updating...
> /home/odoo/src/odoo/18.0/addons/account/models/chart_template.py(322)_pre_reload_data()
-> for model_name, records in data.items():
(Pdb) len([i for i in data['account.tax'].values() if i.get('name')])
163
(Pdb) c
> /home/odoo/src/odoo/18.0/addons/account/models/chart_template.py(397)_pre_reload_data()
-> if obsolete_xmlid:
(Pdb) len([i for i in data['account.tax'].values() if i.get('name')])
75
(Pdb) c
2024-12-26 10:22:14,417 16 INFO higo_2397155_18.0 odoo.addons.l10n_in_withholding: Company M/S Repose already has the Indian localization installed, updating...
> /home/odoo/src/odoo/18.0/addons/account/models/chart_template.py(322)_pre_reload_data()
-> for model_name, records in data.items():
(Pdb) len([i for i in data['account.tax'].values() if i.get('name')])
75
(Pdb) c
> /home/odoo/src/odoo/18.0/addons/account/models/chart_template.py(397)_pre_reload_data()
-> if obsolete_xmlid:
(Pdb) l
392 skip_update.add((model_name, xmlid))
393
394 for skip_model, skip_xmlid in skip_update:
395 data[skip_model].pop(skip_xmlid, None)
396 import pdb; pdb.set_trace()
397 -> if obsolete_xmlid:
398 self.env['ir.model.data'].search([
399 ('name', 'in', [f"{company.id}_{xmlid}" for xmlid in obsolete_xmlid]),
400 ('module', '=', 'account'),
401 ]).unlink()
402
(Pdb) len(obsolete_xmlid)
88
(Pdb) c
2024-12-26 10:22:56,209 16 INFO higo_2397155_18.0 odoo.models.unlink: User #1 deleted ir.model.data records with IDs: [48827, 48804, 48815, 48813, 48823, 48828, 48811, 48809, 48807, 48821, 48817, 48819, 48805, 48812, 48816, 48814, 48806, 48810, 48808, 48822, 48818, 48820, 48824, 48826, 48825, 48887, 48888, 48829, 48831, 48833, 48835, 48843, 48848, 48856, 48862, 48865, 48867, 48869, 48871, 48873, 48877, 48889, 48839, 48858, 48885, 48890, 48830, 48832, 48834, 48836, 48841, 48844, 48846, 48847, 48849, 48850, 48852, 48854, 48857, 48859, 48861, 48863, 48866, 48868, 48870, 48876, 48872, 48874, 48881, 48884, 48886, 48878, 48840, 48855, 48864, 48882, 48837, 48838, 48879, 48891, 48842, 48845, 48851, 48853, 48860, 48875, 48880, 48883]
2024-12-26 10:22:56,738 16 ERROR higo_2397155_18.0 odoo.sql_db: bad query: b'INSERT INTO "account_tax" ("active", "amount", "amount_type", "company_id", "country_id", "create_date", "create_uid", "description", "formula", "include_base_amount", "invoice_label", "is_base_affected", "l10n_in_section_id", "l10n_in_tds_tax_type", "name", "sequence", "tax_exigibility", "tax_group_id", "tax_scope", "type_tax_use", "write_date", "write_uid") ...
```
**Traceback**
```py
2024-12-26 06:49:10,588 26 INFO higo_2403300_18.0 odoo.addons.l10n_in_withholding: Company Sah Estates already has the Indian localization installed, updating...
2024-12-26 07:14:31,217 26 INFO higo_2403300_18.0 odoo.addons.l10n_in_withholding: Company sahaccounts already has the Indian localization installed, updating...
2024-12-26 07:16:43,050 26 INFO higo_2403300_18.0 odoo.models.unlink: User #1 deleted ir.model.data records with IDs: [26281, 26258, 26269, 26267, 26277, 26282, 26265, 26263, 26261, 26275, 26271, 26273, 26259, 26266, 26270, 26268, 26260, 26264, 26262, 26276, 26272, 26274, 26278, 26280, 26279, 26341, 26342, 26283, 26285, 26287, 26289, 26297, 26302, 26310, 26316, 26319, 26321, 26323, 26325, 26327, 26331, 26343, 26293, 26312, 26339, 26344, 26284, 26286, 26288, 26290, 26295, 26298, 26300, 26301, 26303, 26304, 26306, 26308, 26311, 26313, 26315, 26317, 26320, 26322, 26324, 26330, 26326, 26328, 26335, 26338, 26340, 26332, 26294, 26309, 26318, 26336, 26291, 26292, 26333, 26345, 26296, 26299, 26305, 26307, 26314, 26329, 26334, 26337]
2024-12-26 07:35:03,359 28 ERROR higo_2397155_18.0 odoo.modules.registry: Failed to load registry
2024-12-26 07:35:03,359 28 CRITICAL higo_2397155_18.0 odoo.service.server: Failed to initialize database `higo_2397155_18.0`.
Traceback (most recent call last):
File "/home/odoo/src/odoo/18.0/odoo/service/server.py", line 1306, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-13>", line 2, in new
File "/home/odoo/src/odoo/18.0/odoo/tools/func.py", line 97, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 127, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 480, in load_modules
processed_modules += load_marked_modules(env, graph,
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 364, in load_marked_modules
loaded, processed = load_module_graph(
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 245, in load_module_graph
getattr(py_module, post_init)(env)
File "/home/odoo/src/odoo/18.0/addons/l10n_in_withholding/__init__.py", line 26, in _l10n_in_withholding_post_init
ChartTemplate._load_data(data)
File "/tmp/tmpqk9sqppy/migrations/account/0.0.0/pre-ensure-deferred-accounts.py", line 36, in _load_data
return super()._load_data(data, *args, **kwargs)
File "/home/odoo/src/odoo/18.0/addons/account/models/chart_template.py", line 635, in _load_data
created_records[model] = self.with_context(lang='en_US').env[model]._load_records(all_records_vals, ignore_duplicates=ignore_duplicates)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5467, in _load_records
records = self._load_records_create([data['values'] for data in to_create])
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5371, in _load_records_create
records = self.create(vals_list)
File "<decorator-gen-228>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 480, in _model_create_multi
return create(self, arg)
File "/home/odoo/src/odoo/18.0/addons/account/models/account_tax.py", line 599, in create
taxes = super(AccountTax, self.with_context(context)).create([self._sanitize_vals(vals) for vals in vals_list])
File "<decorator-gen-140>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 480, in _model_create_multi
return create(self, arg)
File "/home/odoo/src/odoo/18.0/addons/mail/models/mail_thread.py", line 268, in create
threads = super(MailThread, self).create(vals_list)
File "<decorator-gen-120>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 480, in _model_create_multi
return create(self, arg)
File "/tmp/tmpqk9sqppy/migrations/util/orm.py", line 244, in wrapper
return f(*args, **kwargs)
File "/tmp/tmpqk9sqppy/migrations/base/0.0.0/pre-models-match_uniq.py", line 96, in create
records = super().create([vals_list[idx] for idx in create_idx_list])
File "<decorator-gen-31>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 480, in _model_create_multi
return create(self, arg)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 4975, in create
records = self._create(data_list)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5159, in _create
cr.execute(SQL(
File "/home/odoo/src/odoo/18.0/odoo/sql_db.py", line 354, in execute
res = self._obj.execute(query, params)
psycopg2.errors.NotNullViolation: null value in column "name" of relation "account_tax" violates not-null constraint
DETAIL: Failing row contains (1941, 18, 1, 12, null, 104, 1, 1, sale, null, percent, on_invoice, null, null, null, 0.0000, t, f, t, null, 2024-12-26 07:34:58.528488, 2024-12-26 07:34:58.528488, price_unit * 0.10, null, null, null, null, null).
```
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-prAppointment pages that exclude certain countries can now still be opened through a direct link, instead of showing a 404 error. The exclusion still controls where appointments appear in listings and search, keeping visibility rules intact while preventing broken shared links.
Original PR description
Excluding counbtries on an appointment type should not lead to a 404 page when directly given the appointment link (even wihtout invite). Now the countries excluded are used to not display these appointments when necessary but they can still be reached with the direct link. task-4456488
Fixed an issue that caused the Cash Flow Statement to crash when users selected multiple companies. The report now handles accounts from different companies correctly, so finance teams can view multi-company cash flow data without interruption.
Original PR description
Steps:
- Have 2 or more companies, select both in company selector
- Go to Cash Flow Statement report
-> Traceback: `TypeError: '<' not supported between instances of 'str' and 'NoneType'`
Cause:
https://github.com/odoo/enterprise/blob/0dad52c1371f2daca50775d72571a0eac768ac03/account_reports/models/account_cash_flow_report.py#L228
is equal to `SQL('("account_move_line__account_id"."code_store"->%s->>0)::VARCHAR', '<self.env.company.id>')` therefore the account code
for accounts that are not from `self.env.company` are set to None in the data dict
Fix:
Adding a default value set to '' and reversing the order allowing to
keep the accounts from the selected company first.
opw-4367588Bank reconciliation now correctly uses the partial payment amounts when matching a batch payment to a statement line. This prevents validation errors caused by trying to reconcile the full invoice amounts instead of the actual payments received.
Original PR description
partial payments An user may receive several partial payments for invoices/bills. These payments could be grouped in a batch and reconciled with a single statement line. However this flow is…
partial payments An user may receive several partial payments for invoices/bills. These payments could be grouped in a batch and reconciled with a single statement line. However this flow is currently not working because the bank reconciliation fails Steps to reproduce: - Create 2 invoice and register a partial payment for each one - Select the 2 payments create a batch - Create a new statement with the sum of the payment amounts - Reconcile the statement with the created batch Issue: An error will block the validation ``` The move (BNK1/2024/00011) is not balanced. The total of debits equals $ 510.60 and the total of credits equals $ 100.00. You might want to specify a default account on journal "Bank" to automatically balance each move. ``` This occurs because the system is taking the amount to reconcile from the invoice, instead of the payment, so it will try to reconcile the full amount. opw-4379673
Fixed an issue where reconciling a bank statement with a batch of partial payments could fail because the system compared the batch total with the full invoice amount. The reconciliation now uses the actual payment amounts and ignores cancelled or rejected payments, helping accounting teams complete bank matching reliably.
Original PR description
**Steps to reproduce:** - Install accountant - Create an invoice for $1000 - Register a payment of $100 for the invoice - Register a second payment of $200 for the invoice - Create a batch payment…
**Steps to reproduce:** - Install accountant - Create an invoice for $1000 - Register a payment of $100 for the invoice - Register a second payment of $200 for the invoice - Create a batch payment with both payments - Validate the batch payment - Create a bank statement with an amount equal to the batch payment (i.e. $300) - Reconcile the statement with the batch payment **Issue:** A UserError is raised stating that the moves are not balanced. One amount is equal to the sum of the 2 payments (i.e. $300), but the other one is equal to the amount of the payment term line of the invoice (i.e. $1000). **Cause:** When reconciling a batch payment, only "amount_currency" field from the invoice lines are used in "_validation_lines_vals". But in this case, the payments are partial and their sum is not equal to the amount of of the invoice lines. **Solution:** Use the amount from each payment of the batch for the reconciliation instead of the amount from the account move lines. opw-4304772