Daily updates from Odoo
Navigate
Branch
Saturday, May 17, 2025
49 changes
34 changes
Enhancements to existing features
Budget users can now view budgets in a grouped hierarchy with totals and subtotals while editing directly from the main list. This makes budget review and adjustments easier by keeping the financial rollups visible during updates.
Original PR description
Enable the new groupby hierarchy on the budgets: * new widget in search view * allow editing the budgets from the main list view to allow having the totals/subtotals in the hierarchy while editing.
Spreadsheet-related features now use a newer, shorter identifier generator. This is an internal efficiency improvement that can reduce generated data size without changing how users work with spreadsheets.
Original PR description
Since https://github.com/odoo/o-spreadsheet/pull/5704, a new uuid generator has been added to spreadsheet, with the benefit of being smaller and more efficient than the previous one. This commit updates the code to use the new uuid generator instead of the old one. Task: 4709008
Resolved issues and error corrections
Backorders for make-to-order deliveries no longer trigger an extra procurement that incorrectly increases the related purchase order quantity. This prevents over-ordering when customers receive a partial delivery and the remaining quantity is backordered.
Original PR description
### Steps to reproduce: - In the settings enable Multi-Step routes - Unarchive the MTO route - Create a storable product using the MTO and buy route - Create and confirm a sale order for 100 units of…
### Steps to reproduce: - In the settings enable Multi-Step routes - Unarchive the MTO route - Create a storable product using the MTO and buy route - Create and confirm a sale order for 100 units of that product - Validate the delivery for only 30 units and backorder the rest #### > The purchase order demand was updated to 170 units ### Cause of the issue: Since the refactoring a72382063ee662010729d983fbf6fb6305b8adf2 the rule of the MTO route is purely MTO. Furthermore, the moves creating and running a procurement are added depending solely on their procure_method during the `_action_confirm`: https://github.com/odoo/odoo/blob/1dd360658222c0afeb268a5c8cf435defddf55d1/addons/stock/models/stock_move.py#L1485-L1496 https://github.com/odoo/odoo/blob/1dd360658222c0afeb268a5c8cf435defddf55d1/addons/stock/models/stock_move.py#L1503-L1513 In our use case, the delivery move is therefore created as `mto` and then creates and run a procurments creating the PO during its confirmation. However, when it is backordered, the backorder move is also created and confirmed as `mto` by the `_create_backorder` call: https://github.com/odoo/odoo/blob/02a370a7a34a42f2bc9f668eee756fb466db8722/addons/stock/models/stock_move.py#L2071-L2075 It will therefore also automatically create and run a procurment that will in turn modify the current PO. opw-4633920
Code cleanup and technical improvements
This update removes an old internal date interval helper and moves affected areas to newer shared date and scheduling utilities. It should not change day-to-day workflows, but it reduces maintenance risk and improves consistency across appointments, planning, HR, payroll, manufacturing, and reporting features.
Original PR description
odoo/odoo#207882
Miscellaneous changes
This commit adds the possibility to delete a partner_id on a statement line in kanban view. task-4782348 Forward-Port-Of: odoo/enterprise#85379
Original PR description
This commit adds the possibility to delete a partner_id on a statement line in kanban view. task-4782348 Forward-Port-Of: odoo/enterprise#85379
Currently a traceback occurs if no QST instutions were defined, making it hard for users to understand where the error is coming from, in this PR we specify the missing institution. Forward-Port-Of: odoo/enterprise#85148 Forward-Port-Of: odoo/enterprise#85104
Original PR description
Currently a traceback occurs if no QST instutions were defined, making it hard for users to understand where the error is coming from, in this PR we specify the missing institution. Forward-Port-Of: odoo/enterprise#85148 Forward-Port-Of: odoo/enterprise#85104
This commit will remove the check on the existence of the partner id because we want to have the line that have no partner. In this example: - In the first journal you create a statement line with 100 and do an internal transfer - in the second journal you should be able to reconcile it but since the line has no partner it wasn't in the view. no task id Forward-Port-Of: odoo/enterprise#85568
Original PR description
This commit will remove the check on the existence of the partner id because we want to have the line that have no partner. In this example: - In the first journal you create a statement line with 100 and do an internal transfer - in the second journal you should be able to reconcile it but since the line has no partner it wasn't in the view. no task id Forward-Port-Of: odoo/enterprise#85568
When dealing with statements with communication type 113 (ATM/POS debit), the partner is actually "hidden" in the communication field. We use this to retrieve a potential `partner_name` (name + city of vendor) that we can match to a real partner in the database. [format_description_CODA.pdf](https://github.com/user-attachments/files/20080995/format_description_CODA.pdf) opw-4653293 Forward-Port-Of: odoo/enterprise#84942 Forward-Port-Of: odoo/enterprise#84311
Original PR description
When dealing with statements with communication type 113 (ATM/POS debit), the partner is actually "hidden" in the communication field. We use this to retrieve a potential `partner_name` (name + city of vendor) that we can match to a real partner in the database. [format_description_CODA.pdf](https://github.com/user-attachments/files/20080995/format_description_CODA.pdf) opw-4653293 Forward-Port-Of: odoo/enterprise#84942 Forward-Port-Of: odoo/enterprise#84311
…artner rank Use customer_rank and supplier_rank to determine whether the receivable or payable button should be shown as the default action. The less relevant action is moved to the dropdown. task-4749341 Forward-Port-Of: odoo/enterprise#85153
Original PR description
…artner rank Use customer_rank and supplier_rank to determine whether the receivable or payable button should be shown as the default action. The less relevant action is moved to the dropdown. task-4749341 Forward-Port-Of: odoo/enterprise#85153
When reconciling an invoice and payment in foreign currency on different dates, an exchange rate difference line is added. This results in more than one value in `reconciled_lines_ids`, and `moveData()` no longer resolves a link to the move, so the bank statement is shown instead. This commit introduces a non-stored computed field to filter out exchange difference lines from `reconciled_lines_ids`. The kanban now uses this filtered field as a fallback when the reconciled lines are ambig
Original PR description
When reconciling an invoice and payment in foreign currency on different dates, an exchange rate difference line is added. This results in more than one value in `reconciled_lines_ids`, and `moveData()` no longer resolves a link to the move, so the bank statement is shown instead. This commit introduces a non-stored computed field to filter out exchange difference lines from `reconciled_lines_ids`. The kanban now uses this filtered field as a fallback when the reconciled lines are ambiguous. Steps to reproduce: 1. Enable a foreign currency and create two rates on different dates. 2. Create an invoice on one of the dates and a transaction to pay it on the other. 3. Reconcile them. task-4749264 Forward-Port-Of: odoo/enterprise#84424
[IMP] account_accountant: limit models to show in bank reco widget We should only show reco models that should be applicable on the lines. And so, checking the partner/label/... so they match the values that are set on the reco model (or they are left empty on the model). We also moved this part to the new service. [FIX] account_accountant: applying counterpart with partner + account Before this commit, applying a reconciliation model with a counterpart that has a partner and an a
Original PR description
[IMP] account_accountant: limit models to show in bank reco widget We should only show reco models that should be applicable on the lines. And so, checking the partner/label/... so they match the…
[IMP] account_accountant: limit models to show in bank reco widget We should only show reco models that should be applicable on the lines. And so, checking the partner/label/... so they match the values that are set on the reco model (or they are left empty on the model). We also moved this part to the new service. [FIX] account_accountant: applying counterpart with partner + account Before this commit, applying a reconciliation model with a counterpart that has a partner and an account would never apply the partner. It's counterintuitive. If you apply a model that creates that counterpart, you would expect this partner to be put on the line. [FIX] account_accountant: Limit models visible on wizard Before, only button reconciliation models were visible in the manual reconciliation wizard. This filter was removed as the button mode got removed but we still don't want every model to be visible. So now, we filter the reconciliation models shown there based on the partner and the amount. Also removed some fields that don't exist on the reconciliation widget anymore to avoid traceback. We will need to decide later what to do with the to_check field task-4760590 Forward-Port-Of: odoo/enterprise#85455
The _compute_l10n_mx_edi_cfdi_cancel_id method is calling the following search https://github.com/odoo/enterprise/blob/fd01cf3d57109424725727d7eb40afbe34ef67a9/l10n_mx_edi/models/account_move.py#L685-L691 ```python move.l10n_mx_edi_cfdi_cancel_id = move.search([ ('l10n_mx_edi_cfdi_origin', '=like', f'04|{move.l10n_mx_edi_cfdi_uuid}%'), ('company_id', '=', move.company_id.id)], limit=1, ) ``` It is generating the following sql query ```sql SE
Original PR description
The _compute_l10n_mx_edi_cfdi_cancel_id method is calling the following search…
The _compute_l10n_mx_edi_cfdi_cancel_id method is calling the following search
https://github.com/odoo/enterprise/blob/fd01cf3d57109424725727d7eb40afbe34ef67a9/l10n_mx_edi/models/account_move.py#L685-L691
```python
move.l10n_mx_edi_cfdi_cancel_id = move.search([
('l10n_mx_edi_cfdi_origin', '=like', f'04|{move.l10n_mx_edi_cfdi_uuid}%'),
('company_id', '=', move.company_id.id)],
limit=1,
)
```
It is generating the following sql query
```sql
SELECT id
FROM account_move
WHERE l10n_mx_edi_cfdi_origin :: text LIKE '04|55555-5555-5555-5555-555%'
AND company_id = 1
ORDER BY date DESC,
name DESC,
invoice_date DESC,
id DESC
LIMIT 1
```
Running a analyze for a database with ~7M of `account_move` records the result is
```txt
Limit (cost=73029.67..137055.68 rows=1 width=26) (actual time=1610.419..1637.035 rows=0 loops=1)
-> Incremental Sort (cost=73029.67..649263.71 rows=9 width=26) (actual time=1600.475..1627.091 rows=0 loops=1)
Sort Key: date DESC, name DESC, invoice_date DESC, id DESC
Presorted Key: date
Full-sort Groups: 1 Sort Method: quicksort Average Memory: 25kB Peak Memory: 25kB
-> Gather Merge (cost=1000.46..649263.30 rows=9 width=26) (actual time=1600.466..1627.082 rows=0 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Index Scan Backward using account_move__date_index on account_move (cost=0.43..648262.24 rows=4 width=26) (actual time=1586.469..1586.469 rows=0 loops=3)
Filter: (((l10n_mx_edi_cfdi_origin)::text ~~ '04|55555-5555-5555-5555-555%'::text) AND (company_id = 1))
Rows Removed by Filter: 2274213
Planning Time: 0.197 ms
JIT:
Functions: 13
Options: Inlining false, Optimization false, Expressions true, Deforming true
Timing: Generation 3.044 ms, Inlining 0.000 ms, Optimization 2.327 ms, Emission 34.202 ms, Total 39.574 ms
Execution Time: 1637.815 ms
```
PostgreSQL query stats from production returns the following top 1 slow query
```txt
Total Time Average Time Calls
4,981 min 1,351 ms 221,238
SELECT "account_move"."id"
FROM "account_move"
WHERE (("account_move"."l10n_mx_edi_cfdi_origin"::text LIKE $1)
AND ("account_move"."company_id" = $2))
AND (("account_move"."company_id" IN ($3)) OR "account_move"."company_id" IS NULL)
ORDER BY "account_move"."date" DESC , "account_move"."name" DESC , "account_move"."invoice_date" DESC , "account_move"."id" DESC
LIMIT $4
```
Creating the following index
```sql
CREATE INDEX account_move_l10n_mx_edi_cfdi_origin_index
ON account_move (l10n_mx_edi_cfdi_origin)
WHERE l10n_mx_edi_cfdi_origin IS NOT NULL
```
Similar to define the field `account_move.l10n_mx_edi_cfdi_origin(index='btree_not_null')`
The same query analyze result is
```txt
Limit (cost=4.49..4.49 rows=1 width=26) (actual time=0.018..0.018 rows=0 loops=1)
-> Sort (cost=4.49..4.51 rows=9 width=26) (actual time=0.017..0.017 rows=0 loops=1)
Sort Key: date DESC, name DESC, invoice_date DESC, id DESC
Sort Method: quicksort Memory: 25kB
-> Index Scan using account_move_l10n_mx_edi_cfdi_origin_index on account_move (cost=0.42..4.44 rows=9 width=26) (actual time=0.011..0.012 rows=0 loops=1)
Index Cond: (((l10n_mx_edi_cfdi_origin)::text >= '04|55555-5555-5555-5555-555'::text) AND ((l10n_mx_edi_cfdi_origin)::text < '04|55555-5555-5555-5555-556'::text))
Filter: (((l10n_mx_edi_cfdi_origin)::text ~~ '04|55555-5555-5555-5555-555%'::text) AND (company_id = 1))
Planning Time: 0.147 ms
Execution Time: 0.036 ms
```
It is ~9k times faster
Forward-Port-Of: odoo/enterprise#85427See test in this commit. opw-4744627 Forward-Port-Of: odoo/enterprise#85697
Original PR description
See test in this commit. opw-4744627 Forward-Port-Of: odoo/enterprise#85697
AttachedDocument is a specific XML format used in Colombia, generated by the DIAN regulatory body. These Documents are commonly received from vendors as they contain complete billing information. While Odoo 18.0+ can generate AttachedDocument records for outgoing invoices, it lacks import functionality. This document format contains nested XML documents that represent related records such as DIAN responses, Commercial Events data, and the orignal vendor invoice. The DIAN specifications state
Original PR description
AttachedDocument is a specific XML format used in Colombia, generated by the DIAN regulatory body. These Documents are commonly received from vendors as they contain complete billing information. While Odoo 18.0+ can generate AttachedDocument records for outgoing invoices, it lacks import functionality. This document format contains nested XML documents that represent related records such as DIAN responses, Commercial Events data, and the orignal vendor invoice. The DIAN specifications state that for an AttachedDocument with specified DocumentType must contain the original invoice within the top-most <cac:Attachment> node. (All other documents attached with this file are wrapped in <cac:ParentDocumentLineReference> tags which differentiates it) Specifications: https://www.dian.gov.co/impuestos/factura-electronica/Documents/Anexo-Techico-Factura-Electronica-de-Venta-vr-1-9.pdf task-4299222 Forward-Port-Of: odoo/enterprise#84374
This commit will do a backport of the python change made in this commit: https://github.com/odoo/enterprise/pull/77565/commits/7f26eefa932ec09297fbc4b8256ebe0b2976b231 task-4476707 Forward-Port-Of: odoo/enterprise#85642 Forward-Port-Of: odoo/enterprise#84728
Original PR description
This commit will do a backport of the python change made in this commit: https://github.com/odoo/enterprise/pull/77565/commits/7f26eefa932ec09297fbc4b8256ebe0b2976b231 task-4476707 Forward-Port-Of: odoo/enterprise#85642 Forward-Port-Of: odoo/enterprise#84728
Currently, an empty partner ref in an FEC line could incorrectly match a partner with an empty ref. This fix ensures that only non-empty refs are considered when processing FEC files. Steps to reproduce: 1. Install the `l10n_fr_fec_import` module. 2. Create a contact and set its ref to an empty string (`""`). 3. Import an FEC file containing lines without `CompAuxNum`. 4. The created contact will be incorrectly assigned to all lines without `CompAuxNum`. opw-4592290 Forward-Port-O
Original PR description
Currently, an empty partner ref in an FEC line could incorrectly match a partner with an empty ref. This fix ensures that only non-empty refs are considered when processing FEC files. Steps to reproduce: 1. Install the `l10n_fr_fec_import` module. 2. Create a contact and set its ref to an empty string (`""`). 3. Import an FEC file containing lines without `CompAuxNum`. 4. The created contact will be incorrectly assigned to all lines without `CompAuxNum`. opw-4592290 Forward-Port-Of: odoo/enterprise#84955 Forward-Port-Of: odoo/enterprise#81676
## Version: 17.0+ ## Issue: Test (introduced by task 4457038) fails on Single App because of missing dependency. Relies on SHIF_AMOUNT https://github.com/odoo/enterprise/blob/ffb0aa8d7aad913328bb0b585197172da4e838b3/l10n_ke_hr_payroll_shif/data/hr_salary_rule_data.xml#L46C1-L47C1 runbot-159825 Forward-Port-Of: odoo/enterprise#85021
Original PR description
## Version: 17.0+ ## Issue: Test (introduced by task 4457038) fails on Single App because of missing dependency. Relies on SHIF_AMOUNT https://github.com/odoo/enterprise/blob/ffb0aa8d7aad913328bb0b585197172da4e838b3/l10n_ke_hr_payroll_shif/data/hr_salary_rule_data.xml#L46C1-L47C1 runbot-159825 Forward-Port-Of: odoo/enterprise#85021
**Steps to reproduce** Reproduced on Linux/Firefox. Not reproducible on all browsers. - Open Timesheets app. - Try to add a custom grouping via the "Add Custom Group" select. Bug: the dropdown closes immediately **Cause** Commit 72af4ca4d9859e7236a21cb71401d9f690c42eb6 added an event listener https://github.com/odoo/enterprise/blob/72af4ca4d9859e7236a21cb71401d9f690c42eb6/timesheet_grid/static/src/components/timesheet_timer_header/timesheet_timer_header.js#L41-L48 Depending on the browser
Original PR description
**Steps to reproduce** Reproduced on Linux/Firefox. Not reproducible on all browsers. - Open Timesheets app. - Try to add a custom grouping via the "Add Custom Group" select. Bug: the dropdown closes immediately **Cause** Commit 72af4ca4d9859e7236a21cb71401d9f690c42eb6 added an event listener https://github.com/odoo/enterprise/blob/72af4ca4d9859e7236a21cb71401d9f690c42eb6/timesheet_grid/static/src/components/timesheet_timer_header/timesheet_timer_header.js#L41-L48 Depending on the browser, the first click on a `select` may not propagate to its anchestors all the way to the document `body`. However, if it does, the timer button is focused and the dropdown closes. **Solution** Exlude clicks on popover elments from focusing the timer Start/Stop button. opw-4768571 Forward-Port-Of: odoo/enterprise#85550 Forward-Port-Of: odoo/enterprise#85308
This is a fix-of-fix. #### Explanation of the first fix Before the fix abb3194e190abae023ac2d794e631f38945d5f0d the invoice date was controlling the date that appears in the `Fecha` field of the CFDI, except if the invoice date was set to today or was in the future: in that case, the current time would be used. However, there would be cases where the CFDI would be successfully sent to the PAC but not registered as successfully sent in Odoo because of a timeout or disconnection. In those
Original PR description
This is a fix-of-fix. #### Explanation of the first fix Before the fix abb3194e190abae023ac2d794e631f38945d5f0d the invoice date was controlling the date that appears in the `Fecha` field of the…
This is a fix-of-fix. #### Explanation of the first fix Before the fix abb3194e190abae023ac2d794e631f38945d5f0d the invoice date was controlling the date that appears in the `Fecha` field of the CFDI, except if the invoice date was set to today or was in the future: in that case, the current time would be used. However, there would be cases where the CFDI would be successfully sent to the PAC but not registered as successfully sent in Odoo because of a timeout or disconnection. In those cases, using the current time is a problem because we will try to retry sending the CFDI to the PAC, with a new time, which would be recognised as a new invoice. To solve that issue, that fix set the Fecha to always be the `l10n_mx_edi_post_time` which is the time of posting of the invoice. However, that isn't okay for many Mexican users who expect that the CFDI date must be the same as the invoice date on the PDF (of course, except if the invoice date is in the future). #### The fix-of-fix (this PR) To solve both those issues, here is what we do: - now, the `l10n_mx_edi_post_time` is set when we first try to *send* the CFDI (rather than when we post it), and then stays the same unless the invoice is reset to draft (which ensures that if we must retry several times to resend the CFDI, the sending time won't change). - if the invoice date is older than the `l10n_mx_edi_post_time`, it will be used as the CFDI's Fecha. This ensures that users can control the Fecha using the invoice date. If the user modifies the invoice date, they will need to reset the invoice to draft, so the `l10n_mx_edi_post_time` will be reset too. task-none Forward-Port-Of: odoo/enterprise#85136
Since f82f9ab7b0351d0c1239c4cafa772bea8c17c6ff, the unreconciled aml domain includes payable accounts, which leads to issue when processing followup. Since we need to get the total value including payable accounts, we add `account_id` to the group by, this way we can conditionnally set the computed values regarding the type of account, but also get the total due/overdue amounts, by adding two computed fields. Steps to reproduce new issue: - create a vendor bill for Demo (Joel Willis), with du
Original PR description
Since f82f9ab7b0351d0c1239c4cafa772bea8c17c6ff, the unreconciled aml domain includes payable accounts, which leads to issue when processing followup. Since we need to get the total value including payable accounts, we add `account_id` to the group by, this way we can conditionnally set the computed values regarding the type of account, but also get the total due/overdue amounts, by adding two computed fields. Steps to reproduce new issue: - create a vendor bill for Demo (Joel Willis), with due date 15 days ago - confirm the bill, print the PDF and attach it to the bill (as if we received it from the vendor) - now open the follow-up wizard from the partner form, and notice that the Vendor bill is attached opw-4664402 Forward-Port-Of: odoo/enterprise#85371 Forward-Port-Of: odoo/enterprise#85296
The aim of this commit is to: - avoid reporting negative amount in a 281.50 form which are rejected by the administration. - avoid reporting form with 0 value everywhere which are rejected by the administration. - avoid reporting a form with an amount < 250 EUR Context: The administration stated that we don't need to make any report that would be above 250 EUR. (art. 57, al. 3 CIR 92 et art. 30 AR/CIR 92) https://www.wolterskluwer.com/fr-be/expert-insights/tax-form-281-50
Original PR description
The aim of this commit is to: - avoid reporting negative amount in a 281.50 form which are rejected by the administration. - avoid reporting form with 0 value everywhere which are rejected by the…
The aim of this commit is to:
- avoid reporting negative amount in a 281.50 form which are rejected by the administration.
- avoid reporting form with 0 value everywhere which are rejected by the administration.
- avoid reporting a form with an amount < 250 EUR
Context:
The administration stated that we don't need to make any report that would be above 250 EUR.
(art. 57, al. 3 CIR 92 et art. 30 AR/CIR 92)
https://www.wolterskluwer.com/fr-be/expert-insights/tax-form-281-50 https://travaillerensociete.indicator.be/main/newsadvice/52784/news/52785/news_story/533/ https://www.monastucesetconseils.be/2025-04/fiches-fiscales-281-50-pour-le-29-juin-2025-WAACPCAR_EU33150802
Before this commit:
Odoo could create a form with a negative amount as commission/fee/... This could result in the administration software converting the xml into a BOW file to generated an error and a file that will be rejected by Belcotax.
Same for form with 0 everywhere.
Also, accountants always end up deleting the 281.50 form below 250 EUR as those don't need to be reported.
After this commit:
Odoo don't report negative or null total amount as commission/fee/... and doesn't create any form if the total amounts are below 250 EUR saving accountants the burden to remove them.
task-id: None
This was discussed and done with TSB and DELC and is also the result of our past experiences reporting 281.50 forms which also involved CAHE, MAKR and CAL.
Forward-Port-Of: odoo/enterprise#85508How to reproduce: - Open Documents, go into a folder - Open its chatter, click on the AI btn Current behavior: - Traceback: https://pastebin.com/kyCq2yBE Solution: The AI chat requires a record but when opening a folder in the Documents app, there is no record to refer to, resulting to an error. As a fix, we won't show the AI button in case of missing record. Task-ID: 4796869 Forward-Port-Of: odoo/enterprise#85595
Original PR description
How to reproduce: - Open Documents, go into a folder - Open its chatter, click on the AI btn Current behavior: - Traceback: https://pastebin.com/kyCq2yBE Solution: The AI chat requires a record but when opening a folder in the Documents app, there is no record to refer to, resulting to an error. As a fix, we won't show the AI button in case of missing record. Task-ID: 4796869 Forward-Port-Of: odoo/enterprise#85595
This commit fix some tests in account_reports which were failing in nightly on the runbot, see error 134654. First test fails because an account number sequence was changing depending on if the accountant module was installed or not. Fix the test by replacing the hardcoded account name by the used bank journal name. Second test fails because of payment_state computation which is different depending on if the accountant module was installed or not. Fix it by using the _get_invoice_in_p
Original PR description
This commit fix some tests in account_reports which were failing in nightly on the runbot, see error 134654. First test fails because an account number sequence was changing depending on if the accountant module was installed or not. Fix the test by replacing the hardcoded account name by the used bank journal name. Second test fails because of payment_state computation which is different depending on if the accountant module was installed or not. Fix it by using the _get_invoice_in_payment_state method instead of hardcoded value. no task Forward-Port-Of: odoo/enterprise#84417
user_lang was missing as it was not set in the test setup, which caused an error in the setup because when creating a company it needed a user_lang to be set in this function `_create_dashboard_notes` build_error-161173 Forward-Port-Of: odoo/enterprise#85354 Forward-Port-Of: odoo/enterprise#84249
Original PR description
user_lang was missing as it was not set in the test setup, which caused an error in the setup because when creating a company it needed a user_lang to be set in this function `_create_dashboard_notes` build_error-161173 Forward-Port-Of: odoo/enterprise#85354 Forward-Port-Of: odoo/enterprise#84249
1. Configure aliases 2. Open documents in debug mode 3. Select or enter a folder 4. Open details panel (Info & Tags) 5. See crash Without debug mode in readonly, you'll see "Activity assigned to" instead of "No activity assignee". Also fixes * domain field disappearing if cleared * irregular spacing of alias in readonly * filtered props passed to the Many2OneField (see related COM PR) Tests are not exhaustive but expanded to increase coverage of alias fields and `isContainer` 'f
Original PR description
1. Configure aliases 2. Open documents in debug mode 3. Select or enter a folder 4. Open details panel (Info & Tags) 5. See crash Without debug mode in readonly, you'll see "Activity assigned to" instead of "No activity assignee". Also fixes * domain field disappearing if cleared * irregular spacing of alias in readonly * filtered props passed to the Many2OneField (see related COM PR) Tests are not exhaustive but expanded to increase coverage of alias fields and `isContainer` 'fake' records. Follow up of 4724349 Task-4749289 Forward-Port-Of: odoo/enterprise#84035
When timezone of user is empty and the user clicks on Add Closing Day(s) button, a traceback will appear. Steps to reproduce the error: - Open Profile > Preferences > Select empty in timezone > Save - Install ``Appointments`` - Go to Appointments > Schedule > Resource Bookings > Add Closing Day(s) Traceback: ``` File "/home/odoo/src/enterprise/appointment/wizard/appointment_manage_leaves.py", line 19, in <lambda> leave_start_dt = fields.Datetime('Start Date', required=True, defa
Original PR description
When timezone of user is empty and the user clicks on Add Closing Day(s) button, a traceback will appear. Steps to reproduce the error: - Open Profile > Preferences > Select empty in timezone > Save…
When timezone of user is empty and the user clicks on Add Closing Day(s) button,
a traceback will appear.
Steps to reproduce the error:
- Open Profile > Preferences > Select empty in timezone > Save
- Install ``Appointments``
- Go to Appointments > Schedule > Resource Bookings > Add Closing Day(s)
Traceback:
```
File "/home/odoo/src/enterprise/appointment/wizard/appointment_manage_leaves.py", line 19, in <lambda>
leave_start_dt = fields.Datetime('Start Date', required=True, default=lambda self: self._default_time(0, 0))
File "/home/odoo/src/enterprise/appointment/wizard/appointment_manage_leaves.py", line 14, in _default_time
user_timezone = pytz.timezone(self.env.user.tz or self.env.context.get('tz', 'utc'))
File "/home/odoo/src/odoo/odoo/_monkeypatches/pytz.py", line 129, in timezone
return original_pytz_timezone(name)
File "__init__.py", line 183, in timezone
if zone.upper() == 'UTC':
AttributeError: 'bool' object has no attribute 'upper'
```
https://github.com/odoo/enterprise/blob/2c938b66fc1b526a360f4b199a47bcc53991bcb9/appointment/wizard/appointment_manage_leaves.py#L14
When the user selects an empty timezone, tz will be False.
So, It will lead to the above traceback.
Forward port https://github.com/odoo/enterprise/pull/64948 was closed in master,
so the issue is still present in saas-17.4 and all later versions.
sentry-6537084290
Forward-Port-Of: odoo/enterprise#83363For proper provision management we introduce accounts 2350 and 2351 task-4797323 Forward-Port-Of: odoo/enterprise#85574
Original PR description
For proper provision management we introduce accounts 2350 and 2351 task-4797323 Forward-Port-Of: odoo/enterprise#85574
… condition In JS, rpc is not a service anymore so it will return no matter if the component is already destroyed. In turn, the orm service is protected, so if it is passed it will crash. After this commit, we prevent this race condition and we batch calls that are independant from one another. runbot-error-190605 Forward-Port-Of: odoo/enterprise#85502
Original PR description
… condition In JS, rpc is not a service anymore so it will return no matter if the component is already destroyed. In turn, the orm service is protected, so if it is passed it will crash. After this commit, we prevent this race condition and we batch calls that are independant from one another. runbot-error-190605 Forward-Port-Of: odoo/enterprise#85502
Fix a bug where account moves paid with cash appears in a line with full 0 in the boe export of mod347 tax report. But it shouldn't create a line at all, so this commit remove the lines in this case. task-4613012 Forward-Port-Of: odoo/enterprise#84317
Original PR description
Fix a bug where account moves paid with cash appears in a line with full 0 in the boe export of mod347 tax report. But it shouldn't create a line at all, so this commit remove the lines in this case. task-4613012 Forward-Port-Of: odoo/enterprise#84317
Steps: - Have a main company C with a branch B - Select B in company selector, but have C checkbox checked too - Create a user U with `company_id == B` - Create and confirm an invoice I for user U, company_id should be B, amount X - Go back to accounting dashboard, and open reconciliation widget - Create a new transaction, amout X - Select it, select line from I and click on Validate -> UserError: "Incompatible companies on records" This reason is, even if we have Branch company sele
Original PR description
Steps: - Have a main company C with a branch B - Select B in company selector, but have C checkbox checked too - Create a user U with `company_id == B` - Create and confirm an invoice I for user U, company_id should be B, amount X - Go back to accounting dashboard, and open reconciliation widget - Create a new transaction, amout X - Select it, select line from I and click on Validate -> UserError: "Incompatible companies on records" This reason is, even if we have Branch company selected as `env.company`, as we have Main company checked too, the statement line is created with `company_id == main company` With this commit, we unset the partner from the statement line's move if it is from an accessible branch but not the main company. We also test different usecases to secure the flow. opw-4626664 Forward-Port-Of: odoo/enterprise#85282 Forward-Port-Of: odoo/enterprise#82896
### Before this PR - Go on point of sale (with pos_discount installed) - Click on Action - Click on Discount - Write a discount percentage - Click OK - Validate POS An error appear because the negative price should be a printRecItemAdjustment with type 3 ### After this PR the right printRecitemAdjustiment is sent to printer Forward-Port-Of: odoo/enterprise#85416 Forward-Port-Of: odoo/enterprise#80951
Original PR description
### Before this PR - Go on point of sale (with pos_discount installed) - Click on Action - Click on Discount - Write a discount percentage - Click OK - Validate POS An error appear because the negative price should be a printRecItemAdjustment with type 3 ### After this PR the right printRecitemAdjustiment is sent to printer Forward-Port-Of: odoo/enterprise#85416 Forward-Port-Of: odoo/enterprise#80951
Adding the search more logic on batch payment and limiting the display to 5 batch in the popover no task id Forward-Port-Of: odoo/enterprise#85375
Original PR description
Adding the search more logic on batch payment and limiting the display to 5 batch in the popover no task id Forward-Port-Of: odoo/enterprise#85375
Kiosk mode didn't sign the request headers with "Authorisation" needed by the IoT to execute actions like printing. This PR fixes it along with an error caused by the refactoring PR https://github.com/odoo/odoo/pull/186359 To reproduce the authorisation issue: connect a kiosk with an iot box + printer, then make a payment. The printing would never be done because no "authorization" is sent in the headers, so the IoT Box refuses to execute the action To reproduce the bug linked to the re
Original PR description
Kiosk mode didn't sign the request headers with "Authorisation" needed by the IoT to execute actions like printing. This PR fixes it along with an error caused by the refactoring PR https://github.com/odoo/odoo/pull/186359 To reproduce the authorisation issue: connect a kiosk with an iot box + printer, then make a payment. The printing would never be done because no "authorization" is sent in the headers, so the IoT Box refuses to execute the action To reproduce the bug linked to the refactoring: connect an iot terminal (tested with Worldline) then try to make a payment. A traceback appears upon payment approval or cancellation task-4794798 Forward-Port-Of: odoo/enterprise#85580
Issue: ---------- A user with Sale Manager access is unable to confirm a recurring service type sale order. Root Cause: -------- The Sale Manager lacks write access to task and recurrence records, which are updated during order confirmation. Fix: ------- Used sudo() when updating the recurrence to bypass access restrictions, allowing the Sale Manager to confirm the sale order successfully. Steps to Reproduce: ------------- - Install the project_sale_subscription module
Original PR description
Issue: ---------- A user with Sale Manager access is unable to confirm a recurring service type sale order. Root Cause: -------- The Sale Manager lacks write access to task and recurrence records, which are updated during order confirmation. Fix: ------- Used sudo() when updating the recurrence to bypass access restrictions, allowing the Sale Manager to confirm the sale order successfully. Steps to Reproduce: ------------- - Install the project_sale_subscription module. - Create a user with Sale Manager access only. - Log in as that user and create a subscription-based sale order. - Add a recurring service product to the order line. Forward-Port-Of: odoo/enterprise#85584 Forward-Port-Of: odoo/enterprise#85489
15 changes
Enhancements to existing features
Miscellaneous changes
Forward-Port-Of: odoo/odoo#210330
Original PR description
Forward-Port-Of: odoo/odoo#210330
1.Fix issue encountered in debug mode Repro steps: 1. Install l10n_jo_edi module 2. Enter debug mode 3. Inside an invoice form view, attempt to view the raw record data then you will get an error 2.Change l10n_jo_edi_state The EDI state is not read-only (to give users flexibility in timeout scenarios), so we need to do the following: Not hide it if it's false (because the user can set it to false) and only hide it in non-Jordanian companies Make the field trackable (so it's more clear
Original PR description
1.Fix issue encountered in debug mode Repro steps: 1. Install l10n_jo_edi module 2. Enter debug mode 3. Inside an invoice form view, attempt to view the raw record data then you will get an error 2.Change l10n_jo_edi_state The EDI state is not read-only (to give users flexibility in timeout scenarios), so we need to do the following: Not hide it if it's false (because the user can set it to false) and only hide it in non-Jordanian companies Make the field trackable (so it's more clear to the users when it changes) Make it readonly in case the invoice has a QR code --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#207080
Before this commit, the filename for pdf reports when previewed from the portal is "\<database ID\>.pdf" instead of a readable name like "Sales-Order-S00001".pdf. This can be especially confusing if the database ID is a different number from the record's sequence number. Steps to reproduce ----- 1. Open a sales order in the customer portal 2. Select the Print button 3. From the pdf preview, Print -> Save to PDF 4. The downloaded filename is "\<database ID\>.pdf", also the browser title b
Original PR description
Before this commit, the filename for pdf reports when previewed from the portal is "\<database ID\>.pdf" instead of a readable name like "Sales-Order-S00001".pdf. This can be especially confusing if the database ID is a different number from the record's sequence number. Steps to reproduce ----- 1. Open a sales order in the customer portal 2. Select the Print button 3. From the pdf preview, Print -> Save to PDF 4. The downloaded filename is "\<database ID\>.pdf", also the browser title bar is just the database ID Cause ----- No filename is being set in the Content-Disposition header, so the browser takes the filename from the last segment of the URL which is the database ID. Solution ----- Set an inline Content-Disposition with the filename argument when previewing, similar to what is done when downloading. opw-4710501 Forward-Port-Of: odoo/odoo#210002 Forward-Port-Of: odoo/odoo#207357
moving it to the module mrp_subcontracting_purchase is the correct module, as it depends on the override of _get_resupply_availability happening in mrp_subcontracting_purchase module accorinding to this PR (https://github.com/odoo/odoo/pull/144702/files#diff-54bc40f604ca24cec75d6f7473d21d1d2d0300576456026fe63164daf7cd5149) and fails as a single app test in mrp_subcontracting build_error-163126 Forward-Port-Of: odoo/odoo#206513 Forward-Port-Of: odoo/odoo#206078
Original PR description
moving it to the module mrp_subcontracting_purchase is the correct module, as it depends on the override of _get_resupply_availability happening in mrp_subcontracting_purchase module accorinding to this PR (https://github.com/odoo/odoo/pull/144702/files#diff-54bc40f604ca24cec75d6f7473d21d1d2d0300576456026fe63164daf7cd5149) and fails as a single app test in mrp_subcontracting build_error-163126 Forward-Port-Of: odoo/odoo#206513 Forward-Port-Of: odoo/odoo#206078
Versions -------- - 17.4+ Steps ----- 1. Configure UoM decimal accuracy to be 0 digits; 2. create, confirm a SO; 3. create a downpayment invoice; 4. go back to the SO; 5. modify the product line's price. Issue ----- > AssertionError: precision_rounding must be positive, got 0. Cause ----- When checking for quantity changes to log on `write`, a fallback rounding value is retrieved using `precision_get`. This returns a `precision_digits` value, but is being used as a `precisio
Original PR description
Versions -------- - 17.4+ Steps ----- 1. Configure UoM decimal accuracy to be 0 digits; 2. create, confirm a SO; 3. create a downpayment invoice; 4. go back to the SO; 5. modify the product line's…
Versions -------- - 17.4+ Steps ----- 1. Configure UoM decimal accuracy to be 0 digits; 2. create, confirm a SO; 3. create a downpayment invoice; 4. go back to the SO; 5. modify the product line's price. Issue ----- > AssertionError: precision_rounding must be positive, got 0. Cause ----- When checking for quantity changes to log on `write`, a fallback rounding value is retrieved using `precision_get`. This returns a `precision_digits` value, but is being used as a `precision_rounding` value, resulting in an error when it is 0. In previous versions, this fallback value was never used, as `display_type` lines were skipped, and any other line is guaranteed to have a `product_uom.rounding` value. As of 9aa52dd6418e, the constraint was changed for `is_downpayment` lines not having to be of `display_type` nor require a `product_uom` value, meaning the faulty fallback value now gets used. Solution -------- Remove the fallback value, and only log lines with a `product_uom` value. opw-4566621 Forward-Port-Of: odoo/odoo#205581
**Steps to reproduce:** - Install l10n_it_edi_ndd - Switch to an Italian company (e.g. IT Company) - Create an invoice - Confirm the invoice => Document Type (in "Electronic Invoicing" tab) is computed - Create a credit note from the invoice - On credit note wizard, click on "Reverse and Create Invoice" - Check the created credit note **Issue:** The credit note is posted but its Document Type field (l10n_it_document_type) is empty. l10n_it_document_type should be computed when it do
Original PR description
**Steps to reproduce:** - Install l10n_it_edi_ndd - Switch to an Italian company (e.g. IT Company) - Create an invoice - Confirm the invoice => Document Type (in "Electronic Invoicing" tab) is…
**Steps to reproduce:** - Install l10n_it_edi_ndd - Switch to an Italian company (e.g. IT Company) - Create an invoice - Confirm the invoice => Document Type (in "Electronic Invoicing" tab) is computed - Create a credit note from the invoice - On credit note wizard, click on "Reverse and Create Invoice" - Check the created credit note **Issue:** The credit note is posted but its Document Type field (l10n_it_document_type) is empty. l10n_it_document_type should be computed when it doesn't have a value already and the state of the move is "posted". The credit note will be rejected when sent to SDI because this field is empty. **Cause:** In the reverse method, the field is set to False in order to be recomputed. However, the compute method is triggered when the state changes, but the credit note not is already posted. Therefore the field will not be recomputed. **Solution:** Set the value to False before the creation of the credit note. So that, the field will be recomputed when posting the credit note. opw-4689755 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#208654
Some views use a domain widget to edit/save a domain and use it afterwards in several places where domains must have literals only. Typically, a literal_eval is used to evaluate the (string) domain. Thus expressions like "uid" or "context_today()"" should not be used in those contexts. Here we introduce an option "allow_expressions" (default False) for the domain field and use it to mark as invalid domains that contain expressions when the option is set to False. A notification is displayed whe
Original PR description
Some views use a domain widget to edit/save a domain and use it afterwards in several places where domains must have literals only. Typically, a literal_eval is used to evaluate the (string) domain.…
Some views use a domain widget to edit/save a domain and use it afterwards in several places where domains must have literals only. Typically, a literal_eval is used to evaluate the (string) domain. Thus expressions like "uid" or "context_today()"" should not be used in those contexts. Here we introduce an option "allow_expressions" (default False) for the domain field and use it to mark as invalid domains that contain expressions when the option is set to False. A notification is displayed when a domain contains an unwanted expressions. Since we cannot expect modules like base to be updated, we have to find another system to allow the usage of expressions in the form views for the models ir.filters and base.automation: we simply hardcode those models as allowing expressions. Since for these models, the evaluation of domains is done via safe_eval but with a restricted evaluation context, we also display a notification that alerts the user that the evaluation of expressions (although accepted by the domain field) can fail. We revert the recent commit https://github.com/odoo/odoo/commit/a6787552150434d4366e30cbeb6f6d309c2c6cb9 that introduced potentially problematic calls to safe_eval in order to allow evaluation of expressions. Forward-Port-Of: odoo/odoo#209960 Forward-Port-Of: odoo/odoo#208876 Another fix is added here: The domain field passes a new prop allowExpressions to the domain selector. If that prop is false (default true), the within operator is not proposed for selection for date/datetime fields. This is done to prevent users to introduce expressions in their domains when they are not supported.
When generating the JO UBL file, we want to keep the PartyIdentification and its ID node, even if the latter is empty. Also, in the same file, the country code of a partner should be set to 'PN' if the partner doesn't have its country set. task-4656827 Forward-Port-Of: odoo/odoo#206488
Original PR description
When generating the JO UBL file, we want to keep the PartyIdentification and its ID node, even if the latter is empty. Also, in the same file, the country code of a partner should be set to 'PN' if the partner doesn't have its country set. task-4656827 Forward-Port-Of: odoo/odoo#206488
To be able to configure salary journals and access rule parameters, we reintroduce back the salary menu in configuration Forward-Port-Of: odoo/enterprise#85288
Original PR description
To be able to configure salary journals and access rule parameters, we reintroduce back the salary menu in configuration Forward-Port-Of: odoo/enterprise#85288
Currently a traceback occurs if no QST instutions were defined, making it hard for users to understand where the error is coming from, in this PR we specify the missing institution. Forward-Port-Of: odoo/enterprise#85148 Forward-Port-Of: odoo/enterprise#85104
Original PR description
Currently a traceback occurs if no QST instutions were defined, making it hard for users to understand where the error is coming from, in this PR we specify the missing institution. Forward-Port-Of: odoo/enterprise#85148 Forward-Port-Of: odoo/enterprise#85104
The _compute_l10n_mx_edi_cfdi_cancel_id method is calling the following search https://github.com/odoo/enterprise/blob/fd01cf3d57109424725727d7eb40afbe34ef67a9/l10n_mx_edi/models/account_move.py#L685-L691 ```python move.l10n_mx_edi_cfdi_cancel_id = move.search([ ('l10n_mx_edi_cfdi_origin', '=like', f'04|{move.l10n_mx_edi_cfdi_uuid}%'), ('company_id', '=', move.company_id.id)], limit=1, ) ``` It is generating the following sql query ```sql SE
Original PR description
The _compute_l10n_mx_edi_cfdi_cancel_id method is calling the following search…
The _compute_l10n_mx_edi_cfdi_cancel_id method is calling the following search
https://github.com/odoo/enterprise/blob/fd01cf3d57109424725727d7eb40afbe34ef67a9/l10n_mx_edi/models/account_move.py#L685-L691
```python
move.l10n_mx_edi_cfdi_cancel_id = move.search([
('l10n_mx_edi_cfdi_origin', '=like', f'04|{move.l10n_mx_edi_cfdi_uuid}%'),
('company_id', '=', move.company_id.id)],
limit=1,
)
```
It is generating the following sql query
```sql
SELECT id
FROM account_move
WHERE l10n_mx_edi_cfdi_origin :: text LIKE '04|55555-5555-5555-5555-555%'
AND company_id = 1
ORDER BY date DESC,
name DESC,
invoice_date DESC,
id DESC
LIMIT 1
```
Running a analyze for a database with ~7M of `account_move` records the result is
```txt
Limit (cost=73029.67..137055.68 rows=1 width=26) (actual time=1610.419..1637.035 rows=0 loops=1)
-> Incremental Sort (cost=73029.67..649263.71 rows=9 width=26) (actual time=1600.475..1627.091 rows=0 loops=1)
Sort Key: date DESC, name DESC, invoice_date DESC, id DESC
Presorted Key: date
Full-sort Groups: 1 Sort Method: quicksort Average Memory: 25kB Peak Memory: 25kB
-> Gather Merge (cost=1000.46..649263.30 rows=9 width=26) (actual time=1600.466..1627.082 rows=0 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Index Scan Backward using account_move__date_index on account_move (cost=0.43..648262.24 rows=4 width=26) (actual time=1586.469..1586.469 rows=0 loops=3)
Filter: (((l10n_mx_edi_cfdi_origin)::text ~~ '04|55555-5555-5555-5555-555%'::text) AND (company_id = 1))
Rows Removed by Filter: 2274213
Planning Time: 0.197 ms
JIT:
Functions: 13
Options: Inlining false, Optimization false, Expressions true, Deforming true
Timing: Generation 3.044 ms, Inlining 0.000 ms, Optimization 2.327 ms, Emission 34.202 ms, Total 39.574 ms
Execution Time: 1637.815 ms
```
PostgreSQL query stats from production returns the following top 1 slow query
```txt
Total Time Average Time Calls
4,981 min 1,351 ms 221,238
SELECT "account_move"."id"
FROM "account_move"
WHERE (("account_move"."l10n_mx_edi_cfdi_origin"::text LIKE $1)
AND ("account_move"."company_id" = $2))
AND (("account_move"."company_id" IN ($3)) OR "account_move"."company_id" IS NULL)
ORDER BY "account_move"."date" DESC , "account_move"."name" DESC , "account_move"."invoice_date" DESC , "account_move"."id" DESC
LIMIT $4
```
Creating the following index
```sql
CREATE INDEX account_move_l10n_mx_edi_cfdi_origin_index
ON account_move (l10n_mx_edi_cfdi_origin)
WHERE l10n_mx_edi_cfdi_origin IS NOT NULL
```
Similar to define the field `account_move.l10n_mx_edi_cfdi_origin(index='btree_not_null')`
The same query analyze result is
```txt
Limit (cost=4.49..4.49 rows=1 width=26) (actual time=0.018..0.018 rows=0 loops=1)
-> Sort (cost=4.49..4.51 rows=9 width=26) (actual time=0.017..0.017 rows=0 loops=1)
Sort Key: date DESC, name DESC, invoice_date DESC, id DESC
Sort Method: quicksort Memory: 25kB
-> Index Scan using account_move_l10n_mx_edi_cfdi_origin_index on account_move (cost=0.42..4.44 rows=9 width=26) (actual time=0.011..0.012 rows=0 loops=1)
Index Cond: (((l10n_mx_edi_cfdi_origin)::text >= '04|55555-5555-5555-5555-555'::text) AND ((l10n_mx_edi_cfdi_origin)::text < '04|55555-5555-5555-5555-556'::text))
Filter: (((l10n_mx_edi_cfdi_origin)::text ~~ '04|55555-5555-5555-5555-555%'::text) AND (company_id = 1))
Planning Time: 0.147 ms
Execution Time: 0.036 ms
```
It is ~9k times faster
Forward-Port-Of: odoo/enterprise#85427Steps to reproduce: (thanks to TBS for investigating + writing the test) 1. Have a MX company with Quadrum or SwSapien 2. Create a USD bank transaction with `13220.00 USD` and `305147.51 MXN` 3. Create a USD invoice for `13220.00 USD` and send CFDI 4. Reconcile transaction and invoice 5. Click "Update payments" on the invoice => CRP20211 Looks like it comes from this rounding difference Rate is computed by odoo using `305147.51 MXN / 13220.0 USD = 23.082262481 ≃ 23.082262 MXN/USD`
Original PR description
Steps to reproduce: (thanks to TBS for investigating + writing the test) 1. Have a MX company with Quadrum or SwSapien 2. Create a USD bank transaction with `13220.00 USD` and `305147.51 MXN` 3.…
Steps to reproduce: (thanks to TBS for investigating + writing the test) 1. Have a MX company with Quadrum or SwSapien 2. Create a USD bank transaction with `13220.00 USD` and `305147.51 MXN` 3. Create a USD invoice for `13220.00 USD` and send CFDI 4. Reconcile transaction and invoice 5. Click "Update payments" on the invoice => CRP20211 Looks like it comes from this rounding difference Rate is computed by odoo using `305147.51 MXN / 13220.0 USD = 23.082262481 ≃ 23.082262 MXN/USD` PAC verify the amount paid using `13220.0 USD * 23.082262 MXN/USD = 305147.50 MXN` which is not `305147.51 MXN` Solution: There is no solution by adapting the rate: - quadrum restricts the rate to 6 decimals; - rounding the rate differently (e.g. to `23.082263`) would not help because `13220.0 USD * 23.082263 MXN/USD = 305147.52 MXN` which again is not `305147.51 MXN`. So, the only solution that I can think of is to adapt the amount in company currency so that it is exactly `round(amount_in_payment_curr / rate_rounded_to_6_decimals)`, i.e. in the example, change it to `305147.50 MXN`. In tests, both Quadrum and SwSapien seem to accept this. We don't perform the modification for Solucion Factible (the other PAC). opw-4222310 Forward-Port-Of: odoo/enterprise#85602 Forward-Port-Of: odoo/enterprise#83499
This reverts commit https://github.com/odoo/enterprise/commit/d77df0ea4d3b410d210307976f995d9abdc6c97b. Indeed, for security reasons, it is preferable to avoid calling safe_eval whenever possible. Note that in https://github.com/odoo/odoo/pull/208876 a new mechanism is introduced in order to block the creation of expressions in domain fields where we only want domains with litterals because they are evaluated with literal_eval. Forward-Port-Of: odoo/enterprise#85524 Forward-Port-Of: odoo/enter
Original PR description
This reverts commit https://github.com/odoo/enterprise/commit/d77df0ea4d3b410d210307976f995d9abdc6c97b. Indeed, for security reasons, it is preferable to avoid calling safe_eval whenever possible. Note that in https://github.com/odoo/odoo/pull/208876 a new mechanism is introduced in order to block the creation of expressions in domain fields where we only want domains with litterals because they are evaluated with literal_eval. Forward-Port-Of: odoo/enterprise#85524 Forward-Port-Of: odoo/enterprise#85298
## Version: 17.0+ ## Issue: Stripe payments with an unregistered card on backdated subscriptions lead to Stripe API refusal. ## Steps to reproduce: Ensure Stripe is well configured in `Test Mode` with `Credentials`; Create a new Sale Order with `Monthly Cleaning` as `Quotation Template` for any customer: - Under `Other Info` tab, change the `Subscription` `Start Date` for a date at least 2 days before current date; - Confirm and create regular invoice: - Set `Invoice Date` to the s
Original PR description
## Version: 17.0+ ## Issue: Stripe payments with an unregistered card on backdated subscriptions lead to Stripe API refusal. ## Steps to reproduce: Ensure Stripe is well configured in `Test Mode`…
## Version:
17.0+
## Issue:
Stripe payments with an unregistered card on backdated subscriptions lead to Stripe API refusal.
## Steps to reproduce:
Ensure Stripe is well configured in `Test Mode` with `Credentials`; Create a new Sale Order with `Monthly Cleaning` as `Quotation Template` for any customer:
- Under `Other Info` tab, change the `Subscription` `Start Date` for a date at least 2 days before current date;
- Confirm and create regular invoice:
- Set `Invoice Date` to the same date as the subscription;
- Confirm and go to the invoice's preview and start payment process:
- Use a new card for payment;
- Check `Save my payment details` checkbox and pay.
## Cause:
The Stripe mandate needs to be filled with a start date at least equal to yesterday (https://docs.stripe.com/api/payment_intents/create#create_payment_intent-payment_method_options-card-mandate_options-start_date). Subscription app sets the start date to the SO's `start_date` via https://github.com/odoo/enterprise/blob/5642ad28919081a44bb47c0d936aa51980178d09/sale_subscription/models/payment_transaction.py#L51-L52. The values are retrieved by `_stripe_prepare_mandate_options()` via https://github.com/odoo/odoo/blob/d231565ec9054556d025b093195a934f28d067c3/addons/payment_stripe/models/payment_transaction.py#L206 and sent to Stipe under a new structure given by https://github.com/odoo/odoo/blob/d231565ec9054556d025b093195a934f28d067c3/addons/payment_stripe/models/payment_transaction.py#L209-L220
## Fix:
Initial suggestion made in the `payment_stripe` module (https://github.com/odoo/odoo/pull/207451), but later moved to the origin of the issue. As of 2025-05-12, Stripe seems to have fixed the issue, but this patch is still applied as a safety measure.
opw-4654142
Forward-Port-Of: odoo/enterprise#85554
Forward-Port-Of: odoo/enterprise#85314