Friday, January 31, 2025
23 changes · master
Enhancements to existing features
This update standardizes how Odoo detects when it is running in test mode. It helps several business areas avoid test-only behavior affecting normal operations and makes automated validation more reliable.
Original PR description
A flag on the configuration that indicates whether Odoo was started in a test mode. However, sometimes it is enough to check that we are in the test mode. task-4270485 odoo/odoo#186924
Accounting menu options that open a popup now show an ellipsis, making it clearer to users that another step or confirmation will follow. This improves usability and helps reduce surprises when working with lock dates or 1099 generation.
The map view now updates record ordering using a newer server call that also refreshes the data in the same step. This reduces unnecessary back-and-forth with the server and should make reorder operations in maps more efficient without changing the user workflow.
Original PR description
This commit replaces the use of /web/dataset/resequence by the new web_resequence which does a resequence and a read in one RPC. task-3790638
Resolved issues and error corrections
The WhatsApp Calendar test setup now includes a default phone number for the admin contact. This prevents test failures when demo data is not installed, helping keep quality checks reliable across environments.
Original PR description
Problem: When test cases run without demo data, the admin's phone number is not set, causing `_find_value_from_field_path` to return `''` while creating a WhatsApp message record. This is compared with `False` in the test, leading to a failure. Solution: Set a default phone number for the admin partner in the test setup to ensure consistent behavior regardless of demo data availability.
Code cleanup and technical improvements
This update keeps several website sales features working correctly after changes in the core online shop system. It affects cart, pricing, tax, delivery, rental, appointment, subscription, and localization flows so customers continue to see accurate options during checkout.
Miscellaneous changes
The aim of this commit is to avoid having inconsistent data leading to a Traceback while loading the lines of the Profit and Loss report. Context: cbe74884b937f630cf1d2ccf475a04e70b6f4669 changed the structure hierachy. It wasn't a big issue until e96e8d4aa663a4a5305214f2124243070fa797bb resequenced the lines and changed the order of computation in `<account.report>._get_line`. This method assumes the parent lines are going to be computed first and then cached in a dict. Leaving `parent_id`
Original PR description
The aim of this commit is to avoid having inconsistent data leading to a Traceback while loading the lines of the Profit and Loss report. Context: cbe74884b937f630cf1d2ccf475a04e70b6f4669 changed the structure hierachy. It wasn't a big issue until e96e8d4aa663a4a5305214f2124243070fa797bb resequenced the lines and changed the order of computation in `<account.report>._get_line`. This method assumes the parent lines are going to be computed first and then cached in a dict. Leaving `parent_id` made this assumption wrong leading to a KeyError exception throwing a traceback. Before the commit: The data kept the previous `parent_id` which could lead to a traceback due to inconsistent data. After the commit: `parent_id` not being set, the code doesn't try to get it from the cached lines and computes it correctly. task-id: None Forward-Port-Of: odoo/enterprise#78219
This fixes the sales spreadsheet integration so it continues to work after recent spreadsheet platform changes. Business users should see field highlighting and synchronization behave as expected when working with sales-related spreadsheets.
Original PR description
See: - https://github.com/odoo/odoo/pull/195935 - https://github.com/odoo/o-spreadsheet/commit/7c179b457383fff716156acc216ca34999eaa85d
Original PR description
The access to the cart, pricelist and fiscal position have been changed in the base `website_sale` module. This commits adapts existing code and tests to use the right tools and work as expected.
### Steps to reproduce the issue: 1. Create an clean Analytic Account and use it in a Budget 2. Create a Purchase Order with Analytic Account in the Distribution and a Discount then Confirm 3. In the Budget report, the Committed Amount does not include the Discount ### Explanation: In the `purchase.order.line` side of the calculation of the committed amount of the budget report, we are using `unit_price` as base, because of it having a `not null` constraint, then adding a lot of other
Original PR description
### Steps to reproduce the issue: 1. Create an clean Analytic Account and use it in a Budget 2. Create a Purchase Order with Analytic Account in the Distribution and a Discount then Confirm 3. In the Budget report, the Committed Amount does not include the Discount ### Explanation: In the `purchase.order.line` side of the calculation of the committed amount of the budget report, we are using `unit_price` as base, because of it having a `not null` constraint, then adding a lot of other variables to extract the correct amount: `currency_rate`, `analytic_distribution`, `product_qty` and `qty_invoiced`. This does not include `discount` nor price-included `taxes_id`. ### Fix reasoning: To avoid an issue regarding down payment lines, which have no `price_subtotal`, we will prioritize the field with a fallback on `price_unit`. opw-4391098 Forward-Port-Of: odoo/enterprise#75902
Envia is a delivery aggregator for North and South America that supports a large subset of carriers in the area. It integrates with the main carriers used in: Argentina, Australia, Brazil, Canada, Chile, Colombia, Spain, Guatemala, India, Mexico, Peru, United States, and Uruguay task-4056309 odoo PR: https://github.com/odoo/odoo/pull/174098 Forward-Port-Of: odoo/enterprise#78214 Forward-Port-Of: odoo/enterprise#67131
Original PR description
Envia is a delivery aggregator for North and South America that supports a large subset of carriers in the area. It integrates with the main carriers used in: Argentina, Australia, Brazil, Canada, Chile, Colombia, Spain, Guatemala, India, Mexico, Peru, United States, and Uruguay task-4056309 odoo PR: https://github.com/odoo/odoo/pull/174098 Forward-Port-Of: odoo/enterprise#78214 Forward-Port-Of: odoo/enterprise#67131
In this pr: https://github.com/odoo/enterprise/pull/70591 we added a way to add credit card account but forgot to change some domains in the online synchronisation menu. no-task-id Forward-Port-Of: odoo/enterprise#77672
Original PR description
In this pr: https://github.com/odoo/enterprise/pull/70591 we added a way to add credit card account but forgot to change some domains in the online synchronisation menu. no-task-id Forward-Port-Of: odoo/enterprise#77672
When trying to print invoice before reveiving etims details by the gouvernment, we get an error because we're trying to access some attributes of those fields, such as `strftime` or `len()` With this commit, we replace non set fields by empty strings either for display purpose or methods calls. opw-4480304 Forward-Port-Of: odoo/enterprise#78176
Original PR description
When trying to print invoice before reveiving etims details by the gouvernment, we get an error because we're trying to access some attributes of those fields, such as `strftime` or `len()` With this commit, we replace non set fields by empty strings either for display purpose or methods calls. opw-4480304 Forward-Port-Of: odoo/enterprise#78176
**Specifications:** - remove modal when user click on open desk and directly open kiosk view. - add an install button in menu-item in kanban card **After this PR:** Modal will be removed while opening kiosk mode in frontdesk Task-4161336 Forward-Port-Of: odoo/enterprise#71018
Original PR description
**Specifications:** - remove modal when user click on open desk and directly open kiosk view. - add an install button in menu-item in kanban card **After this PR:** Modal will be removed while opening kiosk mode in frontdesk Task-4161336 Forward-Port-Of: odoo/enterprise#71018
The issue was that payment lines with `is_change` were also being considered in the computation. Exemple: Product: 14.50 Payment: 20.00 Change: 5.50 Forward-Port-Of: odoo/enterprise#76476
Original PR description
The issue was that payment lines with `is_change` were also being considered in the computation.
Exemple:
Product: 14.50
Payment: 20.00
Change: 5.50
Forward-Port-Of: odoo/enterprise#76476Before this commit, opening the calendar event Gantt view called the `calendar.event` model, but the `appointment.type` ID was passed. This mismatch could lead to an error when attempting to load the view. opw-4493685 Forward-Port-Of: odoo/enterprise#77694 Forward-Port-Of: odoo/enterprise#77447
Original PR description
Before this commit, opening the calendar event Gantt view called the `calendar.event` model, but the `appointment.type` ID was passed. This mismatch could lead to an error when attempting to load the view. opw-4493685 Forward-Port-Of: odoo/enterprise#77694 Forward-Port-Of: odoo/enterprise#77447
Version: - 17.0 Steps to reproduce: - Install the Sign module. - Try to open a sample document. Issue: - An access error occurs when a "Sign User" tries to access a demo sign template. Solution: - Allow internal users to access sample data. task- 4390945 Forward-Port-Of: odoo/enterprise#77933 Forward-Port-Of: odoo/enterprise#75522
Original PR description
Version: - 17.0 Steps to reproduce: - Install the Sign module. - Try to open a sample document. Issue: - An access error occurs when a "Sign User" tries to access a demo sign template. Solution: - Allow internal users to access sample data. task- 4390945 Forward-Port-Of: odoo/enterprise#77933 Forward-Port-Of: odoo/enterprise#75522
When the user tries to forward a Google Maps location in a message, a traceback will appear. Steps to reproduce the error: - Go to WhatsApp > Templates > Create a new template A > Header Type: Location - Set a Body message > In Variables, Set the sample values for all the variables - Create a new Contact with a Mobile number > Send a Whatsapp message with template A - User will receive a message with a link of location > Forward that message back to that number Traceback: ``` File "
Original PR description
When the user tries to forward a Google Maps location in a message, a traceback will appear. Steps to reproduce the error: - Go to WhatsApp > Templates > Create a new template A > Header Type:…
When the user tries to forward a Google Maps location in a message,
a traceback will appear.
Steps to reproduce the error:
- Go to WhatsApp > Templates > Create a new template A > Header Type: Location
- Set a Body message > In Variables, Set the sample values for all the variables
- Create a new Contact with a Mobile number > Send a Whatsapp message with template A
- User will receive a message with a link of location > Forward that message back to that number
Traceback:
```
File "/home/odoo/odoo/enterprise/whatsapp/controller/main.py", line 42, in webhookpost
wa_account_id._process_messages(value)
File "/home/odoo/odoo/enterprise/whatsapp/models/whatsapp_account.py", line 225, in _process_messages
body += Markup("<br/>{location_address}").format(location_name=messages['location']['address'])
File "/home/odoo/.local/lib/python3.10/site-packages/markupsafe/__init__.py", line 213, in format
return self.__class__(formatter.vformat(self, args, kwargs))
File "/usr/lib/python3.10/string.py", line 165, in vformat
result, _ = self._vformat(format_string, args, kwargs, used_args, 2)
File "/usr/lib/python3.10/string.py", line 205, in _vformat
obj, arg_used = self.get_field(field_name, args, kwargs)
File "/usr/lib/python3.10/string.py", line 270, in get_field
obj = self.get_value(first, args, kwargs)
File "/usr/lib/python3.10/string.py", line 227, in get_value
return kwargs[key]
File "/home/odoo/.local/lib/python3.10/site-packages/markupsafe/__init__.py", line 249, in __getitem__
return self._kwargs[key]
KeyError: 'location_address'
```
https://github.com/odoo/enterprise/blob/2b4acb4c82a7374d45f25a7d8eebdc53b7f6e140/whatsapp/models/whatsapp_account.py#L225
Here, ``location_name`` is used instead of ``location_address``,
So, It will lead to the above traceback.
sentry-6206183097
Forward-Port-Of: odoo/enterprise#76883Migrated method to get the SAT status for EDI documents to zeep library. This because the old way have some errors when the VAT have some `Ñ`. The old way returns: Params: `<![CDATA[?id=E5E54D9B-8A18-4FD4-ACE4-135B6B7E7960&re=NSE111011M99&rr=LEÑ131002PN2&tt=552.99]]>` Response: ```<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:DeserializationFaile
Original PR description
Migrated method to get the SAT status for EDI documents to zeep library. This because the old way have some errors when the VAT have some `Ñ`. The old way returns: Params:…
Migrated method to get the SAT status for EDI documents to zeep library. This because the old way have some errors when the VAT have some `Ñ`. The old way returns: Params: `<![CDATA[?id=E5E54D9B-8A18-4FD4-ACE4-135B6B7E7960&re=NSE111011M99&rr=LEÑ131002PN2&tt=552.99]]>` Response: ```<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:DeserializationFailed</faultcode><faultstring xml:lang="en-US">The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:expresionImpresa. The InnerException message was \'There was an error deserializing the object of type System.String. \'�131002PN2&tt=552.99\' contains invalid UTF8 bytes.\'. Please see InnerException for more details.</faultstring><detail><ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><HelpLink i:nil="true"/><InnerException><HelpLink i:nil="true"/><InnerException><HelpLink i:nil="true"/><InnerException><HelpLink i:nil="true"/><InnerException i:nil="true"/><Message>Unable to translate bytes [D1] at index 0 from specified code page to Unicode.</Message><StackTrace> at System.Text.DecoderExceptionFallbackBuffer.Throw(Byte[] bytesUnknown, Int32 index)
\n at System.Text.DecoderExceptionFallbackBuffer.Fallback(Byte[] bytesUnknown, Int32 index)
\n at System.Text.DecoderFallbackBuffer.InternalFallback(Byte[] bytes, Byte* pBytes, Char*& chars)
\n at System.Text.UTF8Encoding.GetChars(Byte* bytes, Int32 byteCount, Char* chars, Int32 charCount, DecoderNLS baseDecoder)
\n at System.Text.UTF8Encoding.GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteCount, Char[] chars, Int32 charIndex)
\n at System.Xml.XmlConverter.ToChars(Byte[] buffer, Int32 offset, Int32 count, Char[] chars, Int32 charOffset)</StackTrace><Type>System.Text.DecoderFallbackException</Type></InnerException><Message>\'�131002PN2&tt=552.99\' contains invalid UTF8 bytes.</Message><StackTrace> at System.Xml.XmlConverter.ToChars(Byte[] buffer, Int32 offset, Int32 count, Char[] chars, Int32 charOffset)
\n at System.Xml.XmlBufferReader.GetChars(Int32 offset, Int32 length, Char[] chars)
\n at System.Xml.XmlBufferReader.GetString(Int32 offset, Int32 length)
\n at System.Xml.ValueHandle.GetString()
\n at System.Xml.XmlBaseReader.get_Value()
\n at System.Xml.XmlDictionaryReader.ReadContentAsString(Int32 maxStringContentLength)
\n at System.Xml.XmlBaseReader.ReadElementContentAsString()
\n at System.Runtime.Serialization.StringDataContract.ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
\n at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)</StackTrace><Type>System.Xml.XmlException</Type></InnerException><Message>There was an error deserializing the object of type System.String. \'�131002PN2&tt=552.99\' contains invalid UTF8 bytes.</Message><StackTrace> at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
\n at System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)
\n at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.PartInfo.ReadObject(XmlDictionaryReader reader, XmlObjectSerializer serializer)
\n at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)</StackTrace><Type>System.Runtime.Serialization.SerializationException</Type></InnerException><Message>The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:expresionImpresa. The InnerException message was \'There was an error deserializing the object of type System.String. \'�131002PN2&tt=552.99\' contains invalid UTF8 bytes.\'. Please see InnerException for more details.</Message><StackTrace> at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)
\n at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, Object[] parameters, Boolean isRequest)
\n at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)
\n at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
\n at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)
\n at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
\n at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
\n at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
\n at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace><Type>System.ServiceModel.Dispatcher.NetDispatcherFaultException</Type></ExceptionDetail></detail></s:Fault></s:Body></s:Envelope>' ``` Forward-Port-Of: odoo/enterprise#78031 Forward-Port-Of: odoo/enterprise#77616
At the moment, when grouping by a selection field, the in-database name of the selection option is shown rather than the human-readable name. This is fixed by the present commit. task-none Forward-Port-Of: odoo/enterprise#78153 Forward-Port-Of: odoo/enterprise#78128
Original PR description
At the moment, when grouping by a selection field, the in-database name of the selection option is shown rather than the human-readable name. This is fixed by the present commit. task-none Forward-Port-Of: odoo/enterprise#78153 Forward-Port-Of: odoo/enterprise#78128
This commit adapts a test to cope with changes made in https://github.com/odoo/odoo/pull/195630. task-4523387 Forward-Port-Of: odoo/enterprise#78162
Original PR description
This commit adapts a test to cope with changes made in https://github.com/odoo/odoo/pull/195630. task-4523387 Forward-Port-Of: odoo/enterprise#78162
Due to an oversight when migrating documents share to documents in Sharepocalypse, documents were being deleted when their related website was deleted. This is not a desired behavior. Even though setting the "correct" website is possible (and desired) when there is a `company_id`, there is no problem with having empty `website_id` in the other case. opw-4494091 Forward-Port-Of: odoo/enterprise#78163
Original PR description
Due to an oversight when migrating documents share to documents in Sharepocalypse, documents were being deleted when their related website was deleted. This is not a desired behavior. Even though setting the "correct" website is possible (and desired) when there is a `company_id`, there is no problem with having empty `website_id` in the other case. opw-4494091 Forward-Port-Of: odoo/enterprise#78163
**Issue** When sending a subscription payment reminder, customers were incorrectly notified to pay the full amount (amount_total) instead of the amount corresponding to subscription orders (recurring_total) only. This issue also occurs in cases of payment failure. opw-4224746 Forward-Port-Of: odoo/enterprise#75319
Original PR description
**Issue** When sending a subscription payment reminder, customers were incorrectly notified to pay the full amount (amount_total) instead of the amount corresponding to subscription orders (recurring_total) only. This issue also occurs in cases of payment failure. opw-4224746 Forward-Port-Of: odoo/enterprise#75319
- make kiosk mode open in the same page and logout the user to avoid unwanted rights Task: 4509632 Forward-Port-Of: odoo/enterprise#77852
Original PR description
- make kiosk mode open in the same page and logout the user to avoid unwanted rights Task: 4509632 Forward-Port-Of: odoo/enterprise#77852
Currently, simple pos users can see the due amount of the customers, unless the customer wasn't loaded and we need to search for a customer that isn't loaded. Steps to reproduce: ------------------- * Create a new customer, make a sale order and invoice it. This will set an amount due for that customer * Connect to the shop with a user that has the `point_of_sale.group_pos_user` but not the `account.group_account_readonly` group * Open customer list > Observation: You can see the amount
Original PR description
Currently, simple pos users can see the due amount of the customers, unless the customer wasn't loaded and we need to search for a customer that isn't loaded. Steps to reproduce: -------------------…
Currently, simple pos users can see the due amount of the customers, unless the customer wasn't loaded and we need to search for a customer that isn't loaded. Steps to reproduce: ------------------- * Create a new customer, make a sale order and invoice it. This will set an amount due for that customer * Connect to the shop with a user that has the `point_of_sale.group_pos_user` but not the `account.group_account_readonly` group * Open customer list > Observation: You can see the amount due for multiple customers * Search for the customer created * Select search more > You can't see the amount due for that customer Why the fix: ------------ Since simple pos users are allowed to see the amount due for the loaded customer, there is no reason they shouldn't see it as well for a customer they need to load. Commit allowing simple pos users to see (and settle) customer accounts: https://github.com/odoo/enterprise/commit/37fa4d5f4ed7c7d77f73395a53b7b3ab7006afc4 When loading the pos session `_loader_params_res_partner` is called first and later is called `_get_pos_ui_res_partner`. It is in the function `_get_pos_ui_res_partner` that the amount due is compted if the user does not belong to the group `account.group_account_readonly`. https://github.com/odoo/enterprise/blob/a35a4755cdf86bcfeda0aca6c06397748ba27362/pos_settle_due/models/pos_session.py#L22-L28 However when we load a customer that wasn't previously loaded, only `_loader_params_res_partner` is loaded. And since the users does not belong to the group `account.group_account_readonly`, the field witll not get loaded. We now compute the amount due with the same logic as in `_get_pos_ui_res_partner`. opw-4141955 Forward-Port-Of: odoo/enterprise#77660 Forward-Port-Of: odoo/enterprise#73671