Tuesday, August 12, 2025
21 changes · 18.0
Enhancements to existing features
Users can now update only part of the analytic distribution when editing multiple journal items or analytic items at once. This makes bulk accounting updates more practical and reduces repetitive manual corrections.
Original PR description
In Journal Items list view, mass edition of the Analytic Distribution on several records is disappointing and reported almost unusable. It is impossible to mass edit only one plan on multiple lines using a distribution. This commit is adding the possibility to do so from the list view of analytic items but also from the journal items. task-4937143
This update adds a warning when sending Mexican electronic invoices for customers missing required country or ZIP information while the public CFDI option is turned off. It helps users catch incomplete customer data before invoice sending, reducing compliance issues and failed submissions.
Original PR description
Adding a warning and a check to account.move.send constraints for trying to send an invoice for a customer that doesn't have either country or ZIP specified, when 'CFDI to Public' is set to False (requires user action to override default behavior). task-4963869
The UAE payroll end of service report now calculates an employee’s worked years based on their full duration with the company, rather than only actual worked days. This provides a more accurate tenure figure for end of service reporting and related HR payroll processes.
Original PR description
- update the calculation for the worked years in the end of service report to return the whole duration worked with the comapny not just the actual worked days. Task: 4703337
Resolved issues and error corrections
This fix ensures that when a manufacturing order is unbuilt, returned components keep their original consignment owner information. This prevents consigned stock from being incorrectly mixed into company-owned inventory, improving inventory accuracy for manufacturing operations.
Original PR description
**Problem:** when a MO is unbuild, if some components where consigned, they will come back in stock as not consigned **Steps to reproduce:** - enable "consignemnet" setting - create a storable…
**Problem:** when a MO is unbuild, if some components where consigned, they will come back in stock as not consigned **Steps to reproduce:** - enable "consignemnet" setting - create a storable product (the comp) - set on on hand quantity of 3 without owner - set on on hand quantity of 4 with an owner - create another product (the final product), with a BOM of 7 of the comp product - create a manufacturing order for the final product, confirm and produce all. - unbuild it - open the comp product form, click on the on hand smart button **Current behavior:** - there is a quantity of 7 unconsigned **Expected behavior:** - there should be a quantity of 3 unconsigned and a quantity of 4 consigned **Cause of the issue:** when the stock move line is create in action_unbuild() there is no mechanism to get back the owner of the original stock move line from the MO https://github.com/odoo/odoo/blob/ceccb92af19a6a3fc0c7b5924d9f497b1aec1d55/addons/mrp/models/mrp_unbuild.py#L204 opw-4900386 Forward-Port-Of: odoo/odoo#219905
This fix prevents Odoo from crashing when users open an app while multiple modules are still being installed. It makes the web interface handle partially loaded view information safely, improving reliability during installation workflows.
Original PR description
Currently, an error occurs when the user tries to install multiple modules and, during installation user tries to access any app. This issue happens because line [1] tries to get view info by view…
Currently, an error occurs when the user tries to install multiple modules and, during installation user tries to access any app. This issue happens because line [1] tries to get view info by view name, like `hierarchy`. Normally, we get the view information from the `_get_view_info` method (see [2]), and we override this method to add another view to the returned data (as in [3]). But during installation, when the user tries to access any app, the view is already loaded into the database. So when the `fields_get` method is called, the view is found. However, since the module isn't fully loaded yet, the overridden `get_view_info` method hasn't taken effect. As a result, the additional view we expect isn’t included, and accessing that view key causes an error. This commit fixes the above error by ensuring that `_view_info` is accessed only when `type_` is present in `_view_info` at [1]. [1]: https://github.com/odoo/odoo/blob/80976e3579db4862c16cafab2ec183a7a0d0b63c/addons/web/models/ir_ui_view.py#L14 [2]: https://github.com/odoo/odoo/blob/80976e3579db4862c16cafab2ec183a7a0d0b63c/addons/web/models/ir_ui_view.py#L22-L31 [3]: https://github.com/odoo/odoo/blob/80976e3579db4862c16cafab2ec183a7a0d0b63c/addons/web_hierarchy/models/ir_ui_view.py#L56-L57 sentry-5661154820
Attachments added while scheduling an activity are now linked to the final activity record instead of the temporary scheduling wizard. This prevents those files from being removed during future database upgrades, helping users retain important activity-related documents.
Original PR description
Steps to reproduce the issue: 1. Create a new activity on any `mail.thread` (`project.project` for example) 2. On the wizard, upload an attachment 3. Schedule the activity 4. Upgrade the database to…
Steps to reproduce the issue: 1. Create a new activity on any `mail.thread` (`project.project` for example) 2. On the wizard, upload an attachment 3. Schedule the activity 4. Upgrade the database to any future version Current behavior before PR: The attachments created with activities would be deleted due to the query [here](https://github.com/odoo/upgrade/blob/master/migrations/base/0.0.0/pre-clean-transients.py#L69), because they are linked to the transient model `mail.activity.scheduel`. Attachments linked to these models are deleted during the upgrade. Desired behavior after PR is merged: The newly created attachments are linked to the `mail.activity` record directly, avoiding the post-upgrade issue. This change also aligns the feature with attaching a file to a `mail.message` record, where the `res_model` and `res_id` fields move from `mail.compose.message` to the target model after posting the message. opw-4812659 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The point of sale product screen now adjusts the number of product tiles per row on mobile devices instead of forcing a fixed layout. This prevents the product list from overflowing and makes mobile checkout browsing smoother, with a test added to help avoid regressions.
Original PR description
- This commit fixes the issue of vertical scrolling on mobile devices, now we responsively display the correct number of product lists by line, instead of forcing the display of 3 per lines. - Also add a test to ensure that the product list does not overflow on mobile devices. backport of commit (8dba5b2781d40c0817829ce330aeea2c6b0bff36) task-id: 4922341 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Calendar reminders now only appear for upcoming events within the correct reminder window. This prevents users from receiving confusing notifications for meetings that have already passed, especially for recurring events.
Original PR description
Steps to reproduce the issue: 1. Create a calendar event (meeting, for example) 2. Set the start date as yesterday and in 30 minutes from now. 3. Set it to be recurrent every week with end_type set to end_date and in the future(1 month from now). 4. Add a reminder to the event (30 mins, for example) and ensure that calendar_last_notif_ack is set before the alarm window for your user's res.partner. 5. Save the event and observe an alarm notification made for an event in the past. After the fix, the calendar alarms will only trigger for events in the future and in their designated time windows. The recurrence logic was also removed from the query to align with this [[REF]](https://github.com/odoo/odoo/pull/42031/commits/a27afdb5434166c3ea48c18ccfba9e8245d18e62) since recurring events are all persistent records in the database. opw-4776638 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222214
This fix ensures work entries for employees on flexible schedules use the actual time period being processed, rather than assuming a full standard day. This prevents incorrect 8-hour durations when attendances occur on public holidays or partial-day gaps, improving payroll and attendance accuracy.
Original PR description
### Steps to reproduce: - Set Marc Demo's contract work entry source to attendances and working schedule to flexible hours. - Create a public holiday with generic time off work entry type. - Create…
### Steps to reproduce: - Set Marc Demo's contract work entry source to attendances and working schedule to flexible hours. - Create a public holiday with generic time off work entry type. - Create one or multiple attendances for marc demo on the public holiday. - Regenerate work entries for marc demo for that day, the gaps in between the attendances created and the working hours will be filled with work entries with the right start/end time but duration will always be 8h. ### Cause: This is happening because when getting the duration batch for the work entry we get the attendance intervals the employee should work in that period and if the employee is flexible we will get a fake attendance with the number of hours required per day ignoring if the period is just a small period of the day ### Fix: We are checking now since the start date not monday so we don't set a fixed week start. We check if the period is less than the remaining hours we get it as it mostly means that it is less than one day opw-4887933
This fix prevents the Spanish Modelo 111 tax report from crashing when opened after a reporting engine change. It removes an incompatible grouping setting so affected users can access the report normally.
Original PR description
Commit https://github.com/odoo/odoo/commit/97fe24cea74241a7820841a470994d3ebf9d8d38 changed the engine for some report line of Modelo 111. The new engine used, `external`, is not compatible with having a grouping value defined by the user (field `user_groupby`). Except that value does not get removed from the report lines. As a result, a traceback pops up whenever we try to access the report. Two previous commits aimed to sync that field with the `groupby` field (https://github.com/odoo/odoo/commit/a7d54c76aaee325449248fa698adb9e549c486ee), and update it if it was not compatible with the engine (https://github.com/odoo/odoo/commit/0d5bf820c3737ee3e4af54d1fb556b72d6c59c3d) but both only work with `aggregation` engine. This commit makes `_validate_engine()` account for `external` engine, as it was only checking for `aggregation` engine when validating `groupby` related fields. opw-4972212 opw-4971497 opw-4931269 opw-4949654 Forward-Port-Of: odoo/odoo#221021
This fixes an issue where older Saudi ZATCA Phase 1 invoice QR codes disappeared after the electronic invoicing module was installed. Businesses can now see the correct QR code for both Phase 1 and Phase 2 invoices, supporting compliant invoice reporting.
Original PR description
Phase 1 ZATCA QR codes disappear when l10n_sa_edi is installed, there is a check for document submission to display the QR code for Phase 2 which older Phase 1 invoices will not pass as it doesn't use edi. Description of the issue/feature this PR addresses: Phase 1 ZATCA QR Code disappears once l10n_sa_edi is installed Current behavior before PR: Always hide Phase 1 ZATCA QR Code Desired behaviour after PR is merged: Showing Phase 1 and Phase 2 ZATCA QR codes based on the invoice task-5005304 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
PDF reports covering multiple records now fall back to generating each document separately when automatic splitting cannot determine the correct pages. This prevents missing or broken report files in cases where report templates or PDF generation tools produce inconsistent outlines, though large batches may take longer to process.
Original PR description
When generating PDF reports with multiple records, the system tries to split the concatenated PDF using outlines. However, in cases where the number of outlines doesn't match the number of records or…
When generating PDF reports with multiple records, the system tries to split the concatenated PDF using outlines. However, in cases where the number of outlines doesn't match the number of records or outlines are missing, it falls back to generating individual PDFs per record by recursively calling `_render_qweb_pdf_prepare_streams()` for each `res_id`.
This ensures that each record gets its corresponding PDF even if splitting the combined PDF is not possible due to template or wkhtmltopdf inconsistencies.
issue related: https://github.com/odoo/odoo/issues/202299
Current Behavior:
The _render_qweb_pdf_prepare_streams method does not correctly generate PDF streams under specific conditions, causing the PDF to not be properly split for each res_id. When these conditions are met, the generated streams are set to None, resulting in incorrect PDF processing.
The issue occurs when all the following conditions are true:
reader.numPages != len(res_ids_wo_stream)
len(res_ids_wo_stream) > 1 and set(res_ids_wo_stream) == set(html_ids_wo_none) is True
not has_valid_outlines is False
has_same_number_of_outlines and has_top_level_heading is False, since has_same_number_of_outlines is False
Expected Behavior:
The method should correctly assign a valid PDF stream to each res_id, ensuring proper document splitting even when outlines cannot be used.
Steps to Reproduce:
Generate a PDF report where the number of pages does not match the number of res_ids.
Ensure that the report includes multiple records, and the outlines structure is not valid for splitting.
Debug and Observe that the streams assigned to res_ids are None, leading to issues in PDF rendering.
Error:
Odoo Server Error
RPC_ERROR
Odoo Server Error
Occured on 172.20.18.5:8069 on model ir.cron and id 31 on 2025-03-18 12:02:43 GMT
Traceback (most recent call last):
File "/home/odoo/src/odoo/odoo/tools/safe_eval.py", line 397, in safe_eval
return unsafe_eval(c, globals_dict, locals_dict)
File "ir.actions.server(309,)", line 1, in
File "/home/odoo/src/odoo/addons/account/models/account_move.py", line 5481, in _cron_account_move_send
self.env['account.move.send']._generate_and_send_invoices(
File "/home/odoo/src/odoo/addons/account/models/account_move_send.py", line 687, in _generate_and_send_invoices
self._generate_invoice_documents(moves_data, allow_fallback_pdf=allow_fallback_pdf)
File "/home/odoo/src/odoo/addons/account/models/account_move_send.py", line 612, in _generate_invoice_documents
self._prepare_invoice_pdf_report(batch)
File "/home/odoo/src/odoo/addons/account/models/account_move_send.py", line 333, in _prepare_invoice_pdf_report
content_by_id = self.env['ir.actions.report']._get_splitted_report(pdf_report.report_name, content, report_type)
File "/home/odoo/src/odoo/addons/account/models/ir_actions_report.py", line 60, in _get_splitted_report
pdf_dict = {res_id: stream['stream'].getvalue() for res_id, stream in content.items()}
File "/home/odoo/src/odoo/addons/account/models/ir_actions_report.py", line 60, in
pdf_dict = {res_id: stream['stream'].getvalue() for res_id, stream in content.items()}
AttributeError: 'NoneType' object has no attribute 'getvalue'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/odoo/src/odoo/odoo/http.py", line 1962, in _transactioning
return service_model.retrying(func, env=self.env)
File "/home/odoo/src/odoo/odoo/service/model.py", line 156, in retrying
result = func()
File "/home/odoo/src/odoo/odoo/http.py", line 1929, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "/home/odoo/src/odoo/odoo/http.py", line 2177, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_http.py", line 333, in _dispatch
result = endpoint(**request.params)
File "/home/odoo/src/odoo/odoo/http.py", line 727, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "/home/odoo/src/odoo/addons/web/controllers/dataset.py", line 42, in call_button
action = call_kw(request.env[model], method, args, kwargs)
File "/home/odoo/src/odoo/odoo/api.py", line 533, in call_kw
result = getattr(recs, name)(*args, **kwargs)
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_cron.py", line 120, in method_direct_trigger
self.ir_actions_server_id.run()
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_actions.py", line 995, in run
res = runner(run_self, eval_context=eval_context)
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_actions.py", line 827, in _run_action_code_multi
safe_eval(self.code.strip(), eval_context, mode="exec", nocopy=True, filename=str(self)) # nocopy allows to return 'action'
File "/home/odoo/src/odoo/odoo/tools/safe_eval.py", line 411, in safe_eval
raise ValueError('%r while evaluating\n%r' % (e, expr))
ValueError: AttributeError("'NoneType' object has no attribute 'getvalue'") while evaluating
'model._cron_account_move_send(job_count=20)'
The above server error caused the following client error:
RPC_ERROR: Odoo Server Error
RPC_ERROR
at makeErrorFromResponse (http://172.20.18.5:8069/web/assets/0604b65/web.assets_web.min.js:3140:163)
at XMLHttpRequest. (http://172.20.18.5:8069/web/assets/0604b65/web.assets_web.min.js:3145:13)
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prInternal users can now convert Excel files in shared document folders into Odoo spreadsheets even when portal users have edit access on the folder. During conversion, portal users are limited to view-only access on the new spreadsheet, avoiding an error while respecting spreadsheet sharing rules.
Original PR description
Let's say a Document Folder is shared with a portal user with 'edit' access. The portal user shares a .xlsx file to the folder, and an internal user later try to convert the file to odoo spreadsheet.…
Let's say a Document Folder is shared with a portal user with 'edit' access. The portal user shares a .xlsx file to the folder, and an internal user later try to convert the file to odoo spreadsheet. During the conversion, the portal user has 'edit' role on the folder, which is copied to the documents.access records of the converted sheet. Since Odoo prevents Spreadsheets from being shared in edit mode to portal users, _check_spreadsheet() raises a Validation Error, even though the internal user has all the access rights. To improve the user experience, this commit overrides `copy_data` of `documents.access` model to assign `view` access to portal users for an odoo spreadsheet. Maybe we can extract the if-conditions, and make it an API to reduce repeated code, as the same logic is being used in `_check_spreadsheet()` on the same file. However, looping through the copied vals_list only when handler is spreadsheet might have more value in terms of performance. --- This commit enables .xlsx to spreadsheet conversion only for internal users. The solution for portal users requires more complex implementation deserving its own review cycle, which is proposed in [PR #92134](https://github.com/odoo/enterprise/pull/92134) (PR #92134's first commit is the same commit as current PR's commit) opw-4753670
Payroll users in Belgium can now export work entries for any active company they have access to, instead of being limited to their current company. The export also now checks that the selected company has its required Group S code set, helping prevent incomplete or failed submissions.
Original PR description
before this commit only the current company was taken into account when exporting work entries now another company can be selected if multiple companies are active for the current user In addition to that this commit also add a check for the company's group s code to enforce the user to set it before exporting work entries task-4213675 closes old PR: odoo/enterprise/pull/71521
This fixes an issue where nested grouped lines in account reports did not fold properly and could trigger an error when users expanded or collapsed partner lines. The change helps keep financial reports stable and easier to navigate when using grouped account data.
Original PR description
Steps to reproduce: - Create an Account Group - Create a new Account Report as follows: * Name: any * Lines: 1. [test line] * Group By: partner_id,account_id * Expressions: 1. [test expression] *…
Steps to reproduce:
- Create an Account Group
- Create a new Account Report as follows:
* Name: any
* Lines:
1. [test line]
* Group By: partner_id,account_id
* Expressions:
1. [test expression]
* Computation Engine: Odoo Domain
* Formula: [('account_id.account_type', '=', 'asset_receivable')]
* Subformula: sum
- Actions > Create Menu Item
- Open the new report
- Try to unfold/fold a partner line
Issue:
Folding will not fold the first child (representing the created account group). Also, error will raise
```
Uncaught Promise > Got duplicate key in t-foreach: ~account.report~37|~account.report.line~255|{'groupby': 'partner_id'}~res.partner~4226|~account.group~90
Occured on odoo.nas.cpolar.cn on 2025-04-26 04:58:53 GMT
OwlError: Got duplicate key in t-foreach: ~account.report~37|~account.report.line~255|{'groupby': 'partner_id'}~res.partner~4226|~account.group~90
Error: Got duplicate key in t-foreach: ~account.report~37|~account.report.line~255|{'groupby': 'partner_id'}~res.partner~4226|~account.group~90
at AccountReport.template (eval at compile (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:13743:20), <anonymous>:138:49) (/web/static/lib/owl/owl.js:5752)
at App.callTemplate (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:11363:50) (/web/static/lib/owl/owl.js:3372)
at AccountReport.template (eval at compile (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:13743:20), <anonymous>:9:12) (/web/static/lib/owl/owl.js:5752)
at RootFiber._render (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:9774:38) (/web/static/lib/owl/owl.js:1783)
at RootFiber.render (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:9766:18) (/web/static/lib/owl/owl.js:1775)
at ComponentNode.render (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:10493:23) (/web/static/lib/owl/owl.js:2502)
```
Analysis:
Folding issues occurs because of a mismatch in the grouping markup quote escape. If we don't have the very same string the controller cannot properly recognize the parent line and then is unable to fold/unfold properly.
This eventually led to the mentioned error at unfold as the backend will try to generate the apparently missing lines to unfold, only to create duplicate lines
opw-4754241Tickets created from Timesheets now automatically use the Helpdesk team linked to the selected project. This prevents tickets from being assigned to the wrong team and helps keep support work routed correctly from the start.
Original PR description
Steps to Reproduce: - 1. Go to Timesheets > My Timesheets, start the timer, and select the project linked to the helpdesk team. 2. In the timer header, quick-create a new ticket via the "Ticket" field dropdown 3. Observe that the default helpdesk team on the new ticket is incorrect. Issue: - - When creating a ticket from the Timesheets module (e.g., via timer header or views), the system selects an incorrect default helpdesk team, leading to misassigned tickets. Cause: - - The core default logic for team_id prioritizes user membership or the first team without considering the selected project's linked helpdesk team. Fix: - - Override `_default_team_id` to set the correct Helpdesk Team based on the selected project. - A domain has been added to the team selection field within the timesheet views to only show teams that have the timesheet feature enabled. task-4885679 Forward-Port-Of: odoo/enterprise#89503
Work entries now calculate attendance-based durations correctly for employees on flexible schedules, even when the period starts midweek or covers only part of a day. This prevents holiday-related gaps from being incorrectly recorded as a full 8 hours, improving payroll and attendance accuracy.
Original PR description
### Steps to reproduce: - Set Marc Demo's contract work entry source to attendances and working schedule to flexible hours. - Create a public holiday with generic time off work entry type. - Create…
### Steps to reproduce: - Set Marc Demo's contract work entry source to attendances and working schedule to flexible hours. - Create a public holiday with generic time off work entry type. - Create one or multiple attendances for marc demo on the public holiday. - Regenerate work entries for marc demo for that day, the gaps in between the attendances created and the working hours will be filled with work entries with the right start/end time but duration will always be 8h. ### Cause: This is happening because when getting the duration batch for the work entry we get the attendance intervals the employee should work in that period and if the employee is flexible we will get a fake attendance with the number of hours required per day ignoring if the period is just a small period of the day ### Fix: We are checking now since the start date not monday so we don't set a fixed week start. We check if the period is less than the remaining hours we get it as it mostly means that it is less than one day opw-4887933
Swedish SIE4 imports now complete even when the file does not include previous-year information for opening balances. The importer uses a sensible fallback date and also retries with an alternate character encoding, reducing failed imports for affected accounting files.
Original PR description
**Issue**: Importing a SIE4 file without previous year information causes a traceback. **Steps to reproduce**: - Go to Accounting > Settings > Import - Import SIE 4 file - Check the box "Import account opening balances" - Select the right xml and observe the traceback **Cause**: The method `_prepare_sie4_opening_balance_move` tries to directly access the previous year: https://github.com/odoo-dev/enterprise/blob/6d4919658650a006c73d4aaf1f500d67723dda0d/l10n_se_sie4_import/wizard/import_wizard.py#L376C9-L376C58 This results in a traceback when the previous year is not present. **Solution**: Make `_prepare_sie4_opening_balance_move` more permissive by falling back to the day before the first day of the current year if the `-1` section is not there. **Additional Notes**: The client file does not support `UTF8` format, retry with the `ISO-8859-1` format in case of `UnicodeDecodeError`. opw-4894495 Forward-Port-Of: odoo/enterprise#89425
Fixes an error that could stop users from checking the status of a GSTR-1 return after the related exception email template was deleted. This helps Indian GST reporting workflows continue smoothly instead of showing a system traceback.
Original PR description
Steps to reproduce: - Delete the mail template `GSTR-1 Exception` - Accounting -> Reporting -> GST Return Period - Create a return period, Under GSTR1 click Push to GSTN - Click on the Check Status…
Steps to reproduce:
- Delete the mail template `GSTR-1 Exception`
- Accounting -> Reporting -> GST Return Period
- Create a return period, Under GSTR1 click Push to GSTN
- Click on the Check Status Button
The following RPC is produced:
```py
File "/home/odoo/src/enterprise/l10n_in_reports_gstr/models/gst_return_period.py", line 1261, in button_check_gstr1_status
self.check_gstr1_status()
File "/home/odoo/src/enterprise/l10n_in_reports_gstr/models/gst_return_period.py", line 1345, in check_gstr1_status
act_type_xmlid, advisor_user = self._get_gstr_responsible_activity_and_user()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/l10n_in_reports_gstr/models/gst_return_period.py", line 1271, in _get_gstr_responsible_activity_and_user
act_type = self.env['mail.activity.type'].sudo()._load_records({
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/odoo/models.py", line 5439, in _load_records
xml_ids = [data['xml_id'] for data in data_list if data.get('xml_id')]
^^^^^^^^
AttributeError: 'str' object has no attribute 'get'
```
In this commit, we resolve the above issue and restore the expected output
task-5010701Appointment users can now create appointments from calendar events when the appointment uses a single resource. This removes an access error that previously blocked the booking flow, helping staff schedule appointments without administrator help.
Original PR description
Before this commit, trying to create an appointment through a calendar event as an user will raise an AccessError. This is because in this fix #76653 we needed to make sure the appointment_resource_id is being set on the calendar event and for this we needed to make it readonly. This causes that an user, is not able to get the proper access rights to read on to the 'appointment.booking.line' which is being triggered since inside each booking line, we have an appointment_resource_id which is a many2one to the appointment resource. To fix this, we are adding a sudo on the booking lines when we only have 1 booking line and the appointment resource is set on the calendar event. This way, the user will be able to read the booking lines and create the appointment. opw-4614976 Forward-Port-Of: odoo/enterprise#88373
Repeat website appointment bookings now reuse an existing contact when the same email is provided, instead of creating a duplicate record. This keeps customer data cleaner while respecting company boundaries in multi-company setups.
Original PR description
Booking an appointment on the website creates a new contact. If the same user books again, a duplicate contact is created instead of reusing the existing one. --- **Steps to Reproduce** 1. Book an…
Booking an appointment on the website creates a new contact. If the same user books again, a duplicate contact is created instead of reusing the existing one.
---
**Steps to Reproduce**
1. Book an appointment with a name, email, and phone.
2. Book a second appointment using the same data.
3. A new duplicate contact is created.
---
**Cause:**
In v18, the appointment booking flow lost the fallback email search mechanism that existed in v17. When `_get_customer_partner()` returns empty (anonymous users), the system immediately creates a new partner without checking if one already exists with the same email. This regression causes duplicate contacts to be created for repeat anonymous bookings.
**Root Issue:**
The v17 logic included an email search fallback:
```python
customer = request.env['res.partner'].sudo().search([('email_normalized', '=', email_normalized)], limit=1)
```
This was removed in v18, breaking the partner reuse mechanism.
**Solution:**
Restore the email search logic with multi-company awareness:
1. **Email Search**: When no customer is found, search for existing partners by normalized email
2. **Company Boundaries**: Limit search to partners without a company or belonging to the current company context to prevent cross-company data conflicts
3. **Fallback Creation**: Only create new partners when no compatible existing partner is found
---
This fix restores the fallback email search logic from v17, ensuring anonymous users booking appointments reuse their existing contact records while maintaining proper company data isolation in multi-company environments.
The search is limited to partners without a company or partners belonging to the current company to prevent cross-company data conflicts.
**opw-4614897**