Htet Lin.
← All work
Watchbay by Cherry Oo, Myanmar · July to November 2026

Odoo 16 to 19 eCommerce upgrade and cloud move

Upgraded Myanmar's largest online watch retailer from Odoo 16 to Odoo 19 while it kept trading: rebuilt the storefront that the purchased theme could no longer render, moved hosting to AWS, scripted the migration so the final cutover switched in seconds, and left the client with staging, backups and self-service tools.

Role: Upgrade lead, storefront developer, DevOps

Odoo 19eCommerceVersion upgradeAWSPostgreSQL 16CloudflareMobile app API
16 to 19
Odoo versions crossed
26 s
Final production switch
6 min
Scripted upgrade replay
Odoo 16 to 19 eCommerce upgrade and cloud move

Summary

Watchbay is the official online channel of Cherry Oo, a watch retailer in Myanmar with a web shop, a customer mobile app and tens of thousands of registered customers. The shop ran on Odoo 16 with a purchased theme and a dozen custom modules. I led the move to Odoo 19: the database upgrade, the storefront rebuild, the hosting move and the cutover, then the first weeks of production support.

Challenge

  • The store could not stop trading. Every rehearsal had to be repeatable on a fresh copy of the live database, and the final switch had to fit in a few minutes.
  • The purchased theme would not upgrade. Its source still inherited Odoo 16 views and website-builder options that no longer exist in Odoo 19, so none of its changes could be deployed by module upgrade.
  • Three custom checkout, payment and loyalty modules used pre-Odoo 17 controller contracts, and the mobile app depended on them.
  • The client kept sending design requests during the project: new homepage wireframes, a product specification layout, a filter design, a UI deck, brand banners and spec sheets.

What I delivered

Repeatable upgrade. Ran Odoo’s upgrade service on the live database several times over the project, each time replaying the storefront fixes with scripts: copy the corrected custom views across, mark the modules that the upgrade left broken, upgrade 18 modules in a loop, apply the homepage layout and palette, copy banners, smoke test on a side port. By cutover day the whole replay took about six minutes and the production switch itself 26 seconds.

Storefront rebuilt in a clean add-on. Instead of fighting the theme, I shipped the client’s wireframes in a new Odoo 19 module that inherits the migrated views. It carries the new navigation taxonomy (Home, Men, Women, Clock, Brands, Blog), the full homepage section stack with a flash-sale countdown and full-bleed banners, per-brand pages, a product page with trust badges, per-brand warranty and a specification table, FAQ and blog pages, and a mobile drawer with icons. Watch-type menu entries (Quartz, Automatic, Digital, Smart) fill themselves from product specifications through a daily sync, and empty entries hide.

Shop, wishlist and promotions. Grouped category filters driven by a field staff can edit, a working wishlist heart toggle on top of stock Odoo 19, the site accent changed to the logo orange through the website-builder palette so it survives asset rebuilds, and the old promotion slider rebuilt so staff pick slides in Website Settings and each slide opens a generated landing page.

Reports and data. Ported the Odoo 16 invoice design onto the Odoo 19 template as surgical inherits after the old full-replacement view proved unrecoverable. Imported 2,390 specification rows and 21 brand banners from the client’s spreadsheets and Drive folder. Repaired the Myanmar city and township reference data behind the checkout address form without losing the 24,000 partner addresses that pointed at it.

Hosting move and cutover. Built Python 3.12 from source and installed PostgreSQL 16 side by side with the old Odoo 16 stack on the client’s AWS instance, so the two versions ran on one box during the transition. Cut the domain over behind Cloudflare, stopped the old service, and kept the Odoo 16 database as the rollback.

Operations after go-live. A neutralised staging site refreshed from production by one script; twice-daily database and filestore backups to S3, verified by restore; Cloudflare cache rules fixed after finding the homepage cached for a month by an old page rule; a checkout reload loop traced to loyalty reward markup missing from a custom cart template; nginx rate limits tuned so checkout traffic is not throttled; push notifications to the mobile app confirmed working and documented for staff to use themselves.

Techniques worth noting

  • Odoo 19 compares data-reward-type rows in the cart summary against the server’s reward list and reloads the page on a mismatch. Any custom cart template that drops that attribute produces a reload loop that only appears for carts with an automatic discount.
  • The website colour palette is stored in the database as a website-builder SCSS customisation, so changing fallbacks in theme SCSS does nothing. The lever is make_scss_customization on the website assets model, run from a module migration script.
  • Cloudflare cache rules apply the last matching rule per setting, so a bypass rule must exclude the asset prefixes or it silently turns asset caching off too.
  • Products created on Odoo 19 are not inventory-tracked unless Track Inventory is set. Import files need that column or stock imports fail.
New homepage on Odoo 19: marquee bar, promotion slider in the banner slot, Shop by Collection, Popular Collection and brand artwork bands
New homepage on Odoo 19: marquee bar, promotion slider in the banner slot, Shop by Collection, Popular Collection and brand artwork bands
Shop page with the grouped category filter (Couple, Men, Women with watch types and materials) and discount badges on product cards
Shop page with the grouped category filter (Couple, Men, Women with watch types and materials) and discount badges on product cards
Product page: brand headline, model reference, trust badges, per-brand warranty and the Product Specification table
Product page: brand headline, model reference, trust badges, per-brand warranty and the Product Specification table
Per-brand page with banner, All / Men / Women / New Arrival filter and product grid
Per-brand page with banner, All / Men / Women / New Arrival filter and product grid
Promotion landing page generated from the Website Promotion Slider record
Promotion landing page generated from the Website Promotion Slider record
Homepage on a phone with the bottom navigation bar
Homepage on a phone with the bottom navigation bar
Product page on a phone
Product page on a phone