Branch
[FIX] viin_brand_web: brand the default title of action dialogs A dialog opened by an action without a name, such as "+ New Shop" in Point of Sale Settings, read "Odoo" in a Viindoo backend. The action dialog takes its default title from its own defaultProps, and core copies Dialog.defaultProps when it defines that component. The copy happens before this brand file runs, so the brand never reached it. A shop manager must never see the Odoo name in a dialog title. The brand now covers the action dialog default title too, and a hoot test guards it.
[FIX] web_responsive: pin the apps menu below the navbar's real bottom edge The full-screen apps menu is a position: fixed overlay with a constant top of $o-navbar-height and a height capped at 100vh minus that value. Both assume the navbar is the topmost element of the page. On a neutralized database core's web.neutralize_banner template renders a 24px banner above the navbar, so the menu covered the lower half of the navbar (it looked cut in two) and its last 24px fell below the viewport. Measure the navbar's own bottom edge at render time and set top inline (re-rendered on resize; 0 when no navbar is mounted), and let the box stretch to bottom: 0 instead of a computed height, so anything placed above the navbar is handled the same way.
[FIX] web_responsive: make the mobile apps menu one-handed - On phones the navbar shows a visible, labelled apps grid icon (it was an invisible tap area). - The apps sidebar slides in from the left, next to the icon that opens it, and swipe-left closes it. - "All Apps" in the sidebar opens the full-screen app menu with its search box, like on desktop. - Tapping the icon while the app menu covers a screen closes it; when the app menu is the only screen (redirect-to-home users) it opens the sidebar instead. - The redundant sidebar button in the user menu is removed. - The app title now shortens before the user menu is pushed off narrow (360px) screens. - Vietnamese translation added; template refreshed. Signed-off-by: David Tran <david.tran@tvtmarine.com>
[FIX] viin_brand_mrp: remove Odoo wording from Manufacturing help texts Manufacturing shows Odoo in the help of the automatic printing options of the manufacturing operation type, in the help of Operation Dependencies and of the manual consumption of components, and in a note that sends the user to the Odoo IoT App and Odoo's documentation. Say 'the system' in the help texts. Replace the note with a plain statement that a PDF preview opens by default: the Viindoo IoT box does not route these reports to a printer, so the advice does not apply. The work center control panel digest tip is already rewritten by this module. Bump the module version and update the .pot/.po. Signed-off-by: David Tran <david.tran@tvtmarine.com>
[FIX] viin_brand_pos: remove Odoo wording from POS user-facing messages The POS 'Connection to the printer failed' dialog told cashiers to follow Odoo's documentation. Replace it with the same advice in Viindoo words and no documentation link; this also covers the Epson ePOS path, which reuses the base printer message. Same kind of user-facing Odoo mentions covered in this module: - the generic 'Odoo Server Error' dialog title is now 'Server Error'; - the customer display 'Powered by' badge shows the Viindoo logo instead of the Odoo one; - the IoT customer display failure notice no longer talks about an Odoo database subscription. It is swapped on the notification the core service raises, and the module's terms are now sent to that public page so the Vietnamese wording is applied there. Bump the module version and update the .pot/.po. Signed-off-by: David Tran <david.tran@tvtmarine.com>
[FIX] viin_brand_pos: remove Odoo wording from POS user-facing messages The POS 'Connection to the printer failed' dialog told cashiers to follow Odoo's documentation. Replace it with the same advice in Viindoo words and no documentation link; this also covers the Epson ePOS path, which reuses the base printer message. Same kind of user-facing Odoo mentions covered in this module: - the generic 'Odoo Server Error' dialog title is now 'Server Error'; - the customer display 'Powered by' badge shows the Viindoo logo instead of the Odoo one; - the IoT customer display failure notice no longer talks about an Odoo database subscription. It is swapped on the notification the core service raises, and the module's terms are now sent to that public page so the Vietnamese wording is applied there. Bump the module version and update the .pot/.po. Signed-off-by: David Tran <david.tran@tvtmarine.com>
[FIX] viin_brand_pos: remove Odoo wording from printer error dialog The POS 'Connection to the printer failed' dialog told cashiers to follow Odoo's documentation. Replace it with the same advice in Viindoo words and no documentation link; this also covers the Epson ePOS path, which reuses the base printer message. Same kind of user-facing Odoo mentions covered in this module: - the generic 'Odoo Server Error' dialog title is now 'Server Error'; - the customer display 'Powered by' badge shows the Viindoo logo instead of the Odoo one. Bump the module version and update the .pot/.po. Signed-off-by: David Tran <david.tran@tvtmarine.com>
[I18N] *: align Vietnamese terminology with the corrected core catalogs Odoo 18 core's Vietnamese catalogs were corrected against a glossary researched per business domain (Viindoo/odoo#1299). This brings this repository's catalogs in line, so a Vietnamese user sees one term for one concept across core and Viindoo modules: - Records shared with core (model names, re-declared fields, selection values) now carry core's corrected wording exactly; before, the module loaded last decided which label users saw. - Records shared between Viindoo modules read the same in every module that declares them, following the module that defines them. - Key terms applied in context, e.g. Đơn bán / Đơn mua, Phiếu kho, Loại nghiệp vụ, Hoàn thành, Duyệt / Đã duyệt / Chờ duyệt, Thiết lập, Nháp, Ghi sổ, Phát sinh kế toán, Tài khoản quản trị, Chế độ thuế, Hóa đơn điều chỉnh giảm, Trung tâm sản xuất, Lệnh công đoạn, Làm thêm giờ, Bảng giờ công, Đối chiếu, Danh sách chặn, Công cụ (wizards), plus the creator/updater boilerplate. - Definite errors fixed: reversed or wrong meanings, broken placeholders and markup, garbled text and typos. - Old-style tone marks throughout (hóa, hủy, khóa). Only msgstr content changes; untranslated entries are left as they are.
[FIX] viin_brand_crm: depend on viin_brand_digest to fix install-order crash Installing modules in some environments could abort partway through with: ParseError: .../viin_brand_crm/data/digest_data.xml:5 ValueError: Invalid field 'active' on model 'digest.tip' digest_data.xml writes digest.tip.active, but that field is defined by the sibling module viin_brand_digest, not by viin_brand_crm or by crm. Both modules are auto_install: True with no dependency edge between them, so Odoo's loader has no ordering guarantee and can process viin_brand_crm before viin_brand_digest has added the field - observed on a real build aborting at module 72 of 126. Add viin_brand_digest to viin_brand_crm's depends so the loader is forced to install it first. This does not widen who gets auto-installed: core crm already depends on digest, so whenever crm is installed, digest is installed too, which means viin_brand_digest (depends ['digest'], auto_install) was already an install candidate in exactly the same situations. The new edge only constrains order, which is precisely what was missing. digest_data.xml itself is untouched - the data is correct; it was only running too early.
[IMP] viin_brand: own the module-icon and favicon branding mechanism Moved from to_base (tvtmaaddons), where it ran for every database served by a process that had viin_brand on its addons path and forced to_base to be loaded server wide. The functions, hooks, models (company favicon, settings-page icon RPC, menu web_icon rewrite, session marker), data, views, assets and the QUnit mock server come over unchanged apart from their imports; the uninstall hook now actually restores the core functions it replaced. viin_brand is the module to load server wide from now on (--load=base,web,viin_brand); it warns when it is not.
[FIX] web_responsive: dismiss the apps menu when a search result is chosen Searching the apps menu and choosing a result appeared to do nothing: the menus filtered, but clicking one or pressing Enter left the user where they were. Navigation was in fact succeeding. The controller changed and the URL moved to the target, with no JS error and every RPC returning 200 - but the full-screen overlay stayed mounted over the destination and, being position:fixed with pointer-events:auto, swallowed clicks on the view underneath. The overlay must be dismissed explicitly. When the apps menu became an overlay-service render independent of the action stack, dismiss() was added before selectMenu() on the app-icon path but not on the search paths, and core's selectMenu() only mutates the action stack. Three call sites needed it, not one: the canonical search bar (whose handler the Enter key also reaches, so click and Enter are one path), the fuse variant that inherits it, and the command-palette variant, which fails through a different mechanism because openMainPalette was passed no onClose. The command-palette path dismisses only when a menu was actually selected. onClose fires on every palette close, Escape included, so dismissing unconditionally would tear the apps menu down when a user merely backs out of the palette - trading one surprise for another. It also registers that callback once per open palette session: core's command service ignores onClose on every call after the first while its palette is open, so re-passing it per keystroke orphaned a patch layer on the session-lifetime menu service each time. The app-tile route, which every core tour uses to reach an app, was already correct and is untouched. Signed-off-by: David Tran <david.tran@tvtmarine.com>
[FIX] viin_brand_common: withdraw the square-corners brand decision The product owner withdrew the "square corners are part of the Viindoo brand identity" decision. This module forced Bootstrap's global $border-radius to 0 in bootstrap_overridden.scss; drop that override so Odoo's own product-wide border-radius default applies again across buttons, inputs, cards, badges, dropdowns and modals. No sibling radius variable ($border-radius-sm/lg/xl/xxl) is touched - those are independent Bootstrap literals this module never overrode. viin_brand_square_corners_tour and its Python HttpCase driver (test_real_backend_buttons_keep_the_brand_square_corners) existed solely to guard the withdrawn contract, so both are retired together with it. Every other assertion in the same tour file and test class (brand primary colour, theme secondary colour, base font-size, statusbar outline/fill, discuss sidebar, settings tab) is untouched. Verified: before this change the retired assertion measured .btn border-top-left-radius = 0px (passing, as designed). After this change the full --test-tags /viin_brand_common suite is green (0 failed, 0 error, 0 skipped, 20/20), and a fresh computed-style probe measures .btn border-top-left-radius = 4px - Odoo core's own $o-border-radius default - confirming the product-wide change took effect. Bump manifest version 0.3.4 -> 0.3.5. Signed-off-by: David Tran <david.tran@tvtmarine.com>
[FIX] web_responsive: stop leaking a patch layer per command-palette keystroke A prior fix on this branch (05b40f6) made the command-palette search variant dismiss the apps-menu overlay only when a menu was actually selected, using a temporary patch() on the menu service to detect the selection. That patch was re-applied on every keystroke, but core's command service silently drops the onClose callback on every call after the first while its palette stays open - so only the first keystroke's patch layer was ever unwound, and each keystroke after that permanently leaked one more wrapper layer onto the menu service for the rest of the browser session. Track whether an open-palette session is already being watched and only patch the menu service + register the dismiss callback once per session; later keystrokes in the same session now only update the palette's search value. Adds a Hoot test covering the character-by-character search-typing path (the one the prior tests bypassed) and trims two test comments per the repo's comment convention. Signed-off-by: David Tran <david.tran@tvtmarine.com>
[FIX] web_responsive: correct a false idempotency comment + bind the session_info test Three review findings from the forward-port batch. The migration's comment claimed the is_redirect_home filter makes a re-run match nothing, so an opted-out user is never silently re-opted-in. The second half was false: an opted-out user holds False, which is exactly what the domain selects. Odoo compiles a boolean "= False" to (col IS NULL OR col = FALSE), so the domain provably cannot tell "never backfilled" from "deliberately opted out" - the manifest version gate is what makes this run once. The comment now says that. The domain and the logic are unchanged and correct: that same collapse is what lets the backfill match the NULL rows every pre-existing user actually has. test_session_info only ever exercised the preference at True, so a hardcoded True in the session_info transport would have passed it. It now also flips the preference to False and re-asserts, binding the assertion to the user's real stored value on both sides. The new JS test file carried an OCA sibling's copyright header; it is Viindoo's own 2026 file. The LGPL-3 license line stays - the module is OCA.
[IMP] viin_brand_website_sale: drop unverifiable "#1" claim from promo The eCommerce "Powered by" footer stated "The #1 Open Source eCommerce Software" (vi_VN: "... Mã nguồn mở số 1"), an unverifiable superiority ranking. Vietnam's advertising law forbids "#1"/"best" style claims without supporting evidence and penalises them heavily, so remove the ranking wording from both the template source and the Vietnamese translation. - views/templates.xml: drop the "#1" from the promo label and the standalone "The" text node so the label reads "Open Source eCommerce Software"; add a comment at the label noting the VN advertising-law constraint. - i18n/vi_VN.po and .pot: realign msgid to the new source string and drop the now-orphaned "The" term; msgstr "... Mã nguồn mở số 1" -> "... Mã nguồn mở". - bump module version 0.1 -> 0.2 so existing databases pick up the updated view and translation on upgrade.
[FIX] viin_brand_website_sale: remove "#1" claim from footer brand promotion The website footer showed "The #1 Open Source eCommerce Software" (vi: "Phần mềm Thương mại Điện tử mã nguồn mở số 1") to public visitors. Vietnamese advertising law prohibits superlative claims such as "số 1" without supporting evidence, so the claim is dropped in both English and Vietnamese. Version bumped so existing databases reload the template and translation on module update. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
[FIX] viin_brand_mail: label the notification choices like their help The In Viindoo choice was labelled "Handle in Viindoo" (vi "Xử lý trong hệ thống") while its help says "In Viindoo" (vi "Trong Viindoo"); the label now follows the core 19.0 label with Viindoo in place of Odoo. By Emails is re-declared so the module translates it, as core leaves it untranslated in Vietnamese.
[IMP] *: point the live demo links to the 19.0 demo The 19.0 modules still advertised the 18.0 demo server in live_test_url and live_test_url_vi_VN (one module advertised the 16.0 one). Point both keys of the 44 affected manifests to the v19demo servers, so the Try demo button of each module opens a database that runs 19.0.
[NEW] viin_brand_pos_self_order: hide the Pay after upsell Bridge between viin_brand_pos and pos_self_order, installed automatically with both. The Pay after selector of Point Of Sale self order only opens the Enterprise upsell and reverts to meal, so its row is hidden; the stored value is unchanged. Completes the upsell hiding that viin_brand takes over from to_hide_ent_modules. Version 0.1.
[FIX] viin_brand_pos: Viindoo wordmark in the default dialog title The Point of Sale default dialog title read "System" when "Odoo" was replaced. It now shows "Viindoo", the same wordmark as the rest of the de-branded dialogs. The customer display browser test now requires the default dialog title to be exactly the Viindoo wordmark.
[MERGE] *: forward-port 18.0 into 19.0 (16b8087..ad07bca) Absorbs the 18.0 range 16b80875171f..ad07bca6ba0c in one merge; every source SHA is kept. ccd7144 web_responsive: d+c - the module no longer exists in 19.0 and stays removed. Its fix is re-implemented in viin_backend_theme: the full-screen home menu opened from the navbar now starts at the navbar's real bottom edge (measured on render and on resize, 0 without a navbar), so a banner above the navbar - the red banner of a neutralized test/UAT database - no longer makes the menu cover the lower half of the navbar. A normal database looks the same as before. Guarded in the existing viin_home_menu_fixes Hoot tests. ad07bca viin_brand_web: a - 19.0 already brands the default title of action dialogs ("System"). The source test is kept as one case in the existing action_dialog_debrand Hoot tests (the real action path: an action without a name opened in a dialog), expecting "System". Also fixes a defect the merge itself produced: viin_brand_web's manifest got a second 'web.assets_unit_tests' key that silently dropped the module's nine existing Hoot test files from the bundle; it is one list again.
[FIX] viin_brand_web: a stock website keeps the AA teal; test the customized and stock palettes 293b3ad told a customized website by $o-color-palette-name != 'base-1'. By the time frontend_primary.scss compiles, website's secondary_variables.scss has renamed the active palette 'user-palette' on every website, the stock one included: every website counted as customized and a stock website's login and portal would have shown base-1's aubergine instead of the AA teal (the existing frontend primary test compiles exactly that bundle on a database with website). The selected palette is $o-original-color-palette-name. New test: on the first website, the stock palette compiles --primary to the AA teal; after the editor's own customization call (o-color-1 navy, CC1 secondary button white, no border) the same website compiles --primary to its navy and the secondary button border to its own white, not the brand purple (toaxe 14.0 -> 19.0).
[FIX] viin_backend_theme: keep apps menu open while app reloads Opening the apps menu from the navbar while an app was still reloading (for example clicking the app brand and then the apps button before the screen finished loading) closed the menu before its tiles appeared, so the user saw nothing to pick an app from. It broke the runbot hr_expense tour create_expense_no_employee_access_tour (step 13/13, .o_app tile not found, 4 failures out of 5 runs). Cause: NavBar.setup() closed the menu overlay on every ACTION_MANAGER:UI-UPDATED. The reload started by the brand click finished while the overlay's ViinHomeMenu was still in onWillStart (its mail.activity search_count and res.users read RPCs), so the overlay entry was removed before any tile was mounted. The UI-UPDATED listener is removed. The menu is still closed by a route change, outside click, Escape and when the navbar is destroyed; the mobile "All Apps" guard that refuses to open a menu before any screen exists is unchanged. Tests: a Hoot desktop test holds the list reload and the menu's own RPCs and requires the overlay and its app tiles to be on screen once both finish; it fails with the listener and passes without it. The mobile test that faked a screen to assert the removed close is dropped; the real guard stays covered by "All Apps tapped while the boot app menu is still loading opens no overlay and the toggle keeps working". Signed-off-by: David Tran <david.tran@tvtmarine.com>
[I18N] *: align Vietnamese terminology with the corrected core catalogs Odoo 19 core's Vietnamese catalogs were corrected against the glossary researched per business domain (Viindoo/odoo#1302). This brings this repository's catalogs in line, so a Vietnamese user sees one term for one concept across core and Viindoo modules. The 18.0 alignment came over with the forward-port; this covers the strings new in 19.0 and the terms decided for 19.0: - Records shared with core (model names, re-declared fields, selection values) now carry core's 19.0 wording exactly; before, the module loaded last decided which label users saw. - 19.0 terms: weekdays in word form (Thứ Hai ... Chủ Nhật). - The approved glossary applied in context to strings new in 19.0 (Phiếu kho, Loại nghiệp vụ, Cổng thanh toán, Đóng kiện, ...), and debranded help texts say "hệ thống" where the source does, not "Odoo". - Definite errors fixed: reversed or wrong meanings, broken placeholders and markup, English left in translations, garbled text and typos. - Old-style tone marks throughout (hóa, hủy, khóa), ASCII hyphens. Only msgstr content changes; untranslated entries are left as they are.
Merge remote-tracking branch 'origin/18.0' into 19.0 Range 4a5885d (1 commit). Conflict resolution: - i18n/vi_VN.po: kept the 19.0 catalog shape and entries; where 18.0 changed a msgstr and the same msgid exists on 19.0, the 18.0 wording wins. - viin_brand_common (renamed viin_brand_base_setup on 19.0): its 18.0 msgstr change applied to viin_brand_base_setup/i18n/vi_VN.po. - viin_brand_membership (removed on 19.0): catalog stays deleted.
[FIX] viin_brand_web: scope the navbar hover/active hook guard to the regular navbar test_navbar_menu_entry_interactive_states_use_deep_chrome_rung asserted that core never DECLARES --NavBar-entry-backgroundColor--hover/--active, because the var() fallback those hooks read is what carries the brand's deep chrome rung. It checked that with a substring scan over the whole compiled web.assets_backend, so any declaration anywhere tripped it. viin_customizer declares both hooks to theme its own dark top bar: `.customizer_container .customizer_navbar .o_main_navbar { ... }`. That rule never applies to the regular web client navbar, so the brand rung there is untouched, yet the scan reported it as core re-declaring the hook and the test went red as soon as viin_customizer was installed. The guard now collects only the declarations whose selector can reach the regular navbar entries - the entry itself or any ancestor on the NAVBAR_ANCESTORS chain, including class-less subjects such as :root. Custom properties inherit, so an ancestor-level declaration counts; a declaration under a context the navbar is not in does not. The check cannot be left to the cascade resolution further down: that walks only the entry, so a `.o_main_navbar` declaration inherited from above would stay invisible to it. Verified on 19.0 with viin_brand_web and viin_customizer installed: the old guard fails with "'--NavBar-entry-backgroundColor--hover:' unexpectedly found", the new one passes, and temporarily adding `.o_main_navbar { --NavBar-entry-backgroundColor--hover: #00bbce }` to the brand bundle still makes it fail. Also reword the docstring of viin_backend_theme's test_navbar_apps_icon_computes_cores_navbar_entry_colour. It said nothing in the addons path declares --NavBar-entry-color, which stops being true once viin_customizer is installed. It now says no rule that reaches the regular navbar declares it, and that viin_customizer's declaration lives only under its own .customizer_navbar scope, which the cascade resolver excludes. Docstring only; that test class still passes with viin_customizer installed. Signed-off-by: David Tran <david.tran@tvtmarine.com>
[FIX] viin_brand_web: scope the navbar hover/active hook guard to the regular navbar test_navbar_menu_entry_interactive_states_use_deep_chrome_rung asserted that core never DECLARES --NavBar-entry-backgroundColor--hover/--active, because the var() fallback those hooks read is what carries the brand's deep chrome rung. It checked that with a substring scan over the whole compiled web.assets_backend, so any declaration anywhere tripped it. viin_customizer declares both hooks to theme its own dark top bar: `.customizer_container .customizer_navbar .o_main_navbar { ... }`. That rule never applies to the regular web client navbar, so the brand rung there is untouched, yet the scan reported it as core re-declaring the hook and the test went red as soon as viin_customizer was installed. The guard now collects only the declarations whose selector can reach the regular navbar entries - the entry itself or any ancestor on the NAVBAR_ANCESTORS chain, including class-less subjects such as :root. Custom properties inherit, so an ancestor-level declaration counts; a declaration under a context the navbar is not in does not. The check cannot be left to the cascade resolution further down: that walks only the entry, so a `.o_main_navbar` declaration inherited from above would stay invisible to it. Verified on 19.0 with viin_brand_web and viin_customizer installed: the old guard fails with "'--NavBar-entry-backgroundColor--hover:' unexpectedly found", the new one passes, and temporarily adding `.o_main_navbar { --NavBar-entry-backgroundColor--hover: #00bbce }` to the brand bundle still makes it fail. Signed-off-by: David Tran <david.tran@tvtmarine.com>