Wednesday, January 29, 2025
20 changes · saas-17.2
Resolved issues and error corrections
Contacts in Morocco can now use valid 8-digit VAT numbers without being incorrectly rejected. This prevents validation errors caused by a third-party library change that confused Moroccan VAT numbers with a different identifier type.
Original PR description
### Steps to reproduce: - Create a new Contact - Set the country to Morocco - Add "52258521" as a VAT number - Try to validate -> Error ### Cause: Only occurs after saas-17.4 because it is related to the library `stdnum`. The version of this library change when the Python version is >3.11. As the SaaS version use Python3.12 since saas-17.4 and Python3.10 before, the bug only appears in saas-17.4, but this change targets 17.0 because 17.0 supports Python > 3.10. The cause of the bug is the new version of the library which implements a verification method that corresponds to Moroccan ICE numbers and not VAT numbers. ### Solution: Create the method to check the Moroccan VAT numbers. The format is just a number with 8 digits. opw-4447478
The eCommerce subscription page now includes translations for period labels such as month, week, and year. This ensures customers see subscription terms in their selected language, improving clarity for multilingual shoppers.
Original PR description
Issue: Translations for terms "month", "year," and "week" are missing in the eCommerce subscription. Steps to reproduce: - Navigate to the website shop. - Pick a subscription product. - Change the language. "month" (along with the other two alternatives) is not translated. opw-4404734
Miscellaneous changes
**Issue:** Sometimes "test_select_sublines_with_same_product_and_lot" tour is failing. **Cause:** It could be due to consecutive actions (scan of the lot) that are executed too quickly. **Solution:** Add an extra step after scanning a lot to check the DOM and wait if necessary before scanning another lot. opw-4208612 Forward-Port-Of: odoo/enterprise#78024 Forward-Port-Of: odoo/enterprise#77998
Original PR description
**Issue:** Sometimes "test_select_sublines_with_same_product_and_lot" tour is failing. **Cause:** It could be due to consecutive actions (scan of the lot) that are executed too quickly. **Solution:** Add an extra step after scanning a lot to check the DOM and wait if necessary before scanning another lot. opw-4208612 Forward-Port-Of: odoo/enterprise#78024 Forward-Port-Of: odoo/enterprise#77998
Since the "new" Chrome's headless mode (default starting with version 128), the tour testing the accounting's bank reconciliation widget fails on some steps while selecting and editing the entry's line amount. More precisely, but without absolute certainty, this looks to be a concurrency issue between the selection of the line, the update of the notebook's form and the focus of the related field (for quick edition). While the failing step relies solely on the field being focused (which
Original PR description
Since the "new" Chrome's headless mode (default starting with version 128), the tour testing the accounting's bank reconciliation widget fails on some steps while selecting and editing the entry's line amount. More precisely, but without absolute certainty, this looks to be a concurrency issue between the selection of the line, the update of the notebook's form and the focus of the related field (for quick edition). While the failing step relies solely on the field being focused (which is finicky on headless browser where the "focus" needs to be emulated), this commit works around this issue by checking on the entry's line selected instead. Note: while being an issue in automated test, the feature operated by an actual user is working properly. Forward-Port-Of: odoo/enterprise#77905 Forward-Port-Of: odoo/enterprise#77644
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: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#77678 Forward-Port-Of: odoo/enterprise#77616
Currently an exception was generated when [1] found as multiple state. error: `ValueError: Expected singleton: res.country.state(1674, 18)` This is because [1] searches the state based on state name, but in many scenario the state name maybe repeated for different country eg. United States of America an Uruguay both has same state 'Florida'  This commit will fix the above issue by add
Original PR description
Currently an exception was generated when [1] found as multiple state. error: `ValueError: Expected singleton: res.country.state(1674, 18)` This is because [1] searches the state based on state name, but in many scenario the state name maybe repeated for different country eg. United States of America an Uruguay both has same state 'Florida'  This commit will fix the above issue by adding country id in searching state so we always get state based on country. [1] - https://github.com/odoo/enterprise/blob/f3957dc33d956f55b77520167fc9b8ce9dad8c43/account_invoice_extract/models/account_invoice.py#L574 Sentry-6130462157 Forward-Port-Of: odoo/enterprise#77166
Using a newly created payslip structure for Mexico it is not possible to generate payslips Steps to reproduce: - With an MX Company setup - Go to Payroll > Configuration > Salary > Structures - Create new structure with the following attributes: - Type: "Mexico: employee" - Country: "Mexico" - Go to Payroll > Payslips > Batches, create a new batch - Click "Generate Payslips" - Select the freshly created salary structure in the wizard, then click "Generate" Issue: An error is ra
Original PR description
Using a newly created payslip structure for Mexico it is not possible to generate payslips Steps to reproduce: - With an MX Company setup - Go to Payroll > Configuration > Salary > Structures - Create new structure with the following attributes: - Type: "Mexico: employee" - Country: "Mexico" - Go to Payroll > Payslips > Batches, create a new batch - Click "Generate Payslips" - Select the freshly created salary structure in the wizard, then click "Generate" Issue: An error is raised while creating the payslip Error: float() argument must be a string or a real number, not 'NoneType' This occurs because we don't have a fallback in `_get_paid_amount` opw-4328900 Forward-Port-Of: odoo/enterprise#77277
Issue: - When creating a SO with two service type products, configured to plan services. When auto planning, only one service gets planned. Steps to reproduce: 1- Create a SO with two service type products. 2- Configure the products to plan services. 3- Confirm the SO. 4- Click on the "To Plan" smart button. 5- Click on the "Auto plan" button. 6- Notice that only one service (the first one) gets planned. Solution: - in `action_view_planning` method, we rely on 'search_defaul
Original PR description
Issue: - When creating a SO with two service type products, configured to plan services. When auto planning, only one service gets planned. Steps to reproduce: 1- Create a SO with two service type products. 2- Configure the products to plan services. 3- Confirm the SO. 4- Click on the "To Plan" smart button. 5- Click on the "Auto plan" button. 6- Notice that only one service (the first one) gets planned. Solution: - in `action_view_planning` method, we rely on 'search_default_role_id' in the context to get our role_id. - however when we have an array of `role_id`, `search_default_` eventually calls `visitField` https://github.com/odoo/odoo/blob/a711818e93fb253d52a8925a9b12540e4d83d798/addons/web/static/src/search/search_arch_parser.js#L132 where we take only the first value of the array. - So I added a domain. opw-4350959 Forward-Port-Of: odoo/enterprise#77724
Whatsapp API doesn't allow to send captions with audio anymore, therefore we should modify the way we handle captions. After this commit audio will be sent first while text message will stay in a composer, it will only be sent after the audio is sent. task-4007616 Forward-Port-Of: odoo/enterprise#66818
Original PR description
Whatsapp API doesn't allow to send captions with audio anymore, therefore we should modify the way we handle captions. After this commit audio will be sent first while text message will stay in a composer, it will only be sent after the audio is sent. task-4007616 Forward-Port-Of: odoo/enterprise#66818
Since version Chrome 128, the "new" headless mode has been set as default but the `payroll_dashboard_ui_tour` failed on a step relying on the "blur" event to update the Todo's name. After very long and quite thorough research what was discovered are the following: - this issue happens only once the `website` module has been installed - the tour is started from "/" (in Python) but actually run from "/web" (in JS), resulting in a useless first load. - the "blur" event triggered by the `text_
Original PR description
Since version Chrome 128, the "new" headless mode has been set as default but the `payroll_dashboard_ui_tour` failed on a step relying on the "blur" event to update the Todo's name. After very long…
Since version Chrome 128, the "new" headless mode has been set as default but the `payroll_dashboard_ui_tour` failed on a step relying on the "blur" event to update the Todo's name.
After very long and quite thorough research what was discovered are the following:
- this issue happens only once the `website` module has been installed
- the tour is started from "/" (in Python) but actually run from "/web" (in JS), resulting in a useless first load.
- the "blur" event triggered by the `text_run ...` tour's command never reaches the `t-on-blur` OWL's handler, while no listener that may have "eaten" the event has been found...
- making the "blur" event bubble (which is not its normal behavior) does have some impact on the issue...
- running the tour directly from the backend (e.g. `start_tour("/web", ...)` doesn't present this issue.
While the exact root cause of this issue hasn't been identified so fare, this commit sets the tour to be run directly from the backend (which makes sense as it is a backend-only test tour anyway) as a workaround.
Note: while being an issue in automated test, the feature operated by an actual user looks to be working properly.
Forward-Port-Of: odoo/enterprise#77823Steps to reproduce: - Create a new accounting report - Create a new line - Set a value in the groupby field -> A warning appears, stating that the line uses a custom user-defined "group by" value. This warning is only useful when modifying a groupby value for a line that has a xmlid. task-4286306 Forward-Port-Of: odoo/enterprise#74526
Original PR description
Steps to reproduce: - Create a new accounting report - Create a new line - Set a value in the groupby field -> A warning appears, stating that the line uses a custom user-defined "group by" value. This warning is only useful when modifying a groupby value for a line that has a xmlid. task-4286306 Forward-Port-Of: odoo/enterprise#74526
Issue ----- The "Import FEC" button is only visible when in a company set in France, despite the localization being installed. Steps to reproduce ----- - Install Accounting & the French accounting localization - Settings > Accounting > Import Cause ----- The FEC import button is specified in the base import, and only visible when the company country code is set to France. If the localization isn't installed, it prompts the user to do so. As per the PO, we want the button to be prese
Original PR description
Issue ----- The "Import FEC" button is only visible when in a company set in France, despite the localization being installed. Steps to reproduce ----- - Install Accounting & the French accounting localization - Settings > Accounting > Import Cause ----- The FEC import button is specified in the base import, and only visible when the company country code is set to France. If the localization isn't installed, it prompts the user to do so. As per the PO, we want the button to be present when the localization is installed, regardless of the country of the company. ----- Ticket: opw-4356726 Forward-Port-Of: odoo/enterprise#76235
This commit adds 2025 codes based on https://www.nbb.be/en/statistics/foreign-trade/nomenclature-and-codes Task: 4461223 Forward-Port-Of: odoo/enterprise#77666
Original PR description
This commit adds 2025 codes based on https://www.nbb.be/en/statistics/foreign-trade/nomenclature-and-codes Task: 4461223 Forward-Port-Of: odoo/enterprise#77666
This PR fixes an issue about the `$o-color-original` color map values sometimes not matching the light mode one. | //////// | saas-16.3 and above | This PR | |--------|--------|--------| | Light mode |  |  | | Dark mode |  |  |  | | Dark mode |  |  | When we introduced the redesign of the dark mode with Milk (`saas-16.3`), we fine-tuned the badges design in dark mode by slightly tweaking some colors from the `$o-color-original` map, which contains the colors that will be used on badges (as well as other UI elements). While most of the colors were normally tweaked, some colors received a new hue value, meaning the color would not match the light mode one. As this is inconsistent and unexpected, we review the colors to match the light mode ones. task-4522539 Forward-Port-Of: odoo/enterprise#77989
**Problem**: The cropper buttons are positioned at the end of the page instead of directly under the image being cropped. **Solution**: Remove `position: fixed` from the buttons container, allowing it to be positioned just below the image being cropped/edited. **Steps to Reproduce**: 1. Navigate to Email Marketing > Start from scratch. 2. Add "Blocks" > "Body" > "Columns". 3. Open the cropping tool on the first image. 4. Observe that the cropping buttons appear at the end of the page
Original PR description
**Problem**: The cropper buttons are positioned at the end of the page instead of directly under the image being cropped. **Solution**: Remove `position: fixed` from the buttons container, allowing it to be positioned just below the image being cropped/edited. **Steps to Reproduce**: 1. Navigate to Email Marketing > Start from scratch. 2. Add "Blocks" > "Body" > "Columns". 3. Open the cropping tool on the first image. 4. Observe that the cropping buttons appear at the end of the page, requiring scrolling to access them. opw-4461565 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#193016
Since render.qweb was replaced by renderToElement, the spam input search crashes if more than one post meets the search. This commit renders a fragment instead of an element to bypass this limitation. Steps to reproduce: - Connect as Admin - Flag 2 posts on the forum ("..." at the bottom of a post > Flag) - Go to the flagged posts in the moderation tools (left bar) - Click on "Filter Tool" - Select the "Text" tab - Type "e" (to select both posts) => Traceback. (No linked task) Forwa
Original PR description
Since render.qweb was replaced by renderToElement, the spam input search crashes if more than one post meets the search. This commit renders a fragment instead of an element to bypass this limitation.
Steps to reproduce:
- Connect as Admin
- Flag 2 posts on the forum ("..." at the bottom of a post > Flag)
- Go to the flagged posts in the moderation tools (left bar)
- Click on "Filter Tool"
- Select the "Text" tab
- Type "e" (to select both posts) => Traceback.
(No linked task)
Forward-Port-Of: odoo/odoo#191389### Steps to reproduce: - Create a new Contact - Set the country to Morocco - Add "52258521" as a VAT number - Try to validate -> Error ### Cause: Only occurs after saas-17.4 because it is related to the library `stdnum`. The version of this library change when the Python version is >3.11. As the SaaS version use Python3.12 since saas-17.4 and Python3.10 before, the bug only appears in saas-17.4, but this change targets 17.0 because 17.0 supports Python > 3.10. The cause of the bug i
Original PR description
### Steps to reproduce: - Create a new Contact - Set the country to Morocco - Add "52258521" as a VAT number - Try to validate -> Error ### Cause: Only occurs after saas-17.4 because it is related to the library `stdnum`. The version of this library change when the Python version is >3.11. As the SaaS version use Python3.12 since saas-17.4 and Python3.10 before, the bug only appears in saas-17.4, but this change targets 17.0 because 17.0 supports Python > 3.10. The cause of the bug is the new version of the library which implements a verification method that corresponds to Moroccan ICE numbers and not VAT numbers. ### Solution: Create the method to check the Moroccan VAT numbers. The format is just a number with 8 digits. opw-4447478 Forward-Port-Of: odoo/odoo#194592
Fix the error displayed error. The current code causes a key error. task-no Forward-Port-Of: odoo/odoo#195388
Original PR description
Fix the error displayed error. The current code causes a key error. task-no Forward-Port-Of: odoo/odoo#195388
Versions -------- - 17.0+ Steps ----- 1. Enable Wire Transfer as a payment provider; 2. in eCommerce, add an item to cart; 3. go to checkout; 4. pay via wire transfer. Issue ----- The order reference isn't shown below the "Thank you for your order" message because the payment transaction hasn't been approved yet. Solution -------- Show the order reference regardless of transaction status. opw-3844583 Forward-Port-Of: odoo/odoo#195228
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Enable Wire Transfer as a payment provider; 2. in eCommerce, add an item to cart; 3. go to checkout; 4. pay via wire transfer. Issue ----- The order reference isn't shown below the "Thank you for your order" message because the payment transaction hasn't been approved yet. Solution -------- Show the order reference regardless of transaction status. opw-3844583 Forward-Port-Of: odoo/odoo#195228
Versions -------- - 17.0+ Steps ----- 1. Ensure `geoip` works (or patch the `_get_geoip_country_code` method); 2. create two pricelists for the website; 3. first should be restricted to EU countries & use EUR; 4. second one shouldn't be restricted to any country & use USD; 5. log in as a Portal user without address details from a EU IP; 6. open the shop. Issue ----- The prices are displayed in USD. Cause ----- The geoip country is taken into account for public users, but no
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Ensure `geoip` works (or patch the `_get_geoip_country_code` method); 2. create two pricelists for the website; 3. first should be restricted to EU countries & use EUR; 4. second one shouldn't be restricted to any country & use USD; 5. log in as a Portal user without address details from a EU IP; 6. open the shop. Issue ----- The prices are displayed in USD. Cause ----- The geoip country is taken into account for public users, but not for partners. Instead it relies on the partner's country_id, which could be empty. Solution -------- When computing the `property_product_pricelist`, add the geoip country to the context. Use this value in the fallback for partners without specific pricelist property set, and without a `country_id`. opw-4398543 Forward-Port-Of: odoo/odoo#194885