Daily updates from Odoo
Wednesday, July 29, 2026
59 changes · saas-19.3
Resolved issues and error corrections
Malaysia Statement of Account PDFs now calculate total and overdue amounts using the selected statement date. This ensures the totals match the displayed balance lines, improving accuracy for past-date reporting and customer account reviews.
Original PR description
## Current behavior: In Malaysia's Statement of Account, the total and total overdue amounts dont consider the selected Statement Date, and will calculate all the balances up until today in the…
## Current behavior: In Malaysia's Statement of Account, the total and total overdue amounts dont consider the selected Statement Date, and will calculate all the balances up until today in the generated PDF report ## Expected behavior: The total and total overdue amounts should only sum the balances included in the report up until the selected Statement Date ## Steps to reproduce: 1. Install l10n_my_reports module, switch to Malaysian company 2. Go inside Invoicing > Report > Aged receivable 3. Select a specific date in the past 4. Observe that the total amounts dont match with the balance column, and wont change regardless of the date selected ## Cause of the issue: The template used o.total_overdue which ignores the report domain and statement date ## Fix: Accumulate overdue_total in the template loop with the same domain and date_to cutoff as the balance lines, so it always matches the displayed Balance lines for the selected Statement Date opw-6332970 Forward-Port-Of: odoo/enterprise#125410 Forward-Port-Of: odoo/enterprise#123694
The Vietnam Sales Tax Report now shows VAT amounts consistently as positive values at detailed invoice levels. This prevents confusion when reviewing sales tax data and aligns detailed lines with the report totals.
Original PR description
## Current behavior: In Vietnam's Sales Tax Report, when unfolding until the minimum layer, the VAT now displays the value in negative ## Expected behavior: The VAT value in the minimum layer should…
## Current behavior: In Vietnam's Sales Tax Report, when unfolding until the minimum layer, the VAT now displays the value in negative ## Expected behavior: The VAT value in the minimum layer should be consistent with the upper layers and kept positive ## Steps to reproduce: - Install l10n_vn (l10n_vn_reports will install as well) - Switch to VN Company - With demo data, go to Invoicing / Reporting / Tax Report - Change Tax Report (VN) to Sales/Purchase Tax Report (VN) - Unfold the lines all the way to the minimum layer: VAT on sales of goods and services 10% -> INV/2026/00003 - Observe that the VAT 10% line is at negative, which is inconsistent with the Total line below ## Cause of the issue: - In Odoo, tax journal items store tax_base_amount with the accounting sign (negative for sales). This is expected behavior - However, Vietnamese VAT listing expects commercial amounts, which means sales bases need to be displayed as positive numbers ## Fix: Normalized tax_base_amount sign in _query_tax_lines function before building the SQL query opw-6344577 Forward-Port-Of: odoo/enterprise#125257 Forward-Port-Of: odoo/enterprise#122785
The scheduled payroll data update for Australian payroll now restores needed salary rule category data before updating salary rules. This prevents an error if those categories were deleted, keeping payroll maintenance actions running reliably.
Original PR description
Currently, an error occurs when the "Payroll: Update Data" scheduled action is run. **Steps to Reproduce:** - Install `l10n_au_hr_payroll` with demo data. - Switch to `Australian Company`. - Go to…
Currently, an error occurs when the "Payroll: Update Data" scheduled action is run. **Steps to Reproduce:** - Install `l10n_au_hr_payroll` with demo data. - Switch to `Australian Company`. - Go to `Payroll` > `Configuration` > `Salary` > `Rule Categories`. - Delete all records related to the `Australian Company`. - Go to `Scheduled Actions` and run `Payroll: Update Data`. `ValueError: External ID not found in the system: l10n_au_hr_payroll.rule_category_ote` After [this commit], the category_id field becomes non-required, allowing users to delete a rule category record even if it is linked to a salary rule. When updating the data file [1], an error is raised due to the missing rule category. This commit ensures that when updating the salary rule data, it updates the category data beforehand as like [here] [this commit]: https://github.com/odoo/enterprise/commit/c663fd2a81b7f6b34f8199fdbdc4a75c4f21379e [1] https://github.com/odoo/enterprise/blob/b6612dd58276646b81a3a12cd48e8427ea5359c2/l10n_au_hr_payroll/models/hr_payslip.py#L76-L83 [here]: https://github.com/odoo/enterprise/blob/b6612dd58276646b81a3a12cd48e8427ea5359c2/l10n_ch_hr_payroll/models/hr_payslip.py#L1074-L1087 sentry-7349905716 Forward-Port-Of: odoo/enterprise#121167
Accrual report totals now display correctly when users group purchase and sales accounting records by date. This prevents misleading zero totals in grouped views, helping finance teams review bills to receive and related accrual amounts accurately.
Original PR description
Currently, when users group accrual reports by dates, aggregated computed fields are not calculated correctly. As a result, values such as the total amount may be displayed as zero even when the…
Currently, when users group accrual reports by dates, aggregated computed fields are not calculated correctly. As a result, values such as the total amount may be displayed as zero even when the grouped records contain non-zero amounts.
## Steps to produce:
- Install Purchase and Accounting
- Create a product `Energy drink Sample` with cost 10$
- Create and Confirm a PO with the energy drink sample with vendor as `Administrator`
- Set `Received` as 1.
- Go to Accounting > Review > Bill to Receive
- Search Filter> Remove vendor grouping > Use Custom Group `Order Date`
- Expand the group
## Observed Behavior
Although the grouped lines contain an amount of 10 dollars, the aggregated total displayed in the sum remains zero.
The total should reflect the combined value of the grouped lines.
## Root Cause:
This issue occurs because opening the view triggers `_read_group_for_accrual`, which overrides the `_read_group` method on purchase order lines. The purpose of this override is to support grouping on computed fields that are not stored in the database such as `amount_to_invoice_at_date (Amount)`, `qty_received_at_date (Received)`.
When `_read_group_for_accrual` is executed, it delegates grouping for non-computed fields to the parent `_read_group` implementation, as shown at [1].
The parent method returns results in `res` similar to:
```
[(datetime.datetime(2026, 6, 1, 0, 0), 1.0, 10.0, 1)]
```
During iteration over res at [2], the code uses `group[0]` as the grouping key. In this example, group[0] is `datetime.datetime(2026, 6, 1, 0, 0)`, which represents the granularity date
(e.g., the first day of the month when grouping by month).
However, `records_by_group` is keyed by the actual purchase order line order dates rather than the granularity dates returned by `_read_group`. For example:
```
{datetime.datetime(2026, 6, 12, 0, 0): purchase.order.line(1,)}
```
As a result, the lookup performed using the granularity date (`datetime.datetime(2026, 6, 1, 0, 0))` does not find a matching entry in `records_by_group`. Consequently, records falls back to an empty `purchase.order.line()` recordset.
Later, at [3], the aggregation logic computes totals using this empty recordset. Since the required fields are evaluated on an empty set of records, the aggregated values are computed as zero.
This ultimately causes the method to return a total value of zero
[1]-
https://github.com/odoo/enterprise/blob/eeea1377a7d36d11e140c44dee30a45228e7b4a6/account_accountant/models/analytic_mixin.py#L9-L24
[2]-
https://github.com/odoo/enterprise/blob/eeea1377a7d36d11e140c44dee30a45228e7b4a6/account_accountant/models/analytic_mixin.py#L40-L42
[3]-
https://github.com/odoo/enterprise/blob/eeea1377a7d36d11e140c44dee30a45228e7b4a6/account_accountant/models/analytic_mixin.py#L44-L47
## Solution:
The issue can be resolved by grouping records using the same date granularity specified in the groupby, rather than using the field values.
By aligning the grouping logic with the granularity returned by `_read_group` (for example, grouping by the first day of the month when using monthly grouping ), the keys in `records_by_group` match the values returned in `res`. As a result, the corresponding records are correctly retrieved during aggregation.
This ensures that the aggregation is performed on the appropriate purchase order lines instead of an empty recordset, allowing the computed totals to be calculated correctly.
[opw-6261225](https://www.odoo.com/odoo/project/49/tasks/6261225)
Forward-Port-Of: odoo/enterprise#120369Fixes an issue where the Planning Gantt view could crash when users grouped shifts by role and a role had no assigned resource or working schedule. This keeps planning reports usable for edge cases involving unstaffed or flexible roles.
Original PR description
Currently, an error occurs when grouping planning slots by role. **Steps to Reproduce:** - Install the `Planning` module. - Go to `Planning` > `Configuration` > `Roles`. - Create a `role` without…
Currently, an error occurs when grouping planning slots by role.
**Steps to Reproduce:**
- Install the `Planning` module.
- Go to `Planning` > `Configuration` > `Roles`.
- Create a `role` without assigning any resource to it (or assign a resource without a working time).
- Go to `Planning`, create a new `planning slot`, assign the `role` created above, set the start date to `20/07/2026 12:00 PM` and the end date to `21/07/2026 2:00 AM`.
- Switch to the `Gantt view` of the `planning slots`.
- Group by `Role` and set the custom date range to `07/19/2026 -> 07/20/2026`, then click `Apply`.
`KeyError: 1`
The error occurs when the user groups the planning slots by role in the Gantt view. During
the computation of the Gantt progress bar, if the existing slot's role has no resource, or has
a flexible resource without a calendar, the regular resources become empty [1]. Then it
attempts to compute the valid work intervals for these empty resources [2], resulting in an
empty calendar work interval dictionary ({}) [3]. Later, when computing the duration over the
period with the valid range slots, it tries to access the resource directly from the empty
calendar_intervals dictionary [4], which raises the error.
This commit ensures that, when no work intervals are available for a resource, an empty
work interval is used instead.
[1]- https://github.com/odoo/enterprise/blob/3871b75fb74a7b35bfea9610ca08b853eb723320/planning/models/planning_slot.py#L307
[2]: https://github.com/odoo/odoo/blob/5663509fe5caa1191fafcea3b3879dcef9ceca8f/addons/resource/models/resource_resource.py#L220
[3]: https://github.com/odoo/enterprise/blob/3871b75fb74a7b35bfea9610ca08b853eb723320/planning/models/planning_slot.py#L3415-L3417
[4]- https://github.com/odoo/enterprise/blob/3871b75fb74a7b35bfea9610ca08b853eb723320/planning/models/planning_slot.py#L3300
sentry-7620222164
Forward-Port-Of: odoo/enterprise#124991Mexican payroll users can now clear a payslip start or end date without triggering an error. The change checks that dates are present before running salary-limit warning calculations, keeping payslip editing smoother and preventing avoidable interruptions.
Original PR description
Currently, an error occurs when a user removes the payslip dates. **Steps to reproduce:** - Install the `l10n_mx_hr_payroll_account_edi` module with demo data. - Switch to `ZAPATERIA URTADO ÑERI`…
Currently, an error occurs when a user removes the payslip dates. **Steps to reproduce:** - Install the `l10n_mx_hr_payroll_account_edi` module with demo data. - Switch to `ZAPATERIA URTADO ÑERI` company - Go to `Payslips`, create a payslip. - Set an `employee`, and remove either the `start date` or the `end date` from Period.. `TypeError: unsupported operand type(s) for +: 'bool' and 'relativedelta'` After the [recent commit] adding a warning about the employee exceeding the salary limit, when the user removes the dates from the payslip, the compute method attempts to compute the warning from [1], and when it adds relativedelta to date_from, which is False, it raises the error [2]. This commit ensures that the payslip dates are checked first before adding relativedelta to the date and performing the comparison. [recent commit]: https://github.com/odoo/enterprise/commit/6abfa47dafe439f9328d606ef6ac5126ec6eb1f6 [1]- https://github.com/odoo/enterprise/blob/53a7fd4d53ffd510ad42632c69ce9d3a22c59e70/hr_payroll/models/hr_payslip.py#L1446 [2]- https://github.com/odoo/enterprise/blob/53a7fd4d53ffd510ad42632c69ce9d3a22c59e70/l10n_mx_hr_payroll_account_edi/models/hr_payslip.py#L272-L276 Forward-Port-Of: odoo/enterprise#125479 Forward-Port-Of: odoo/enterprise#122643
Odoo now imports Lazada and Shopee orders with discounts, vouchers, coins, and shipping fees in a way that matches the marketplace totals. This reduces reconciliation differences caused by rounding and makes order amounts clearer for sales and accounting teams.
Original PR description
Marketplace orders with discount lines could not match the platform total: Odoo accumulated a small rounding residue vs Shopee's total_amount / Lazada's order price. sale_shopee ----------- Changes:…
Marketplace orders with discount lines could not match the platform total: Odoo accumulated a small rounding residue vs Shopee's total_amount / Lazada's order price. sale_shopee ----------- Changes: - Fetch buyer-side escrow amounts via `_fetch_order_income` and pass them through `self.env.context` (`order_income`). - Build item lines from the buyer-paid item price with `discount=0` and a recomputed tax-exclusive `price_unit`. - Distribute order-level discounts (seller/platform vouchers and coins) as dedicated negative lines per product tax group via `_prepare_discount_lines_values`. - Append a shipping line from `buyer_paid_shipping_fee` with fiscal-position mapped taxes. - Reconcile any leftover residue with `_adjust_order_total` using a single tax-free amount-adjustment line. - Register `default_discount_product` and configure it on upgrade (v1.1). sale_lazada ----------- - Port the same reconciliation model as shopee: reconciled line specs, discount=0 with discounted unit from paid_price, shipping line from shipping_fee, order-level "Discount line" distributed at order-level. task-6112062 Forward-Port-Of: odoo/enterprise#125068 Forward-Port-Of: odoo/enterprise#117561
Users without Planning or Project permissions can now open the product catalog from relevant sales quotations without seeing an access error. The fix ensures the system checks permissions before reading restricted planning or field service information, reducing interruptions in the sales workflow.
Original PR description
A user without Project rights cannot add a product from the catalog on a sale order Steps to reproduce: 1. Install industry_fsm_sale module 2. Go to Settings > Users & Companies > Users and open user Marc Demo 3. Set Field Service and Project rights to No 4. Log in as Marc Demo 5. Go to Sales and open any quotation 6. Click on Catalog in the order lines 7. An access error is raised Issue: industry_fsm_sale overrides `action_add_from_catalog` and tries to read sale.order.tasks_ids but users can't always access this field as it requires Project rights Solution: Check that the user has Project rights before trying to read tasks_ids opw-6315647 Forward-Port-Of: odoo/enterprise#125526 Forward-Port-Of: odoo/enterprise#123228
Mexican payroll now calculates expected work hours even when a payslip has not yet been created. This helps off-cycle payroll runs start with accurate work hour and attendance values, reducing manual corrections and workflow interruptions.
Original PR description
Previously, the `_preprocess_work_hours_data` method would abort early if no payslip was found for the given period. This prevented the correct generation or evaluation of expected Mexican work hours…
Previously, the `_preprocess_work_hours_data` method would abort early if no payslip was found for the given period. This prevented the correct generation or evaluation of expected Mexican work hours in contexts where a draft payslip does not yet exist (i.e., when an off-cycle payslip is initially generated for a given time period). To resolve this, the strict dependency on the payslip record has been removed. It now falls back to the contract version's base data when a payslip is absent: - The calendar defaults to the contract version's `resource_calendar_id`. - The duration is assumed to be standard (`is_wrong_duration = False`). - The Mexican schedule table (`l10n_mx_schedule_table`) is fetched globally from the environment (`hr.rule.parameter`) rather than relying on the payslip-specific helper method. This ensures expected work hours and attendance fields are calculated consistently across all payroll workflows, regardless of whether the payslip has been instantiated. opw-6351402 Forward-Port-Of: odoo/enterprise#125219
The payroll correction wizard no longer asks users to choose between correcting one or multiple payslips when launched from a specific payslip. This prevents accidental broader corrections and keeps the action focused on the payslip the user opened.
Original PR description
Steps to reproduce: - Validate and pay two payslips for the same employee - Change a payroll field (e.g. wage) on the employee form, flagging both payslips as having wrong data - Open one of the paid payslips and click "Correct" - The wizard shows the single/multi radio selection Hide the radio selection in the button flow, like the other button-flow-specific elements of the wizard view. The wizard then falls back to its default correction_choice 'single', correcting only the opened payslip. task-6391197
The Belgian Partner VAT Listing now always uses the required calendar year period, from January 1 to December 31. This prevents incorrect VAT listing periods for companies whose fiscal year does not match the calendar year, improving compliance and reporting accuracy.
Original PR description
The Belgian Partner VAT Listing must always report on the civil calendar year (01/01/N to 12/31/N). Previously, the report was relying on the company's fiscal year configuration, which caused incorrect reporting periods for companies with non-calendar fiscal years. This commit overrides `_custom_options_initializer` to strictly enforce a civil year date range based on the selected year, entirely ignoring custom fiscal year boundaries. Task-6086513 Forward-Port-Of: odoo/enterprise#125752 Forward-Port-Of: odoo/enterprise#114337
This update fixes an issue in Belgian payroll where ONSS notification files could be analyzed incorrectly. It helps ensure payroll declaration feedback is processed more reliably, reducing the risk of administrative errors for Belgian employers.
Original PR description
Forward-Port-Of: odoo/enterprise#125500
This fix prevents payroll salary rule account settings from being reset when other apps, such as Point of Sale, are installed. Businesses that customize Swiss payroll accounting can now keep their manual debit and credit account choices intact.
Original PR description
### Steps to reproduce: - In a database with Switzerland localization, install 'Accounting' and 'Payroll' - Manually change the debit and credit accounts on the Swiss ELM salary rules (rule code…
### Steps to reproduce: - In a database with Switzerland localization, install 'Accounting' and 'Payroll' - Manually change the debit and credit accounts on the Swiss ELM salary rules (rule code 1000) - Install 'POS' - Check the accounts you configured on the salary rules >The accounts are reset to their default values ### Cause of Issue: POS depends on the module `stock_account`. When `stock_account` is installed, the `_configure_journals` method in its `__init__.py` creates a new `account.journal` for inventory valuation. To apply default values to this journal, the method retrieves data from the chart template. https://github.com/odoo/odoo/blob/7d16ef88784e18e885b97dbded3231775f1349d2/addons/stock_account/__init__.py#L41 The `hr_payroll_account` module overrides `_post_load_data` and unconditionally calls `_load_payroll_accounts(template_code, company)`. https://github.com/odoo/enterprise/blob/fcf06997a0eb999af86e4b6917311a86f04a390e/hr_payroll_account/models/account_chart_template.py#L16-L18 This triggers the reinstallation of the default payroll accounts, which overwrites and discards any manual configuration changes the user has made to their salary rules. ### Fix: Ensure that default payroll accounts are only reset during a genuine chart of accounts loading process, and not during localized post-load operations triggered by other modules. opw-6251112 Forward-Port-Of: odoo/enterprise#121687
Manufacturing planning now uses the product's Bill of Materials batch size even when no specific BOM is selected while adding the product to the Master Production Schedule. This helps planners get correct replenishment quantities and avoid under-planning production batches.
Original PR description
In MPS, if a product’s Bill of Materials (BOM) is not specified at the time of addition, the system will not correctly account for batch size. Steps to reproduce: ------------------- * Create a…
In MPS, if a product’s Bill of Materials (BOM) is not specified at the time of addition, the system will not correctly account for batch size. Steps to reproduce: ------------------- * Create a product with a bom that has a batch size of 2 * Open MPS * Add the product - without specifying the bom - Route Manufacture * Add 1 in the Forcast Demand -> the batch size from the bom it's not taken into account. Observation: ------------- When updating mps, it will call get_production_schedule_view_state: https://github.com/odoo/enterprise/blob/7092dd2cc3578c3f22d1fbc82d958d57e2f93553/mrp_mps/models/mrp_mps.py#L424 this function when calculating the quantity to resplenish will call _get_resplenish_qty: https://github.com/odoo/enterprise/blob/7092dd2cc3578c3f22d1fbc82d958d57e2f93553/mrp_mps/models/mrp_mps.py#L534 to know the quantity to resplenish it will need the batch size, in mps they will only consider the batch size from the bom registered: https://github.com/odoo/enterprise/blob/7092dd2cc3578c3f22d1fbc82d958d57e2f93553/mrp_mps/models/mrp_mps.py#L863-L865 Since there is no default value for bom_id, If there is no bom selected, there is no batch size. opw-6259956 Forward-Port-Of: odoo/enterprise#124922 Forward-Port-Of: odoo/enterprise#119560
Belgian payroll calculations now handle payslip corrections that are still in progress, not only those already finalized. This helps prevent incorrect historical payroll totals when correcting employee payslips, reducing the risk of payroll errors.
Original PR description
Currently when computing all_previous_monthly_payslips, if a corrected payslip has a correction in the done state, it will work correctly, but when we are currently correcting, since we are not in the done state yet, the negative payslip is not taken into account. Instead of assuming the correction payslip will be in a done state, we will now filter out all corrected and negative correction payslips task-6397633
Chilean invoice PDF copies now always show the legally required CEDIBLE disclaimer in Spanish. This prevents the footer from appearing in English when the customer’s language is set to something other than Spanish, supporting compliant local invoicing.
Original PR description
Steps to reproduce: - Set the database language to Spanish (Latin America). - Create a customer invoice, confirm it and send it to the SII. - Print it using Print > Invoice PDF copy (Chile). - Scroll…
Steps to reproduce:
- Set the database language to Spanish (Latin America).
- Create a customer invoice, confirm it and send it to the SII.
- Print it using Print > Invoice PDF copy (Chile).
- Scroll to the CEDIBLE section at the bottom of the PDF.
Cause of the issue:
The CEDIBLE footer is merged into l10n_cl.report_invoice_document, which account.report_invoice (odoo/addons/l10n_cl/views/report_invoice.xml) renders with t-lang set to the invoice partner's lang, not the database/user language. The disclaimer text was hardcoded in English and relied on the regular translation to be shown in Spanish, so as
soon as the partner's lang field isn't Spanish, the translation lookup falls back to the untranslated English source, regardless of the database language.
Solution:
This disclaimer is boilerplate mandated by Chilean law: it must always be printed in Spanish, independently of the invoice partner's or current user's language. The same template already follows that rule a few lines above for the SII stamp block ("Timbre Electrónico SII..."), which is hardcoded in Spanish instead of relying on translation.
opw-6390207
Forward-Port-Of: odoo/enterprise#124916This fixes Belgian payroll calculations by updating the 3000 deduction rules for the second and third quarters of 2026. It helps ensure payroll declarations and related accounting tests stay aligned with the expected legal values.
Original PR description
Forward-Port-Of: odoo/enterprise#124348 Forward-Port-Of: odoo/enterprise#124034
This fixes barcode transfer behavior when extra products are not allowed. Users are now prevented from scanning unreserved products after reopening a transfer, while immediate delivery transfers can still use the Add Product button when appropriate.
Original PR description
This [PR] made sure it was not possible to scan unreserved products when `allow_extra_product` was disabled, even when exiting and re-entering a transfer. It worked under the assumption that an immediate transfer always stays in draft, which is wrong for deliveries. The 2nd commit of this PR partly address this issue by allowing the user to add multiple products with the "Add Product" button when the transfer is immediate. While working on this issue, we encountered a bug in the scanning prevention that should have been caught by a tour but was not. This is fixed in the 1st commit. More details in the commit messages. [PR]: https://github.com/odoo/enterprise/pull/123793 Forward-Port-Of: odoo/enterprise#125313
Opening the Scrap option from a new manufacturing barcode operation no longer triggers an error. This improves reliability for warehouse and manufacturing users, including scenarios where consignment products are scanned before the manufacturing order is fully saved.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Open Barcode app; 2. click Operations; 3. click MANUFACTURING 4. click New; 5. click cogwheel on top right; 6. click Scrap. Issue ----- Traceback: > Error: Record stock.location with id=undefined doesn't exist in the cache Cause ----- When setting up the default context for the scrap menu, it it assumes `this.record` is not empty. Solution -------- Make `cache.getRecord` not raise an error when a location isn't found. Use optional chaining for other parts of the context that rely on a `record` being present. Also fixes a related issue introduced by 4b457fe, where the same traceback would be thrown on opening a new MO and scanning a product whilst consignment is enabled. opw-6397774 Forward-Port-Of: odoo/enterprise#125571 Forward-Port-Of: odoo/enterprise#124818
This fix prevents the Swiss payroll pension fund number from being included when checking BVG-LPP declaration status. It helps avoid incorrect status requests and supports smoother payroll declaration processing.
Original PR description
Forward-Port-Of: odoo/enterprise#126040
Expense card authorization updates now keep the merchant currency more reliably instead of falling back to the company currency. This helps avoid incorrect amounts or currency displays when Stripe sends authorization updates.
Original PR description
During updates of the authorization amounts the currency may revert to the company one Specifically, if the merchant currency cannot be found, it defaults to the company currency. We now broaden the search search on currency with the `ilike` operator Task [link](https://www.odoo.com/odoo/project.task/6345203) opw-6345203 Forward-Port-Of: odoo/enterprise#123772
Sales commission achievement records with very large IDs can now be opened correctly. This prevents users from seeing an incorrect “record does not exist” message when accessing those achievements.
Original PR description
Steps to reproduce: - Open an achievement with id > JS limit Issues: - We get a pop-up saying the record does not exists The reason we get this error is because since we are browsing a record with an id greater than JS limit the browser truncate it. In order to solve this issue the following PR was made #108751. A field `id_str` was added but it still wasn't working as we weren't retrieving the `id_str`. We now do this by passing `id_str` in the context and retrieving it on the `web_read`. Forward-Port-Of: odoo/enterprise#123757 Forward-Port-Of: odoo/enterprise#113701
Fixed an issue that could prevent the Payroll dashboard from opening when a payroll structure type had no scheduled pay configured. Users can now access the dashboard reliably even when this optional setting is left blank.
Original PR description
If one of the Payroll Structure Types has the Scheduled Pay field unset, opening the Payroll dashboard raises a traceback. Steps to reproduce the error: - Install ``hr_payroll`` module - Go to…
If one of the Payroll Structure Types has the Scheduled Pay field unset, opening the Payroll dashboard raises a traceback. Steps to reproduce the error: - Install ``hr_payroll`` module - Go to Payroll > Configuration > Settings > Set Payroll Closing Date > Save - Go to Payroll > Configuration > Structure Types > Create a new Structure Type > Unset Scheduled Pay - Open Dashboard Traceback: ```py AttributeError: 'bool' object has no attribute 'title' ``` https://github.com/odoo/enterprise/blob/9a3ea83a432f42f62076a50fca6bc771a2de96bf/hr_payroll/models/hr_payroll_warning.py#L413-L419 The dashboard collects the scheduled pay values from all structure types and later calls ``schedule.title()`` to build the labels. When a Structure Type has no Scheduled Pay configured, so ``schedule`` becomes ``False``, leading to the traceback. ``_get_schedule_pay`` method can return False at [1], So, It will generate the traceback from below line also. https://github.com/odoo/enterprise/blob/8a3d87d51a9a3c4df656a328a9179ee43541022d/hr_payroll/models/hr_payroll_warning.py#L401 Solution: Added a fallback value when default scheduled pay is False. [1]: https://github.com/odoo/enterprise/blob/8a3d87d51a9a3c4df656a328a9179ee43541022d/hr_payroll/models/hr_payroll_warning.py#L149-L154 sentry-7583037488 Forward-Port-Of: odoo/enterprise#122492
Swedish SIE4 general ledger exports now use the actual fiscal year dates selected by the company, including non-standard fiscal years. This prevents mismatches between the dates declared in the export and the accounting data included, improving reliability for reporting and compliance.
Original PR description
## Issue: Exporting the general ledger as SIE4 set the duration of fiscal years to one year from the starting date of the fiscal year. ## Steps to reproduce: - Create a fiscal year A of one month for…
## Issue: Exporting the general ledger as SIE4 set the duration of fiscal years to one year from the starting date of the fiscal year. ## Steps to reproduce: - Create a fiscal year A of one month for year X-1 (December 1st to December31th year X-1) - Create a fiscal year B of 1 year and 1 month (January 1st Year X to January 31th year X+1) - Create Invoices in November year X-1, December year X-1, year X and in January year X+1 and confirm them - Go to General Leder - Set date to the fiscal year B - Export as SIE4 ### Current behavior: - **for previous fiscal year** - declared fiscal year (#RAR field) goes : - from fiscal year X date_from -1 year - to fiscal year X date_to -1 year - However data are computed: - from fiscal year X date_from -1 year - to fiscal year X date_from -1 day - **for current fiscal year** - declared fiscal year (#RAR field) goes : - from fiscal year X date_from - to fiscal year X date_to - However data are computed: - from fiscal year X date_from - to fiscal year X date_from +1 year ### Expected behavior: Declared fiscal year match the one that is use for computation. - for previous fiscal year - from fiscal year X-1 date_from - to fiscal year X date_from -1 day - for current year - from fiscal year X date_from - to fiscal year X date_to Cause: Current year length was wrong because it [relied on](https://github.com/odoo/enterprise/blob/22b4100006ec24bf6e4b64042cbfdba360fcf470/l10n_se_sie4_export/models/account_general_ledger.py#L139-L140) the next_date_from which was wrong. opw-6264766 Forward-Port-Of: odoo/enterprise#125354
This fix prevents Mexican electronic invoice status checks from repeatedly triggering on the same documents. It reduces unnecessary background processing and prioritizes customer invoices so important checks are handled within the required time windows.
Original PR description
While trying to fix the SAT cron, we did not think it through it could cause infinite cron triggering. Indeed, the write_date is updated on every record that is handled. Fix is manyfold: - Avoid…
While trying to fix the SAT cron, we did not think it through it could cause infinite cron triggering. Indeed, the write_date is updated on every record that is handled. Fix is manyfold: - Avoid re-processing what we already check within the last 4 hours/12 hours depending on the type of the document. - The domain takes the *static* create date instead of the write_date to make sure we don't endless re-process the same record and that the window of 7/60 days applies. - Limit the Vendor Bill to be checked only during 7 days after their creation. - Use the create_date in the order of the search to ensure we process older records first, before their time-window closes. - Process the Vendor Bills last, this ensure Customer Invoices will be processed in priority in case we are not able to process everything within the last 4/12 hours. This is still imperfect and a little fragile, we will find a better solution in master, most likely by adding a dedicated field to keep track of the last SAT check. See https://github.com/odoo/enterprise/pull/123213 See https://github.com/odoo/enterprise/pull/103272 task-none Forward-Port-Of: odoo/enterprise#125598 Forward-Port-Of: odoo/enterprise#125317
This fix changes US payroll localization so it is installed through the standard automatic installation process instead of a later setup hook. This helps avoid upgrade issues where payroll localization modules could be temporarily treated as not installed, improving reliability for US companies using payroll.
Original PR description
In a [previous PR], a test was introduced to reject any `l10n_xx_hr_*` module that has a `countries` key in its manifest and depends on a module that also has that country key. This test was too…
In a [previous PR], a test was introduced to reject any `l10n_xx_hr_*` module that has a `countries` key in its manifest and depends on a module that also has that country key. This test was too broad and rejected some valid cases: 1. A non-auto-install module can have a country key defined to add flags in the apps kanban view. ([src]) 2. A module that has a country-specific regular dependency, but not as an auto-install condition. The second case is illustrated by [l10n_us_hr_payroll], which should auto-install when `hr_payroll` is installed and a US company exists. With the old test, achieving this required adding `l10n_us` to its auto-install dependencies. But, since `l10n_us` is not auto-installable, `l10n_us_hr_payroll` would not be installed if you create a DB with a US company and only install `hr_payroll`. In practice, that module was still being installed via a [post-init hook] in `hr_payroll`. This hook was installing all `l10n_XX_hr_payroll` modules for each country where a company is located, which is the behavior of the `countries` parameter in the manifest. This caused issues during upgrades as this runs late in the process: after the auto-discovery phase. Modules installed by this hook would be considered as `uninstalled` until `hr_payroll` is loaded. This commit narrows the check to only fail if: - A module has a `country` key in its manifest, and - It has a country-specific module in its **auto-install** dependencies. Moreover, it modifies `l10n_us_hr_payroll` to correctly rely on the auto_install mechanism instead of the post-init hook. [previous PR]: https://github.com/odoo/enterprise/pull/101843 [src]: https://github.com/odoo/odoo/blob/6df9f92a537aa4bb4ee5dc946fe31c4e56e6dfea/odoo/addons/base/models/ir_module.py#L271-L273 [l10n_us_hr_payroll]: https://github.com/odoo/enterprise/blob/24a33ffb769557be498d61328522bb77f68d3a5a/l10n_us_hr_payroll/__manifest__.py [post-init hook]: https://github.com/odoo/enterprise/blob/85185595cfd1ee5310ceb9dc80c0589accad2f19/hr_payroll/__init__.py#L21 Forward-Port-Of: odoo/enterprise#125853 Forward-Port-Of: odoo/enterprise#120279
Swiss employee payslips now show the contract withdrawal date rather than the payroll version end date. This prevents incorrect end dates from appearing on payslip reports when those dates differ.
Original PR description
The Withdrawal Date in the payslip of CH employees was printing the date_end relative to the version related to the payslip. Instead, it should print the end of the contract of that version, since they can be different. The end date of the contract is in l10n_ch_withdrawal. Task: 6398291 Forward-Port-Of: odoo/enterprise#124848
Steps to Reproduce: - Go to Settings > Translations > Languages and select your active language. - Change the Time Format to a 13:00:00 (24-hour) - Click on the Attendance systray icon in the top navbar and Check In. - Notice that the recorded time still displays in a 12-hour format. Cause: - The attendance popup doesn't enforce a strict 12-hour or 24-hour rule. Because of this missing rule, your web browser just uses your computer's default time settings. As a result, Odoo's actual
Original PR description
Steps to Reproduce: - Go to Settings > Translations > Languages and select your active language. - Change the Time Format to a 13:00:00 (24-hour) - Click on the Attendance systray icon in the top…
Steps to Reproduce:
- Go to Settings > Translations > Languages and select your active language.
- Change the Time Format to a 13:00:00 (24-hour)
- Click on the Attendance systray icon in the top navbar and Check In.
- Notice that the recorded time still displays in a 12-hour format.
Cause:
- The attendance popup doesn't enforce a strict 12-hour or 24-hour rule. Because of this missing rule, your web browser just uses your computer's default time settings. As a result, Odoo's actual language and time settings are completely ignored.
Fix:
- Replaced the browser-based formatting with the existing formatting utilities.
- Used is24HourFormat() to determine whether the active time format uses a 12-hour or 24-hour clock.
Solution:
- Dynamically selected the display format using:
- HH:mm for 24-hour format
- hh:mm a for 12-hour format
- Applied the selected format consistently for both check-in and check-out times so the systray now correctly follows the configured language time format.
task-6120540
Forward-Port-Of: odoo/odoo#259918**Steps to reproduce:** - Go to Discuss app - Start a new meeting - Enable Push-To-Talk in voice settings - A banner for the discuss extension recommendation is added the first time you enable the setting - Banner makes the call window move down - Call actions are pushed to the bottom of the screen and not easily accessible **Issue:** An ad banner for the Push-To-Talk extension was added by [1], but it was inserted above the call window rather than on top of it, causing the content bel
Original PR description
**Steps to reproduce:** - Go to Discuss app - Start a new meeting - Enable Push-To-Talk in voice settings - A banner for the discuss extension recommendation is added the first time you enable the setting - Banner makes the call window move down - Call actions are pushed to the bottom of the screen and not easily accessible **Issue:** An ad banner for the Push-To-Talk extension was added by [1], but it was inserted above the call window rather than on top of it, causing the content below to be pushed down. **Fix:** Moved the banner inside the call window, but only when it is not compact (not in smaller chat window or mobile). Could fix with css but we probably don't want to show the banner in these cases anyway (as it would take too much space in the chat window, or not be relevant to mobile users). [1] https://github.com/odoo/odoo/commit/d45c92eb07cd16cc45b0e9c8bf9422fe974f0c62 opw-6250056 Forward-Port-Of: odoo/odoo#278804 Forward-Port-Of: odoo/odoo#277982
When a product uses automated inventory valuation, scrapping it from an already validated (done) picking generated no inventory valuation journal entry, even though the stock move value and the on-hand quantity were correctly updated. The same scrap done from the Scrap menu, or from a picking that is not done yet, worked as expected. A stock move whose picking is already done is created directly in the 'done' state (stock.move.create). Such a move is filtered out of the recordset returned by
Original PR description
When a product uses automated inventory valuation, scrapping it from an already validated (done) picking generated no inventory valuation journal entry, even though the stock move value and the on-hand quantity were correctly updated. The same scrap done from the Scrap menu, or from a picking that is not done yet, worked as expected. A stock move whose picking is already done is created directly in the 'done' state (stock.move.create). Such a move is filtered out of the recordset returned by _action_done(), on which _create_account_move() is called, so the scrap move never received its journal entry. Steps to reproduce: - Use a storable product with automated inventory valuation - Create and validate a receipt for it - Open the completed picking, click Scrap, set a quantity and validate it - The stock is reduced but no journal entry is created. opw-6368258 Forward-Port-Of: odoo/odoo#278210 Forward-Port-Of: odoo/odoo#275847
Steps to reproduce: - Install the `l10n_br` module. - Go to Portal > Addresses > Add Address > select Brazil as the country. (Do not change the company's country to Brazil) Issue: - The address layout is broken: the Street input has no label and `Steet and Number` field is missing. Cause: - The `o_extended_address` elements are not rendered when the company country is not Brazil. When the user selects Brazil, `_setVisibility` looks for `o_extended_address` elements but finds none, s
Original PR description
Steps to reproduce: - Install the `l10n_br` module. - Go to Portal > Addresses > Add Address > select Brazil as the country. (Do not change the company's country to Brazil) Issue: - The address layout is broken: the Street input has no label and `Steet and Number` field is missing. Cause: - The `o_extended_address` elements are not rendered when the company country is not Brazil. When the user selects Brazil, `_setVisibility` looks for `o_extended_address` elements but finds none, so it fails to make the standard address fields visible. Fix: - Restore the company country condition in JS so `o_standard_address` is not hidden when no `o_extended_address` elements are rendered. Forward-Port-Of: odoo/odoo#278008
The mock server was computing the reaction sequence with `Math.min(reactionGroup.map(...))` instead of `Math.min(...reactionGroup.map(...))`. This returned `NaN`, making the sort order non-deterministic and causing the 'Reactions are ordered by id' test to be flaky. Fixes runbot error https://runbot.odoo.com/odoo/error/944188 Forward-Port-Of: odoo/odoo#278895
Original PR description
The mock server was computing the reaction sequence with `Math.min(reactionGroup.map(...))` instead of `Math.min(...reactionGroup.map(...))`. This returned `NaN`, making the sort order non-deterministic and causing the 'Reactions are ordered by id' test to be flaky. Fixes runbot error https://runbot.odoo.com/odoo/error/944188 Forward-Port-Of: odoo/odoo#278895
Description of the issue/feature this PR addresses: Updates `test_auth_ldap` to retrieve the company associated with the current environment instead of relying on a hardcoded value. This prevents test failures in environments where the hardcoded company does not exist. Resolves https://runbot.odoo.com/odoo/error/243763 opw-6353706
Original PR description
Description of the issue/feature this PR addresses: Updates `test_auth_ldap` to retrieve the company associated with the current environment instead of relying on a hardcoded value. This prevents test failures in environments where the hardcoded company does not exist. Resolves https://runbot.odoo.com/odoo/error/243763 opw-6353706
## Issue In Attendances > Management, negative overtimes do not appear in the list, even if they need approval from a manager. ## Steps to reproduce 1. Install *Attendances* (`hr_attendance`) 2. In Settings: - Toggle *Attendances from Backend* - Toggle *Absence Management* - Toggle *Display Extra Hours* - Set *Extra Hours Validation* to *Approved by Manager* 3. On an Employee E: - Overtime Ruleset: Default Ruleset 4. In Attendances, create an attendance for emplo
Original PR description
## Issue In Attendances > Management, negative overtimes do not appear in the list, even if they need approval from a manager. ## Steps to reproduce 1. Install *Attendances* (`hr_attendance`) 2. In…
## Issue
In Attendances > Management, negative overtimes do not appear in the list, even if they need approval from a manager.
## Steps to reproduce
1. Install *Attendances* (`hr_attendance`)
2. In Settings:
- Toggle *Attendances from Backend*
- Toggle *Absence Management*
- Toggle *Display Extra Hours*
- Set *Extra Hours Validation* to *Approved by Manager*
3. On an Employee E:
- Overtime Ruleset: Default Ruleset
4. In Attendances, create an attendance for employee E on a day where they are expected to work. The attendance should be shorter than a full day of work (e.g., from 9:00am to 11:00am, which would be -6 hours of overtime if 8 hors are expected).
5. Navigate to Attendances > Management
6. **The attendance created in Step 4 does not appear, even though it should be approved by a manager.**
## Cause
The domain for the `hr_attendance_management_action` is the following:
https://github.com/odoo/odoo/blob/22a94663e4c1672366b7a614943cef843ced3503/addons/hr_attendance/views/hr_attendance_view.xml#L439
The `overtime_hours > 0` condition was added by https://github.com/odoo/odoo/commit/e5067262174725466056e9a6c530439b4845c19b with the intent to remove attendance records with zero extra hours. Instead, it removes all records with less than zero extra hours.
opw-6372360**Steps to reproduce:** 1. Enable "Display Product Images" in Sales settings 2. Set the document layout table style to Boxed, Bubble or Column [Settings -> Companies -> Document Layout] 3. Create a quotation with a product that has an image and a long description 4. Print the quotation as PDF **Issue:** The product description text overflows the Description column boundary and crosses into the Quantity column, overlapping the separator line **Why this happens:** - The `td_product_nam
Original PR description
**Steps to reproduce:** 1. Enable "Display Product Images" in Sales settings 2. Set the document layout table style to Boxed, Bubble or Column [Settings -> Companies -> Document Layout] 3. Create a quotation with a product that has an image and a long description 4. Print the quotation as PDF **Issue:** The product description text overflows the Description column boundary and crosses into the Quantity column, overlapping the separator line **Why this happens:** - The `td_product_name` cell uses a `d-flex` container to place the product image and description text side by side - wkhtmltopdf does not properly constraint the text div's width, so it's width grew wider than the `td` **Fix:** - Replace the `d-flex` wrapper with a CSS `float` layout - `overflow: hidden` on `.o_product_name_cell` prevents overlap on sibling float and automatically occupy exactly the remaining width beside it opw-6408701
## Current behavior: Clicking on the Late activity for Lot/Serial in the notification systray doesn't apply the Late activities filter. ## Expected behavior: Clicking on the Late activity for Lot/Serial in the notification systray should apply the Late activities filter. ## Steps to reproduce: 1. Install Inventory (stock) module, make sure to enable Lots & Serial Numbers in Inventory > Traceability 2. Create some new Lots / Serial numbers 3. Add some Activities with Due Date before to
Original PR description
## Current behavior: Clicking on the Late activity for Lot/Serial in the notification systray doesn't apply the Late activities filter. ## Expected behavior: Clicking on the Late activity for…
## Current behavior: Clicking on the Late activity for Lot/Serial in the notification systray doesn't apply the Late activities filter. ## Expected behavior: Clicking on the Late activity for Lot/Serial in the notification systray should apply the Late activities filter. ## Steps to reproduce: 1. Install Inventory (stock) module, make sure to enable Lots & Serial Numbers in Inventory > Traceability 2. Create some new Lots / Serial numbers 3. Add some Activities with Due Date before today 4. Observe that the Clock icon on systray will count up, showing the number of activities that are late, for today and for future 5. Click on the Late activities (e.g. 2 Late) should only show the 2 late activities. Instead, no filter is applied, thus showing all the Lots / Serial numbers in the inventory ## Cause of the issue: Missing filters for Late, Today and Future activities in the stock_lot_views.xml ## Fix: Added 3 filters for Late, Today and Future activities opw-6332560 Forward-Port-Of: odoo/odoo#278165 Forward-Port-Of: odoo/odoo#272735
Steps to reproduce the bug: - Install l10n_ke_edi_oscu_stock - Run Test_sale_mrp_kit_bom_cogs Problem: ```self.assertAlmostEqual(stock_out_aml.credit, 1.53, msg="Should not include the value of consumable component") AssertionError: 3.07 != 1.53 within 7 places (1.5399999999999998 difference) : Should not include the value of consumable component ``` The test delivered 1 whole unit of every component of Kit A regardless of the fractional quantity actually needed to produce a single kit
Original PR description
Steps to reproduce the bug: - Install l10n_ke_edi_oscu_stock - Run Test_sale_mrp_kit_bom_cogs Problem: ```self.assertAlmostEqual(stock_out_aml.credit, 1.53, msg="Should not include the value of…
Steps to reproduce the bug: - Install l10n_ke_edi_oscu_stock - Run Test_sale_mrp_kit_bom_cogs Problem: ```self.assertAlmostEqual(stock_out_aml.credit, 1.53, msg="Should not include the value of consumable component") AssertionError: 3.07 != 1.53 within 7 places (1.5399999999999998 difference) : Should not include the value of consumable component ``` The test delivered 1 whole unit of every component of Kit A regardless of the fractional quantity actually needed to produce a single kit (0.34/0.14/0.2 units for Component A/B/BB respectively). This went unnoticed under the default invoice_policy 'order', since qty_delivered never drives the invoiced quantity in that case. l10n_ke_edi_oscu_stock forces invoice_policy to 'delivery' for storable products that have no explicit company_id, which is the case for the products created in this test. With invoice_policy 'delivery', _compute_kit_quantities() correctly reads the over-delivered components as enough stock to form 2 complete kits (min ratio 2.94, floored to 2) instead of 1, doubling the invoiced quantity and the resulting COGS (3.07 instead of 1.53). runbot-243633 Forward-Port-Of: odoo/odoo#277519
Steps to reproduce the bug: - Run the product module test suite on a loaded/slow CI runner - Observe test_get_first_possible_combination occasionally failing Problem: test_get_first_possible_combination asserts that _get_first_possible_combination() completes in under 0.5 seconds on a template with 10 attributes x 50 values and exclusion rules. On a busy runner (Testing country uk build) it took 0.587s and the test failed with `0.5868358612060547 not less than 0.5`, even though the return
Original PR description
Steps to reproduce the bug: - Run the product module test suite on a loaded/slow CI runner - Observe test_get_first_possible_combination occasionally failing Problem:…
Steps to reproduce the bug: - Run the product module test suite on a loaded/slow CI runner - Observe test_get_first_possible_combination occasionally failing Problem: test_get_first_possible_combination asserts that _get_first_possible_combination() completes in under 0.5 seconds on a template with 10 attributes x 50 values and exclusion rules. On a busy runner (Testing country uk build) it took 0.587s and the test failed with `0.5868358612060547 not less than 0.5`, even though the returned combination was correct. The 0.5s threshold is an arbitrary sanity check meant to catch a gross algorithmic regression (e.g. loss of early pruning of invalid combinations), not a strict performance SLA, so it is too tight to survive normal CI load variance. Solution: Raise the threshold to 2 seconds, keeping enough margin to absorb CI load variance while still catching a real performance regression, which would take far longer than the current computation. runbot-243606 Forward-Port-Of: odoo/odoo#277986
Steps to reproduce the bug: - Create a purchase requisition: - add any storable product and vendor - From it, create a purchase order and confirm it -> a picking is created - Cancel the "purchase.requisition" Problem: The confirmed purchase order was cancelled even though it had already been validated (state = 'purchase') and had active receipts or vendor bills attached to it. In `action_cancel`, `requisition.purchase_ids.button_cancel()` is called unconditionally on all linked POs,
Original PR description
Steps to reproduce the bug:
- Create a purchase requisition:
- add any storable product and vendor
- From it, create a purchase order and confirm it -> a picking is created
- Cancel the "purchase.requisition"
Problem:
The confirmed purchase order was cancelled even though it had already been validated (state = 'purchase') and had active receipts or vendor bills attached to it.
In `action_cancel`, `requisition.purchase_ids.button_cancel()` is called unconditionally on all linked POs, with no check on their current state or on whether picking or invoices existed.
Solution:
Only cancel linked purchase orders that are still in 'draft' state. Once
outside of that state, the purchase process might be too far engaged to
simply cancel the purchase order without notice.
opw-6329742
Forward-Port-Of: odoo/odoo#272190Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: . Add safe execution to the element before use focus() task-6409715 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278083
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: . Add safe execution to the element before use focus() task-6409715 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278083
Currently, an error occurs when grouping invoice lines by tax. **Steps to Reproduce:** - Install the `Accounting` module. - Go to `Accounting` > `Customers` > `Invoices` and `create an invoice`. - Add an `invoice line`, set a `price`, and select an `account`. - Go to `Accounting` > `Configuration` > `Chart of Accounts`, open the account used on the invoice line, and clear its `Code` field. - Return to the `invoice`, click `Action` > `(Un)Group lines by tax`. `ValueError: Typ
Original PR description
Currently, an error occurs when grouping invoice lines by tax. **Steps to Reproduce:** - Install the `Accounting` module. - Go to `Accounting` > `Customers` > `Invoices` and `create an invoice`. -…
Currently, an error occurs when grouping invoice lines by tax.
**Steps to Reproduce:**
- Install the `Accounting` module.
- Go to `Accounting` > `Customers` > `Invoices` and `create an invoice`.
- Add an `invoice line`, set a `price`, and select an `account`.
- Go to `Accounting` > `Configuration` > `Chart of Accounts`, open the account used on
the invoice line, and clear its `Code` field.
- Return to the `invoice`, click `Action` > `(Un)Group lines by tax`.
`ValueError: TypeError('sequence item 1: expected str instance, bool found') while evaluating`
`'if records:\n records.action_group_ungroup_lines_by_tax()'`
After this [recent commit], account codes became optional and can be removed. As a result,
when a user adds an account with no code to an invoice line and groups the lines by the same
tax, it creates the grouped line from here [1]. Then, when it gets the account code from the
grouped line to prepare the name, the code is False, which raises the error [2].
This commit ensures that the grouped line name is built using filter(None, ...), which removes
None and other falsy values, so that the account code is included if it exists; otherwise,
it is not included.
[recent commit]: https://github.com/odoo/odoo/commit/c3313b336b9f1305c363097745926f2bdf61e277
[1]- https://github.com/odoo/odoo/blob/92ced215895d027a2b5606dbecbf3eb96b9dcd10/addons/account_edi_ubl_cii/models/account_move.py#L156-L158
[2]- https://github.com/odoo/odoo/blob/92ced215895d027a2b5606dbecbf3eb96b9dcd10/addons/account_edi_ubl_cii/models/account_move.py#L189-L193
sentry-7598941609
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prBefore this commit, starting a tour in test mode on the tours viewz wasn't triggering the redirect at the first step of the tour. Now, it redirect. TASK-6331071 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
Before this commit, starting a tour in test mode on the tours viewz wasn't triggering the redirect at the first step of the tour. Now, it redirect. TASK-6331071 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The implementation of the highlight of missing required settings (#249321) was discarding the `SearchableSetting` if the `<setting>` had no `id`. This behavior disabled the highlight of the setting formPage in those cases. This commit fixes the issue by allowing `settingId` to be undefined. Note that `settingId` can safely be undefined since it is used only for the highlight behavior and during a case of url hash check. task-6364849
Original PR description
The implementation of the highlight of missing required settings (#249321) was discarding the `SearchableSetting` if the `<setting>` had no `id`. This behavior disabled the highlight of the setting formPage in those cases. This commit fixes the issue by allowing `settingId` to be undefined. Note that `settingId` can safely be undefined since it is used only for the highlight behavior and during a case of url hash check. task-6364849
The test that verifies the behavior of cancelling the link popover during an attachment upload relies on a hard-coded delay. Occasionally, when the test runs on an overloaded runbot infrastructure, the upload manages to complete before the discard happens. This commit fixes this by making sure the upload never completes within the test. runbot-940190 runbot-944098 Forward-Port-Of: odoo/odoo#278820
Original PR description
The test that verifies the behavior of cancelling the link popover during an attachment upload relies on a hard-coded delay. Occasionally, when the test runs on an overloaded runbot infrastructure, the upload manages to complete before the discard happens. This commit fixes this by making sure the upload never completes within the test. runbot-940190 runbot-944098 Forward-Port-Of: odoo/odoo#278820
**Issue** Printing an invoice for a returned dropshipped tracked product could display the wrong lot/serial number on the invoice report. **Steps to reproduce** - Activate "Display Lots & Serial Numbers on Invoices" - Create a product tracked by serial/lot and enable the dropship route - Create two lots: "lot1" and "lot2" - Create and confirm a SO for quantity 2 - Confirm the PO and validate the dropship for both lots - Create and post an invoice - Return "lot2" from the dropship pick
Original PR description
**Issue** Printing an invoice for a returned dropshipped tracked product could display the wrong lot/serial number on the invoice report. **Steps to reproduce** - Activate "Display Lots & Serial…
**Issue**
Printing an invoice for a returned dropshipped tracked product could display the wrong lot/serial number on the invoice report.
**Steps to reproduce**
- Activate "Display Lots & Serial Numbers on Invoices"
- Create a product tracked by serial/lot and enable the dropship route
- Create two lots: "lot1" and "lot2"
- Create and confirm a SO for quantity 2
- Confirm the PO and validate the dropship for both lots
- Create and post an invoice
- Return "lot2" from the dropship picking
- Create and post a credit note for quantity 1
- Click on print on the invoice
-> The generated PDF displays "lot1 & lot2" instead of "lot1"
**Cause**
While rendering `account.report_invoice_with_payments`, the report calls `_get_invoiced_lot_values` to determine which lot/serial numbers should be displayed:
https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L31-L32 `invoiced_qties = 2` since the invoice is on a quantity of 2 https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L44 Three stock move lines are retrieved from the SO:
- the two original dropship deliveries,
- the return move for `lot2`. https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L63 However, none of them are considered as `is_stock_return` because the dropship locations use `supplier` instead of `internal`: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L72-L76 As a consequence:
- The two original delivery move lines each keep quantity `1`: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L69 they never pass through the return handling logic (as they should be): https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L77-L80
- for the last one, `is_stock_return = False` while it should not, thus the quantity is 1 instead of 0. Furthermore, it does not pass by this code:
https://github.com/odoo/odoo/blob/8759429547e42e9f63b15a7c80475be46ef437e2/addons/sale_stock/models/account_move.py#L79 which would make the quantity for lot2 equalled to 0 (1-1) The quantities are therefore accumulated as:
https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L92
resulting in:
`qties_per_lot = {lot1: 1, lot2: 2}`
instead of:
`qties_per_lot = {lot1: 1, lot2: 0}`
The report selects both lots since it starts with lot1 (qty of 1): https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L94-L99
opw-6236855
Forward-Port-Of: odoo/odoo#270599This commit [1] added a top margin to headings for the html_editor. However, this margin was also applied in the website, breaking the WYSIWYG behavior. Exclude the website from this rule so the margin is only applied in the html_editor. [1]: https://github.com/odoo/odoo/commit/13a452106733c950a7e25cfeb5107eb03367b756 Forward-Port-Of: odoo/odoo#278730
Original PR description
This commit [1] added a top margin to headings for the html_editor. However, this margin was also applied in the website, breaking the WYSIWYG behavior. Exclude the website from this rule so the margin is only applied in the html_editor. [1]: https://github.com/odoo/odoo/commit/13a452106733c950a7e25cfeb5107eb03367b756 Forward-Port-Of: odoo/odoo#278730
# How to reproduce - Have two language in the db - Create an e-Commerce category - Have a different translation for each language for that category's name - Copy the link to that category's name in one language (Should be something like /shop/category/name-x) - Have two websites, each with a different default language - Create a link to the shop category in each website. > ! The link must be the exact same > You can put it in the header menu for simplicity - Open the website editor - D
Original PR description
# How to reproduce - Have two language in the db - Create an e-Commerce category - Have a different translation for each language for that category's name - Copy the link to that category's name in…
# How to reproduce
- Have two language in the db
- Create an e-Commerce category
- Have a different translation for each language for that category's name
- Copy the link to that category's name in one language (Should be something like /shop/category/name-x)
- Have two websites, each with a different default language
- Create a link to the shop category in each website.
> ! The link must be the exact same
> You can put it in the header menu for simplicity
- Open the website editor
- Do 2 or 3 times :
- click on the category link and switch website
# The issue
A traceback is displayed
# Cause
This manipulation will make us enter an infinite redirect scenario described here :
https://github.com/odoo/odoo/blob/f8741728294a5147c7d2427d9997738096386262/addons/website/static/src/client_actions/website_preview/website_builder_action.js#L371-L384
The problem is that this commit introduced an assignation to `iframe.contentDocument.body` before the patch :
https://github.com/odoo/odoo/commit/89994eb7a54ca606bab26b6d579d03e86c11ba60
But in our case, iframe.contentDocument is null, so it throws an error before the patch can be applied
opw-6322115
Forward-Port-Of: odoo/odoo#276634Unlocking a validated MO to add a new component move should, naturally, bring about a validated move. Although there exists a `state` check in `stock.move`'s `create()` as of odoo/odoo#196161, it only checks for `picking_id`, whereas a component move has a `raw_material_production_id` (and a finished (by)product has a `production_id`), so we replicate the check here. Task ID: [6226710](https://www.odoo.com/odoo/project/966/tasks/6226710) Forward-Port-Of: odoo/odoo#267186
Original PR description
Unlocking a validated MO to add a new component move should, naturally, bring about a validated move. Although there exists a `state` check in `stock.move`'s `create()` as of odoo/odoo#196161, it only checks for `picking_id`, whereas a component move has a `raw_material_production_id` (and a finished (by)product has a `production_id`), so we replicate the check here. Task ID: [6226710](https://www.odoo.com/odoo/project/966/tasks/6226710) Forward-Port-Of: odoo/odoo#267186
Once the cron is called to update current_version_id, the new employee calendar is applied to the previous version as well, due to the inverse on resource.resource def _inverse_calendar_id(self): for resource in self: if resource.calendar_id != resource.employee_id.resource_calendar_id: resource.employee_id.resource_calendar_id = resource.calendar_id All that because the introduced piece of code was called before super if 'current_versi
Original PR description
Once the cron is called to update current_version_id, the new employee calendar is applied to the previous version as well, due to the inverse on resource.resource
def _inverse_calendar_id(self):
for resource in self:
if resource.calendar_id != resource.employee_id.resource_calendar_id:
resource.employee_id.resource_calendar_id = resource.calendar_id
All that because the introduced piece of code was called before super
if 'current_version_id' in vals:
new_version = self.env['hr.version'].browse(vals.get('current_version_id'))
self.resource_id.calendar_id = new_version.resource_calendar_id
And this the inverse method was called on the previous version (not yet updated), not the new one.
Forward-Port-Of: odoo/odoo#279048## Problem When a `web_read_group` call is made with some condition on the active field, the active test is bypassed by adding `['active', 'in', [True, False]]` to the domain. This will cause a search to fail if the model's active field is not called `active` (like in a studio model). ## Solution We will change the domain to `[self._active_name, 'in', [True, False]]` to properly handle customizations. ## Steps to replicate (Runbot v19) 1. Create a new model with Studio - enable Pipeline
Original PR description
## Problem When a `web_read_group` call is made with some condition on the active field, the active test is bypassed by adding `['active', 'in', [True, False]]` to the domain. This will cause a search to fail if the model's active field is not called `active` (like in a studio model). ## Solution We will change the domain to `[self._active_name, 'in', [True, False]]` to properly handle customizations. ## Steps to replicate (Runbot v19) 1. Create a new model with Studio - enable Pipeline and Archiving 2. Open the kanban view and add 'Archived' to the filter 3. Traceback opw-6403422 Forward-Port-Of: odoo/odoo#277908 Forward-Port-Of: odoo/odoo#277666
`_get_belgian_cocontractant_note()` resolves the co-contractant fiscal position through chart_template.ref(), which uses env.company. The "Send invoices automatically" cron runs as the inactive OdooBot user, so env.company is OdooBot's default company, not the invoice's. That company can differ from the invoice's and even be archived, in which case ref() raises "IndexError: tuple index out of range" (parent_ids is empty for an archived company) Steps to reproduce: - Set the main company to a
Original PR description
`_get_belgian_cocontractant_note()` resolves the co-contractant fiscal position through chart_template.ref(), which uses env.company. The "Send invoices automatically" cron runs as the inactive OdooBot user, so env.company is OdooBot's default company, not the invoice's. That company can differ from the invoice's and even be archived, in which case ref() raises "IndexError: tuple index out of range" (parent_ids is empty for an archived company) Steps to reproduce: - Set the main company to a non-Belgian company, and invoice from another active Belgian company. - Move every active user off the main company and archive it - Send a Belgian 0% invoice through the cron. => IndexError: tuple index out of range in chart_template.ref opw-6398778 Forward-Port-Of: odoo/odoo#278666 Forward-Port-Of: odoo/odoo#278326
- Fix: The edit() calls now pass { confirm: false } to avoid calling the extra step that involved clicking manually on the input to trigger the search and the dropdown display. This should remove the race condition. - Small cleanup: clickFieldDropdownItem replaces the hardcoded ".dropdown-item:nth-child(1)" click, allowing selecting by product name instead of position. runbot-error: 941390 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-P
Original PR description
- Fix: The edit() calls now pass { confirm: false } to avoid calling the extra step that involved clicking manually on the input to trigger the search and the dropdown display. This should remove the race condition.
- Small cleanup: clickFieldDropdownItem replaces the hardcoded ".dropdown-item:nth-child(1)" click, allowing selecting by product name instead of position.
runbot-error: 941390
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#278813When an order/invoice is fully discounted by a global discount, its base and tax amounts are sums of values each already rounded to the currency precision, so their sum is only a sub-unit floating point residue (~1e-6) instead of a clean zero. `_get_tax_totals_summary` fed that raw sum straight to the cash rounding. With a 'UP' (or 'DOWN') rounding method the residue was inflated into a full rounding step, e.g. a 0.01 total to pay on an otherwise empty document. opw-6402143 --- I confi
Original PR description
When an order/invoice is fully discounted by a global discount, its base and tax amounts are sums of values each already rounded to the currency precision, so their sum is only a sub-unit floating point residue (~1e-6) instead of a clean zero. `_get_tax_totals_summary` fed that raw sum straight to the cash rounding. With a 'UP' (or 'DOWN') rounding method the residue was inflated into a full rounding step, e.g. a 0.01 total to pay on an otherwise empty document. opw-6402143 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278291
When the shop sidebar categories are enabled with collapsed categories, subcategory names could wrap unexpectedly at 100% zoom or lower, even when there was enough available space. Steps to reproduce: - Open the Shop page and click Edit - Go to the Style tab - Set Content Width to Full - Enable the Categories sidebar - Enable Collapse Category This issue caused sidebar subcategory labels to wrap only at lower zoom levels, while higher zoom levels displayed them correctly. Add CSS
Original PR description
When the shop sidebar categories are enabled with collapsed categories, subcategory names could wrap unexpectedly at 100% zoom or lower, even when there was enough available space. Steps to reproduce: - Open the Shop page and click Edit - Go to the Style tab - Set Content Width to Full - Enable the Categories sidebar - Enable Collapse Category This issue caused sidebar subcategory labels to wrap only at lower zoom levels, while higher zoom levels displayed them correctly. Add CSS rules to prevent category names in the sidebar from wrapping. opw-6296804 Forward-Port-Of: odoo/odoo#275279
When receiving a Peppol/UBL XML file containing an embedded PDF via an email alias, the PDF is not extracted and attached to the resulting vendor bill. Steps to reproduce: - Set up a BE Company - Configure an incoming mail server - Set up an email alias for the Vendor Bill journal - Receive a Peppol XML with embedded PDF via alias - Check the created Bill Issue: PDF has not been extracted from the xml This occurs because the received xml is set as main attachment for the record a
Original PR description
When receiving a Peppol/UBL XML file containing an embedded PDF via an email alias, the PDF is not extracted and attached to the resulting vendor bill. Steps to reproduce: - Set up a BE Company - Configure an incoming mail server - Set up an email alias for the Vendor Bill journal - Receive a Peppol XML with embedded PDF via alias - Check the created Bill Issue: PDF has not been extracted from the xml This occurs because the received xml is set as main attachment for the record and in this case we skip extraction opw-6075250 Forward-Port-Of: odoo/odoo#278806 Forward-Port-Of: odoo/odoo#262047
When `cash_rounding` is enabled on a POS config but `rounding_method` is not set,`get_tax_totals_summary` is called with undefined (instead of null). Fix: ensure the `rounding_method` is set when `cash_rounding` is enabled, otherwise pass null to `get_tax_totals_summary`. task-id: 6388234 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278144 Forward-Port-Of: odoo/odoo#276914
Original PR description
When `cash_rounding` is enabled on a POS config but `rounding_method` is not set,`get_tax_totals_summary` is called with undefined (instead of null). Fix: ensure the `rounding_method` is set when `cash_rounding` is enabled, otherwise pass null to `get_tax_totals_summary`. task-id: 6388234 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278144 Forward-Port-Of: odoo/odoo#276914
In the current state, running `test_qris_link_with_pos_order` results in an access error. This is because the user is missing the PoS group user access group. This PR changes the test class inheritance from `AccountTestInvoicingHttpCommon` to `TestPointOfSaleHttpCommon`. This provides the necessary PoS setup. I also had to change mentions of `pos_user`, as the qris test class created its own `pos_user` distinct from its ancestor's. Error page: https://runbot.odoo.com/odoo/error/938918
Original PR description
In the current state, running `test_qris_link_with_pos_order` results in an access error. This is because the user is missing the PoS group user access group. This PR changes the test class inheritance from `AccountTestInvoicingHttpCommon` to `TestPointOfSaleHttpCommon`. This provides the necessary PoS setup. I also had to change mentions of `pos_user`, as the qris test class created its own `pos_user` distinct from its ancestor's. Error page: https://runbot.odoo.com/odoo/error/938918
Following odoo/odoo#230736, the function now includes in its count the leaves that have no calendar, regardless of the company. This commit fixes this by grouping them by company as well, and including that count. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276472
Original PR description
Following odoo/odoo#230736, the function now includes in its count the leaves that have no calendar, regardless of the company. This commit fixes this by grouping them by company as well, and including that count. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276472
A POS session could not be closed if there were draft orders planned for later the same day. The backend check was only filtering out orders with a date strictly in the future, ignoring the time part for same-day orders. task-id: 6000698 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269093 Forward-Port-Of: odoo/odoo#251935
Original PR description
A POS session could not be closed if there were draft orders planned for later the same day. The backend check was only filtering out orders with a date strictly in the future, ignoring the time part for same-day orders. task-id: 6000698 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269093 Forward-Port-Of: odoo/odoo#251935