Tuesday, January 30, 2024
21 changes · 17.0
Resolved issues and error corrections
The Employee app now shows a more appropriate title when adding resume experience entries, instead of incorrectly displaying "Select Skills." This reduces confusion for HR users managing employee resume information.
Original PR description
**Current behavior:** Using the resume_one2many widget renders a view whose title is the same as the skills_one2many widget. --- **Expected behavior:** The resume_one2many widget will render a view with a more relevant title. --- **Steps to reproduce:** 1. In the Employee application, select or create and employee 2. In the 'Resume' notebook tab, add a new entry in their 'Experience' section 3. The view rendered here is titled "Select Skills" --- **Cause of the issue:** The resumeX2ManyField class extends skillsX2ManyField, inheriting its title. --- **Fix:** Setup resumeX2ManyField independent of skillsX2ManyField and give it a unique title. --- opw-3687865
This fixes an issue in Field Service Sales where manually invoiced service quantities could not be decreased from the product catalog. Users can now correct service quantities more easily, helping keep orders and invoices accurate.
Original PR description
Task-3689939
Fixed a payslip display issue where a sample amount could appear even when real payroll values were present. This prevents confusing or misleading information from showing on employee payslip reports.
Original PR description
100$ should be a placeholder, but is outside of the span, so it is always displayed instead of only when there is no values.
This fix resolves an issue where refunding a POS order containing products with zero price would cause an error in the Mexican electronic invoice (CFDI). The system now properly filters out zero-price line items when processing global invoices and refunds, ensuring compliance with Mexican tax requirements.
Original PR description
Current behavior: When you do a global invoice with line that have a price unit of 0, then refund the order you get an error on the CFDI. Steps to reproduce: - Install l10n_mx_edi_pos - Create a product with a price unit of 0 - Create a POS order with this product and another one - Validate the order - Go in backend and create a global invoice form the orders view - Refund the order - Go on the order and check the CFDI, it will be in error opw-3630583
Fixed an issue where filtering deferred revenue reports by analytic account was not working properly. The fix updates the report generation to use a consistent query method, making the reports more reliable and easier to maintain when users need to filter financial data by specific analytic accounts.
Original PR description
Steps to reproduce: [account_accountant, sale_subscription] - create two quotations/subscriptions (sales) yearly: one with an analytic account, one without - confirm - create invoice - confirm - Go on Deferred Revenue - Filter Analytic with the one used in your quotation Issue: The analytic filter does not work Solution: We want to make sure to use `_query_get` to be consistent with other report generation and to make the retrieval of lines more easily maintainable opw-3603096 Forward-Port-Of: odoo/enterprise#52622
This fix resolves an issue where the Industry FSM tour would fail inconsistently when switching between the web client and portal, particularly when certain modules were installed. The problem was caused by asynchronous module loading that could delay tour patches. By removing unnecessary imports and re-enabling previously disabled tests, the tour now works reliably with or without demo data installed.
Original PR description
*: industry_fsm, industry_fsm_report Previously, the industry_fsm_tour would sometimes fail, it would appear that after transitioning between the webclient and the portal, the tour step would be…
*: industry_fsm, industry_fsm_report Previously, the industry_fsm_tour would sometimes fail, it would appear that after transitioning between the webclient and the portal, the tour step would be incorrect when industry_fsm_sale or industry_fsm_report was installed. This is because the modules that define and patch the tour are implicitly asychronous because they import web.legacy_translations_loaded (directly or indirectly). This can cause the module loader to apply these patches after the tour_service has been started, and cause the tour to be started without the patches in some circumstances, causing the current step to be inconsistent between the frontend and backend. This commit fixes that by removing the import of web.legacy_translations_loaded, which makes the modules synchronous and guarantees that the patches are applied before the tour service starts. This import is no longer necessary since the tour steps is now a function that's only invoked by the tour service after the translations are known to be loaded. Forward-Port-Of: odoo/enterprise#55319
This fix resolves an issue where the "Invoices to validate" link in the accounting dashboard was broken when the enterprise 3-way matching module was installed. The problem occurred because invoices and bills were sharing the same link, and the 3-way matching module was modifying it for bills only, which inadvertently broke the invoices link. The solution creates separate, dedicated links for invoices and bills so each can function independently.
Original PR description
Currently the "Invoices to validate" link is broken in case the module account_3way_match (from enterprise) is installed. The same link / context is used for "Invoices to validate" and "Bills to validate". (The text inside the link is just changed depending on the journal type.) The module account_3way_match changes the context of that link to change the behaviour for the "Bills to validate" (bill specific filter). This breaks the link for "Invoices to validate". This commit makes invoices and bills have dedicated / separate links. Thus after this commit account_3way_match only changes the behaviour of the "Bills to validate" link. task-3680398
This fix ensures that when interface elements are updated in the base language during a system upgrade, the corresponding display rules (like visibility conditions) are properly synchronized across all language translations. Previously, translated versions would retain outdated rules, causing interface elements to display incorrectly or behave unexpectedly after upgrades.
Original PR description
When we update an inline translated element (like `<span>`) for the base language `en_US` we should update the modifiers attributes for all languages. For example when updating from (16.0)…
When we update an inline translated element (like `<span>`) for the base
language `en_US` we should update the modifiers attributes for all
languages.
For example when updating from (16.0)
https://github.com/odoo/odoo/blob/7ecd9413/odoo/addons/base/views/ir_ui_view_views.xml#L127-L129
https://github.com/odoo/odoo/blob/7ecd9413/odoo/addons/base/i18n/fr.po#L7233-L7235
to (17.0)
https://github.com/odoo/odoo/blob/b1461d28/odoo/addons/base/views/ir_ui_view_views.xml#L126-L128
https://github.com/odoo/odoo/blob/b1461d28/odoo/addons/base/i18n/fr.po#L12087-L12089
The base term, `en_US`, is updated since the text matches but the
attributes of the translated terms, `fr_FR` for example, are not
updated. Later when the PO file is loaded in non-overwrite mode the
translated terms for `fr_FR` is not updated. This causes all sort of
issues during an upgrade for inline-translated terms -- like `<span>`.
More so since the recent change that converts domain-based attributes
into inline Python expressions.
In this patch we propagate modifiers attributes from inline-translated
items in the new base term into all translated terms when the base term
is updated. In that way we ensure the attributes are correct in all
languages even if later the loading of their corresponding PO file
doesn't update the term.
For a detailed example, let's see what happens when loading the view
above during an upgrade 16->17, right at the first load of the XML file
at https://github.com/odoo/odoo/blob/b1461d28/odoo/fields.py#L1864
```
(Pdb) p old_term
'<span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'soft\')]}">This view has no previous version.</span>\n <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'hard\')]}">This view is not coming from a file.</span>\n <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'other_view\')]}">You need two views to compare.</span>'
(Pdb) p closest_term
'<span invisible="reset_mode != \'soft\'">This view has no previous version.</span>\n <span invisible="reset_mode != \'hard\'">This view is not coming from a file.</span>\n <span invisible="reset_mode != \'other_view\'">You need two views to compare.</span>'
(Pdb) p translation_dictionary[old_term]
defaultdict(<class 'dict'>, {'fr_FR': '<span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'soft\')]}">Cette vue n\'a pas de version antérieure.</span>\n <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'hard\')]}">Cette vue ne provient pas d\'un fichier.</span>\n <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'other_view\')]}">Vous avez besoin de deux vues pour comparer.</span>'})
```
As we can see the new term will get an updated value for its `invisible`
attribute, while also removing `attrs`. The translated terms will be
still keep the old modifier though.
Now later when the fr_FR.po file is loaded we reach this point
https://github.com/odoo/odoo/blob/b1461d28/odoo/tools/translate.py#L1442
```
(Pdb) p term_en
'<span invisible="reset_mode != \'soft\'">This view has no previous version.</span>\n <span invisible="reset_mode != \'hard\'">This view is not coming from a file.</span>\n <span invisible="reset_mode != \'other_view\'">You need two views to compare.</span>'
(Pdb) p translation_dictionary[term_en]
defaultdict(<function DeepDefaultDict at 0x7fc9640cdfc0>, {'fr_FR': '<span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'soft\')]}">Cette vue n\'a pas de version antérieure.</span>\n <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'hard\')]}">Cette vue ne provient pas d\'un fichier.</span>\n <span attrs="{\'invisible\': [(\'reset_mode\', \'!=\', \'other_view\')]}">Vous avez besoin de deux vues pour comparer.</span>'})
```
Thus the translated values are NOT updated, keeping the _wrong_
modifiers. This is later fixed during the upgrade in a clumsy way.
C.f. the warnings like this one in runbot:
```
Incomplete conversion for view(id=77, lang=fr_FR) at
<span attrs="{'invisible': [('reset_mode', '!=', 'soft')]}">Cette vue n'a pas de version ant&https://github.com/odoo-dev/odoo/pull/233;rieure.</span>
```
Note that such warnings are gone in current PR CI.
The root issue here is that when the fr_FR translation is loaded the
terms are not updated due to a combination of factors:
1. The text content of the term didn't change
2. There is no override flag set for translations
Option 2 is not a valid option during upgrades because we want to keep
custom translations. We could instead of the current patch tweak how
option 1 works and perhaps make the closest term more restricted. This
would lead to the update of the whole translation though while the
actual issue here is _just_ the modifiers. Moreover if the translations
are out of sync the translated terms will still keep the wrong values
that could still be essential for the correct functioning of the record
they belong too (view archs -- for example).
Finally this is a more extreme case (16.0):
https://github.com/odoo/enterprise/blob/1e63b4a8/sale_subscription/views/sale_order_views.xml#L142
In this case during the upgrade we fix the modifier value (refer to
runbot warning above -- it's the same script that fixes it) and set
```
invisible="(subscription_management == 'upsell') or (recurrence_id == False)"
```
for translations, which is wrong. The correct value is (17.0):
```
invisible="not plan_id or subscription_state == '7_upsell'"
```
https://github.com/odoo/enterprise/blob/530ba3ad/sale_subscription/views/sale_order_views.xml#L136The HR attendance kiosk was displaying a default logo instead of the correct company logo when multiple companies existed in the system. This fix updates the logo retrieval method to properly access and display the correct company's logo for any company, not just the default one.
Original PR description
**Current behavior:** Creating an additional company then creating an attendance kiosk link for it will not display this company's logo. --- **Expected behavior:** The kiosk page displays the logo…
**Current behavior:** Creating an additional company then creating an attendance kiosk link for it will not display this company's logo. --- **Expected behavior:** The kiosk page displays the logo for whichever company is actively selected when the link is generated --- **Steps to reproduce:** 1. Create a second company, set the logo to anything besides the default/fallback image 2. In the HR Attendance application settings, generate a kiosk link then paste & go in an incognito window 3. Observe the logo image displayed above the bar code is the default/fallback image --- **Cause of the issue:** The route being used to get the company's logo does not work for companies which are not the first/default one generated with the database. An accessibility check fails due to some information about the user's access rights not being available with the request. --- **Fix:** Use an alternative route which can properly access the logo image file of the company that is active when the kiosk link is generated. --- opw-3672577
This fix ensures that orders created while offline are properly synchronized to the server when closing a Point of Sale session. Previously, orders would only sync when using the back button, but not when closing the session, causing data loss. The sync mechanism is now shared between both actions.
Original PR description
**Step to reproduce**: - Open a pos session - Turn off the connection between the server and your POS instance - Create an order offline - Turn back on the connection between the server and your POS instance - Close the POS session **Issue**: The order created offline is not synced to the server **Cause**: The sync of the order has been implemented for the button to go back to the backend without closing but not for the closing session button. **Solution**: Make the synch mechanism common to both buttons. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#143308 Forward-Port-Of: odoo/odoo#137648
Employees were unable to open the time off type dropdown when creating time off requests due to insufficient access permissions to accrual plans. This fix ensures employees can properly access the necessary data when managing their time off, resolving errors that prevented them from completing time off requests.
Original PR description
to reproduce ============ As admin: - in my Belgian company: create an accrual plan (use default values) - create an allocation for laurie poiret, use the created accrual + add 2 days of allocation - as lauriepoiret go to time off - create a time off for today or in the past - try to open time off type drop-down -> error Problem ======= The problem is that the accrual plan is not readable by the employee, but used in compute method. Solution ======== use sudo to read the accrual plan opw-3687866 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes two issues in the Time Off management system. First, it corrects the employee dashboard display to accurately show remaining leave days by only counting valid allocations, not expired ones. Second, it adds a warning system to identify and track problematic leave records that may have been created due to bugs or data inconsistencies, helping administrators maintain data integrity.
Original PR description
Fix 1: Before this commit, the smart button on the employee would display `x/y` Time Off, indicating remaining leaves over max leaves. However, while `y` was correctly taking into account current allocations only, `x` didn't, resulting in incoherent values. Reproduce the issue: - For an employee, create an expired allocation and validate it of x days; - Create an additional allocation which is still valid today of y days and validate it as well; - Go on the employee form view; - Time Off smart button display (x+y)/y instead of y/y Fix 2: Before this commit, there was no way to track error inducing leaves that were created through a bug or that were already created in the database prior to the changes brought in version 17.0. This commit adds a new property in the leave data indicating the id and the start date of the leave that is causing the discrepancies in the database and displays a warning on the dashboard if there are some error inducing leaves.
Fixed an issue where the website page manager would always show the first website instead of remembering which website you were viewing. Now when you switch websites in the preview and then go to manage pages, it correctly shows the website you selected. This also fixes cases where reloading the page or accessing the page manager directly would lose your website selection.
Original PR description
Before this commit: The website selected in the website selector of the search view in the website.page list/kanban view was always set to the first one found in the DB and was never: 1. the one you…
Before this commit: The website selected in the website selector of the search view in the website.page list/kanban view was always set to the first one found in the DB and was never: 1. the one you visited in the website preview 2. or the one matching the URL of your backend. But 1. was working fine before commit [1] from the frameworkjs which introduced a way to "reset" the screen between apps/menu switch. Despite 1. working before commit [1], it was not ideally coded and worked "by chance", see below for a few facts and explication. ------------------ Fact 1: When you have multiple websites and you are on a website, the website served is result of 2 possibilities: 1. All websites have a specific domain, then you can only see a given website on its own domain. Attempting to select another website in the website switcher will redirect you to that other website domain. 2. You have one or more websites without any domain, then you can see those ones from any domain by using the website switcher. It will force the website in session, and despite being on a domain which should serve a given website (the one which has its domain set that domain if there is one), it will serve you the one you selected in the website switcher. Fact 2: - It is the `website_preview` which is setting the currentWebsite property of the `website_service`. - But the `website_service` can be used on its own, without any `website_preview` being involved in the process. - When the website preview is unmounted, the currentWebsite from the website service is reset to null. - The website page list component is reading the currentWebsite from the website service. - When switching from the website preview to another menu like the website pages list, the page list component (PageControllerMixin) is actually initialized/created before the website preview is unmounted. In the end, the follow happen: 1. Go to website preview -> it sets the website service current website 2. Go to website page list 3. The website page list component reads the current website from the website service which is set 4. The website preview is unmounted, emptying the current website from the website service 5. The website page list is shown to the user 6. Any call from the page list component to the current website will now be "wrong" / not return the same as during its `onWillStart`, as website preview was unmounted just after that, emptying the website set in the website service. Fact 3: Commit [1] changed the order listed above, now 4 occurs before 3, so when the page list component reads the website from the website service, the unmount of the website preview already kicked in, emptying that website service website. ----------------- This commit is simply finding the current website_id by asking it to the server. It will fix point 1. listed at the very beginning of the commit message, but will also make point 2. work. ---------------- Steps to reproduce 1: - Without any domain set, go to your DB in the website preview of your website in the backend - Switch to the website 2 in the navbar website switcher - You are now viewing website 2 in the website preview - Click on "Pages" in the "Site" menu to go to the page list view - The website selected in the search view is the first one, not the website 2. Also, the page shown are from the website 1, not the website 2. - This was working before commit [1] and this commit is fixing that. But this commit is also fixing/improving flows which never worked: - Before commit [1] (or in Odoo 16 to be simpler), do the same 4 first steps as above. - You will see that the listed pages are the ones from website 2 and that the selected website is the second one, correct. - Now just reload the page, it will show website 1, despite the website 2 being forced (if you did reload the page on the preview, it would still show website 2). - This is because the website_preview was never involved after the reload since you reached the list view / website service without going through the website preview. - The same can be seen if you go to the Pages list view directly through CTRL+K, in which case you won't go through the preview. [1]: https://github.com/odoo/odoo/commit/9f6ed9f6d1ef7ec1870980498480cae0ffc729d8 Related to task-3676124 opw-3658648 Forward-Port-Of: odoo/odoo#151253 Forward-Port-Of: odoo/odoo#149070
This fix resolves an issue where the "see records" feature in spreadsheets would fail when optional formula parameters were left empty. The system now properly uses default values for these parameters, allowing users to successfully drill down to view the specific accounting transactions that match their spreadsheet formulas.
Original PR description
The `see records` action that drill downs to the specific AccountMoveLines that match the formula domain would break if we left some optional formula arguments empty (specifically concerns the offset and companyId arguments). This revision ensures that we use their default value when the arguments are not provided. Task: 3621110 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#151315 Forward-Port-Of: odoo/odoo#148284
This update fixes a bug in the website editor where widgets were being destroyed at the wrong time, causing editing features to malfunction. Specifically, when re-entering edit mode on pages with countdown snippets, the editor's editable regions were losing their proper configuration. The fix ensures widgets are cleaned up before the editor initializes, preventing conflicts between widget updates and editor setup.
Original PR description
[FIX] website: destroy widgets before instantiating the wysiwyg Steps to reproduce the problem: - Add a "Countdown" snippet on the website. - Save. - Enter in edit mode again. -> Problem: the…
[FIX] website: destroy widgets before instantiating the wysiwyg Steps to reproduce the problem: - Add a "Countdown" snippet on the website. - Save. - Enter in edit mode again. -> Problem: the `destroy()` of the `CountdownWidget` public widget comes from a `widgets_start_request` that is triggered when the `WysiwygAdapterComponent` has been mounted and patched (see [useEffect documentation]). The problem is that, as the widgets are only destroyed at this moment, it is possible that a widget could replace an element that has been modified during the instantiation of the `WysiwygAdapterComponent`. For example: - At the `onWillStart()` hook of the `WysiwygAdapterComponent`, the `o_editable` is added on some elements. - A widget could then replace one of these elements. - The widget is destroyed after the rendering of the `WysiwygAdapterComponent`. -> The `o_editable` class is not on the element anymore. The goal of this commit is to, as before [1], destroy the existing widgets before instantiating the `wysiwyg`. This commit also adds a test to ensure that the order of the calls to the widgets and wysiwyg lifecycle methods is coherent. Related to runbot-28700 [1]: https://github.com/odoo/odoo/commit/a3e34512bf229d5d55f9e9d9eb0a9f7211a5a826 [useEffect documentation]: https://github.com/odoo/owl/blob/master/doc/reference/hooks.md#useeffect Forward-Port-Of: odoo/odoo#151237 Forward-Port-Of: odoo/odoo#149385
This fix resolves an issue in the Indian EDI (Electronic Data Interchange) system that was preventing invoices from being cancelled when the EDI had already been cancelled. Previously, the system would display an error and block the cancellation. Now, invoices can be successfully cancelled in this scenario, improving the flexibility of invoice management for Indian operations.
Original PR description
Before this commit ================== It was not allowed to cancel the invoice, an error message was displayed, response as False was returned as it was always moving inside else condition After this commit ================= After changes the error message has been removed and response as True is returned, and allowed to cancel the invoice task-3258582 Forward-Port-Of: odoo/odoo#151517 Forward-Port-Of: odoo/odoo#117592
This update fixes an issue in the web editor where pressing Tab to navigate between table cells would incorrectly display a toolbar and select all text in the next cell. After this fix, the toolbar no longer appears when tabbing through table cells, and the cursor properly positions at the end of each cell for a better editing experience.
Original PR description
Current behavior before PR: - On table when we hit tab it displays toolbar as it sets selection between startPosition and endPosition. - On hitting tab it selects the text in the next cell completely, which should not happen. Desired behavior after PR is merged: - Now toolbar is not displayed on hitting tab. - selection is made to collapse at the end the lastNode of the cell. task-3475079 Forward-Port-Of: odoo/odoo#132807
This update brings the spreadsheet application to the latest version with multiple bug fixes that improve stability and user experience. The fixes address issues with sheet renaming, formula evaluation, text editing, and icon display, ensuring the spreadsheet tool works more reliably for users.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/3c1209a38 [REL] 17.0.9 https://github.com/odoo/o-spreadsheet/commit/fa95e4614 [FIX] BottomBarSheet: renaming a sheet…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/3c1209a38 [REL] 17.0.9 https://github.com/odoo/o-spreadsheet/commit/fa95e4614 [FIX] BottomBarSheet: renaming a sheet with styled content https://github.com/odoo/o-spreadsheet/commit/8df011627 [FIX] evaluation: behavior for invalid range arguments https://github.com/odoo/o-spreadsheet/commit/190fd0457 [FIX] SelectionInput: Allow commands that target non focused input Task: 3689504 https://github.com/odoo/o-spreadsheet/commit/aaaf7fea0 [FIX] Edition: filter invalid references from edition highlights Task: 3378775 https://github.com/odoo/o-spreadsheet/commit/cbc3b91a0 [FIX] Composer: double click on composer gives traceback https://github.com/odoo/o-spreadsheet/commit/6306302ae [FIX] demo: wrong App.mount arguments https://github.com/odoo/o-spreadsheet/commit/13a3fd3c6 [FIX] icon: broken path for HIDE_COL icon https://github.com/odoo/o-spreadsheet/commit/b2abf2362 [FIX] format: fix chaining of FORMAT.LARGE.NUMBER Task: 3633947 https://github.com/odoo/o-spreadsheet/commit/eb1492393 [IMP] github: add templates
This update removes an unnecessary variable that was being sent when the POS system communicates with IoT devices for password management. By eliminating this unused parameter, the system will no longer generate warning messages in the IoT logs, resulting in cleaner system operations and easier troubleshooting.
Original PR description
In iot, when we send a request to the route '/hw_posbox_homepage/password' we pass a variable which is unused. And which therefore causes a warning in the iot logs. This commit removes the query parameter. 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#151505
This fix prevents the creation of massive unnecessary log files when running tests that fail. The issue occurred because a background process was trying to write screencast files without first checking if the required directory existed, causing a race condition. The fix simply ensures the directory is checked before writing, eliminating the problematic logs.
Original PR description
Without this patch, running this command on an environment where the tour will fail, will create massive and useless logs:
odoo --stop-after-init -i auth_totp --test-enable --test-tags /auth_totp
[Excerpts of those massive useless logs](https://github.com/odoo/odoo/files/14065596/odoo.log.txt)
This is because this method is a callback that can come in a different thread, creating a race condition.
There's no problem on checking wether the directory exists before creating the file, and then safeguarding from the problem.
@moduon MT-1075
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#151364Fixed a bug where the "Logged in as" text was not displaying correctly on the public chat page. The issue was caused by a missing function call syntax that prevented the user information from being properly shown. Users will now see their login status correctly displayed when accessing the public chat interface.
Original PR description
`getLoggedInAsText` is a function, due to missing brackets the function content was dumped instead of evaluation of function. opw-3701333 Before  After  Forward-Port-Of: odoo/odoo#151523