Monday, September 28, 2026
5 changes · saas-18.3
New functionality added to Odoo
A new FedEx certified shipping module has been added to align Odoo's FedEx integration with FedEx certification guidelines. This helps ensure businesses can use the updated FedEx shipping flow in a compliant and officially certified way.
Original PR description
For the certification process of FedEx there were some changes needed in the delivery_fedex_rest module. This modules made those changes according to the FedEx guidelines. Task-id: 6164275 Forward-Port-Of: odoo/enterprise#122663
Resolved issues and error corrections
Starshipit shipping quotes now handle incomplete wallet checkout addresses without stopping all delivery options from loading. Customers using Apple Pay or Google Pay can continue checkout with other available carriers when Starshipit cannot quote from the partial address.
Original PR description
#### Description of the issue/feature this PR addresses: Rating a Starshipit shipment for an incomplete delivery address makes the whole rating loop fail instead of skipping that carrier. This breaks…
#### Description of the issue/feature this PR addresses:
Rating a Starshipit shipment for an incomplete delivery address makes the whole rating loop fail instead of skipping that carrier. This breaks express checkout (Apple Pay / Google Pay), where the wallet only discloses a partial address before authorization: the customer gets "update postal address" and cannot pay, while manual checkout works.
#### Current behavior before PR:
delivery_starshipit is the only connector that rates a shipment without validating the addresses first, and it ignores the express_checkout_partial_delivery_address context key set by website_sale. The empty street is sent to /api/rates, which answers 200 with {"success": false, "errors": [{"details": "street parameter value is required"}]}, and _send_request turns that into a UserError. As starshipit_rate_shipment lets it propagate, it aborts the rating of every carrier instead of only this one, so no delivery method reaches the wallet. The same happens for errors only the api can report, such as invalid credentials.
#### Desired behavior after PR is merged:
Both the recipient and the warehouse address are validated before the api is called, as the other connectors already do, and the message is returned as an unsuccessful rate rather than raised. Starshipit requires the street, so a streetless address is still refused, but with a neutral message in the express checkout flow since the customer cannot complete it before paying. The Starshipit carrier is simply not proposed among the wallet's options, the other carriers are rated normally, and express checkout completes.
opw-6393393
Forward-Port-Of: odoo/enterprise#129640
Forward-Port-Of: odoo/enterprise#125117Malaysian payroll calculations now correctly handle SOCSO and Employment Insurance deductions, avoiding duplicated employee contributions. This ensures employee net pay and employer contribution lines match official contribution rates more accurately.
Original PR description
There was a difference between the actual and expected NET. **Causes** - rules existed for both SOCSO Act 800 and EIS, but Act 800 seems to be the official name of the Employment Insurance System…
There was a difference between the actual and expected NET. **Causes** - rules existed for both SOCSO Act 800 and EIS, but Act 800 seems to be the official name of the Employment Insurance System (source: https://www.perkeso.gov.my/images/dokumen/Rate_of_Contribution_ACT_800.pdf). Keep the ACT 800 one as its matches the expected amount. - there was a double counting of the SOCSO employee contributions (4 and 800) , as `l10n_my_rule_socso_employee` (the sum of both) was added to the total deductions. **Change** Before: 3500/month wage results in a 3108 NET. <img width="1181" height="533" alt="before" src="https://github.com/user-attachments/assets/cdf4420f-e2cf-4dc7-9488-6bde3f1f9961" /> After: 3500/month wage results in a 3090.85 NET: - 6.90 SOCSO Act 800 Employee - 6.90 SOCSO Act 800 Employer - 17.25 SOCSO Act 4 Employee - 60.35 SOCSO Act 4 Employer Which seems consistent with online sources (https://payroll.my/) <img width="1181" height="425" alt="after" src="https://github.com/user-attachments/assets/7fb41186-dbb4-4d7a-ac9a-14fb56efc4bc" /> Other fix: while not affecting the calculation, 'SOCSO Employer Share' appeared as incorrect, the two rules SOCSO_800_EMPLR and SOCSO_4_EMPLR should have the same sign. opw-5976362 Forward-Port-Of: odoo/enterprise#118138
Swiss payroll employee forms now hide non-Swiss certificate options so users see only the choices that apply to Switzerland. This reduces confusion and helps teams select the correct certificate information for Swiss payroll processes.
Original PR description
The certificate field on the employee model was being extended by the swiss localization to add the swiss-specific certificates. This was done using selection_add on the field which was causing the selection to also show the original values defined on the base employee model. We don't want to see the original values but only the swiss ones when we operate in the swiss localization. At the same time, we can't just override the field (without using selection_add) because a warning is triggered. Other possible solustions like using the result of a function or changing the type of the field to Many2one to use a domain are either not working on a record-per-record basis or not stable compliant. The only working solution for stable is to keep the selection_add working and filter the results in the views using the filterable_selection widget. Task: 5948460 Forward-Port-Of: odoo/enterprise#107821
Swiss payroll employee forms now show only Switzerland-specific certificate options instead of mixing in unrelated default certificate values. This reduces confusion and helps users select the correct certificate when working with Swiss localization.
Original PR description
The certificate field on the employee model was being extended by the swiss localization to add the swiss-specific certificates. This was done using selection_add on the field which was causing the selection to also show the original values defined on the base employee model. We don't want to see the original values but only the swiss ones when we operate in the swiss localization. At the same time, we can't just override the field (without using selection_add) because a warning is triggered. Other possible solustions like using the result of a function or changing the type of the field to Many2one to use a domain are either not working on a record-per-record basis or not stable compliant. The only working solution for stable is to keep the selection_add working and filter the results in the views using the filterable_selection widget. Task: 5948460 Forward-Port-Of: odoo/odoo#250046