74 Commits

Author SHA1 Message Date
gsinghpal
f4c6dca171 Update woo_instance.py 2026-04-07 21:47:15 -04:00
gsinghpal
7d8f30627f changes 2026-04-07 21:42:12 -04:00
gsinghpal
1c560c6df2 changes 2026-04-02 17:55:32 -04:00
gsinghpal
3022b8ed59 CHANGES 2026-04-02 10:45:07 -04:00
gsinghpal
2a363c6b40 changes 2026-04-02 03:30:02 -04:00
gsinghpal
5b76037988 fix: don't re-upload images for already-synced variants
Pre-fill image field only for NEW variants. Already-synced variants
get an empty image field — existing WC image is kept unless the user
actively uploads a new one in the wizard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 22:06:32 -04:00
gsinghpal
39e007b42f feat: default variant selector — user picks which variant is the default
Added 'Default' toggle column in variant push wizard. First variant is
pre-selected as default. User can change it. The default variant's
attribute values are set as WC product's default_attributes using
WC attribute IDs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 22:02:29 -04:00
gsinghpal
8c01deb2e3 fix: properly decode base64 image data and detect MIME type
Image endpoint was returning base64 text instead of decoded binary.
Now properly decodes base64 from Odoo Binary field and detects actual
content type from magic bytes (JPEG, PNG, GIF, WebP).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:57:14 -04:00
gsinghpal
1a679a45c3 fix: serve variant images via custom endpoint instead of product URL
Product image URL was serving placeholder because writing to image_1920
doesn't work for variants (computed field). New approach:
1. Store image in wizard line table (attachment=False, bytea column)
2. Serve directly via /woo/image/{line_id}/{filename} endpoint
3. WC downloads real image data from this URL
4. Also saves to image_variant_1920 for Odoo reference

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:53:41 -04:00
gsinghpal
88305a4ce0 chore: bump version to 19.0.3.0.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:49:08 -04:00
gsinghpal
e3d784f566 fix: store variant image in DB table not ir.attachment
Binary field with attachment=True (default) stores in ir.attachment
which doesn't work reliably for transient model inline list records.
Set attachment=False to store in the woo_variant_push_line table directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:44:30 -04:00
gsinghpal
27955c8c41 fix: force commit image save and add debug logging for variant images
Image wasn't persisting because transient model write was in the same
transaction. Added cr.commit() after saving image to ensure it's
available when WC downloads it. Added size/type logging to trace
image data flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:37:39 -04:00
gsinghpal
21c1e37211 fix: save wizard images to Odoo product before passing URL to WC
The wizard's binary image field wasn't being saved to the product.product
record, so the public URL returned the default placeholder. Now saves
line.image → variant.image_1920 first, then generates the URL with a
cache-busting timestamp. Only includes image in WC data if the wizard
line has an actual image uploaded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:35:03 -04:00
gsinghpal
ed426912ce fix: add .png extension to image URLs — WC rejects extensionless URLs
WooCommerce requires a file extension in image src URLs to determine
file type. Added filename.png to all Odoo image URLs. Also fixed
variable name ordering bugs where img_name was used before defined.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:26:25 -04:00
gsinghpal
768731da0f fix: use Odoo public image URLs instead of broken WP media upload
WC consumer key cannot auth against /wp/v2/media (401). Instead, pass
Odoo's public image URL in the product/variation data and let WC
download it directly from {odoo_base}/web/image/product.product/{id}/image_1920.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:10:47 -04:00
gsinghpal
75ceee1e69 fix: use WC attribute ID (not name) when setting variation attributes
WooCommerce silently ignores attribute 'name' on variation updates —
requires 'id' (the WC attribute ID). Built a lookup map from the
parent product's wc_attributes and use 'id' in all variation payloads.
Fixed in all 3 files: variant push wizard, product creation wizard,
and product map direct push.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 18:59:54 -04:00
gsinghpal
71dea1f91b fix: remove readonly from variant line model — use force_save in view
Odoo web client strips readonly field values during record creation,
so already_synced/wc_variation_id/map_id were always NULL. Removed
readonly from Python model, added force_save="1" in XML view to ensure
these tracking fields are persisted through the wizard lifecycle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 18:39:13 -04:00
gsinghpal
842832cc41 fix: filter inactive/attributeless variants from push wizard
Archived variants (active=False) and variants with no attribute values
were being included, causing WC 400 errors. Now only active variants
with attribute assignments are shown and pushed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 18:33:50 -04:00
gsinghpal
08d7ee17ff fix: populate variant lines in default_get instead of onchange
Onchange wasn't firing when wizard opened via context defaults. Moved all
variant line population to default_get so lines are pre-filled immediately.
Added debug logging to trace new vs update classification.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 18:32:13 -04:00
gsinghpal
39d4fe5020 fix: variant update now sets attribute values and default variant on WC
- Update path sends attributes per variation (was missing, causing
  "Any COLOR..." on WC)
- Sets default_attributes on parent product (first variant's values)
- Better API error logging with response body

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 18:20:52 -04:00
gsinghpal
8983c8bd50 feat: variant wizard now creates AND updates existing WC variations
Already synced variants are editable — change price, SKU, image and click
Save & Sync to update them on WooCommerce. New variants are created,
existing ones updated in a single action. Button shows on all products
with variants (purple for new, grey for already synced).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 18:10:07 -04:00
gsinghpal
1bf4092b39 feat: variant push wizard — review pricing, SKU, images before pushing
Replaced direct push with a wizard that shows all variants in an editable
table. User can review/edit standard price, sale price, SKU, and image
per variant before pushing. Include/exclude toggle per variant. Already
synced variants shown for reference. Geo-tags images if configured.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 18:05:39 -04:00
gsinghpal
2afe54d15e fix: move variant push button inline with Odoo Product name
Removed separate Variants column — button now appears right next to the
Odoo product name so it's visible without scrolling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 17:59:25 -04:00
gsinghpal
a0ad52fe46 feat: push variants button on mapped products — convert simple→variable in WC
When a mapped product is simple on WC but has variants in Odoo, a purple
"N variants" button appears in the Variants column. Clicking it:
1. Converts the WC product from simple to variable
2. Creates WC attributes and terms from Odoo attribute lines
3. Creates a WC variation for each Odoo variant with price/SKU/stock/tax/image
4. Creates woo.product.map records for each variation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 17:52:37 -04:00
gsinghpal
a3fa1ced16 fix: group Odoo products by template — show variant count instead of duplicates
Search endpoint now queries product.template instead of product.product,
so a product with 20 variants shows as 1 row with a "20 variants" badge
instead of 20 duplicate rows. Category name shown in sub-text.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 17:42:01 -04:00
gsinghpal
9d483fb474 feat: full variable product support — create WC products with variants from Odoo
Detects Odoo product variants (product.template.attribute_line) and creates
WC variable products with attributes and variations. Each variation gets
its own price, SKU, image, stock, and tax class. Variant lines shown in
wizard with include/exclude toggle. WC attributes and terms auto-created.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 17:22:40 -04:00
gsinghpal
05c84d077d feat: move tax and pricelist mapping inline to Sync Settings tab
Tax mapping and pricelist mapping now live directly on the instance
form under Sync Settings. Added Fetch WC Tax Classes button that pulls
tax classes from WC API and auto-matches. Removed standalone menu items.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:58:01 -04:00
gsinghpal
bc2bba14aa fix: redesign product creation wizard — use Odoo statusbar, clean layout
- Replaced hardcoded badge step indicator with Odoo's native statusbar widget
- Removed all hardcoded Bootstrap colour classes (bg-primary, text-muted, etc.)
- Using oe_highlight and oe_link for buttons (theme-aware)
- Cleaner 2-column layout for basic info and review steps
- Full-width separators and fields for content step
- Images in 2-column grid
- SEO meta fields use proper group layout

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:23:07 -04:00
gsinghpal
b83c9fd318 fix: auto-refresh product list when category filter wizard closes
Used doAction onClose callback instead of await — the wizard dialog
close now triggers reload of excluded count and product list. Same
fix applied to product creation wizard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:11:36 -04:00
gsinghpal
5e806745da feat: persistent hidden categories with wizard and toggle
Categories to hide are stored on woo.instance and persist across sessions.
Click 'Hidden (N)' button to open wizard where you can add/remove categories
using a tag picker. Eye/eye-slash toggle to quickly apply or unapply the
filter without losing the saved list.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:06:15 -04:00
gsinghpal
52be90c10d feat: category filter dropdown on unmatched Odoo products panel
Filter by Odoo product category or clear filter. Backend supports
both include and exclude category filtering. Loads all categories
on init for the dropdown.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:56:13 -04:00
gsinghpal
9f0badfb7e fix: AI prompt fields use full width instead of narrow column
Removed group wrappers around prompt fields. Using label + field pattern
directly inside the page so prompts span the full available width.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:45:18 -04:00
gsinghpal
c46e4c0b28 feat: AI model selection dropdown with Claude and OpenAI models
Replaced free-text model field with Selection showing standard models
from both providers: Claude Opus/Sonnet/Haiku and OpenAI GPT-4o/4.1/o3.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:36:23 -04:00
gsinghpal
c169704687 chore: bump version to 19.0.2.0.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:50:06 -04:00
gsinghpal
4efd5066d0 feat: AI-powered product creation wizard with SEO and image geo-tagging
4-step wizard: Basic Info → Images → Content & SEO → Review & Create.
AI generates product titles, descriptions, meta data using Claude or OpenAI.
Image geo-tagging with company EXIF data. SEO meta pushed to Rank Math,
Yoast, AIOSEO, and SEOPress simultaneously. Products created with CAPS
name in Odoo, Title Case in WooCommerce.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:44:48 -04:00
gsinghpal
f759bf558f feat: add AI service (Claude + OpenAI) and image processor with EXIF geo-tagging
AIService wraps both Anthropic Claude and OpenAI APIs for product content
generation. ImageProcessor handles EXIF geo-tagging with company info and
GPS coordinates using piexif.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:39:44 -04:00
gsinghpal
3493c43916 feat: add category mapping model and AI settings on woo.instance
Category mapping between Odoo product categories and WC categories with
auto-match by name and manual mapping UI. AI settings for Claude/OpenAI
with customizable prompts for product content generation. GPS coordinates
for image geo-tagging pulled from company settings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:30:02 -04:00
gsinghpal
3179cc1f7b feat: add editable WC SKU and Odoo SKU columns with bidirectional sync
Both SKU fields are inline-editable. Arrow buttons sync individual SKUs.
Bulk buttons sync all SKUs Odoo→WC or WC→Odoo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:32:26 -04:00
gsinghpal
1a1a37b3e3 feat: add Fusion WooCommerce app icon
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:34:52 -04:00
gsinghpal
3de513fb7b fix: round edit values — margin shows whole number, prices show 2 decimals
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:44:10 -04:00
gsinghpal
4941df8131 fix: remove decimal points from margin percentage — whole numbers only
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:41:50 -04:00
gsinghpal
b3fb2ef40c feat: add Cost and Margin % columns with inline editing
Cost column shows Odoo standard_price (editable). Margin % is calculated
from cost and sale price. Editing margin auto-calculates the sale price
using: price = cost / (1 - margin/100). All cells are inline-editable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:38:37 -04:00
gsinghpal
c5b519f8f4 feat: inline-editable prices in product mapping UI
Click any price cell (WC Standard, WC Sale, Odoo Price) to edit inline.
Enter or click away saves and syncs to the source. Escape cancels.
Validation: sale price cannot exceed standard price.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:23:23 -04:00
gsinghpal
8b723086b9 docs: add CLAUDE.md for both fusion_woocommerce and fusion-woodoo
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 01:02:21 -04:00
gsinghpal
80f9ddd0d6 feat: WC standard price + sale price with smart sync logic
- Split woo_price into woo_regular_price and woo_sale_price
- Sync to WC: if standard=0 sets regular_price, otherwise sets sale_price
- Validation: standard price cannot be less than sale price
- Both prices shown in mapping UI with sale price highlighted in green
- Refresh Prices pulls both values from WC API

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 23:19:01 -04:00
gsinghpal
b1e4ed5ec8 feat: clickable WooCommerce product links in mapping UI
Product names in the mapped table are now links that open the WC product
page in a new tab. Added woo_permalink field, stored during fetch,
returned by search endpoint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 23:06:27 -04:00
gsinghpal
0e84b97c89 fix: sync never changes product map state from mapped
Price conflicts and sync errors were setting woo.product.map state to
'conflict'/'error', making products disappear from the mapped list.
Conflicts are now tracked only in woo.conflict model. Map state stays
'mapped' as long as the product link exists.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 23:01:26 -04:00
gsinghpal
1cc3ea7a18 fix: health check no longer changes instance state
The health check cron runs inside Docker which can't always reach
external URLs. It was setting state to 'error' breaking fetch/sync.
Now it only logs warnings — state changes only via explicit Test
Connection button.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 22:53:53 -04:00
gsinghpal
f9fcb6612b feat: add pagination, individual price sync arrows, and bulk price sync
- Pagination with page nav for mapped, unmatched Odoo, and unmatched WC tabs
- Per-product arrow buttons to push price in either direction
- Bulk price sync buttons: All Prices Odoo→WC and All Prices WC→Odoo
- Server-side offset/limit with total count in search endpoints

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 22:51:07 -04:00
gsinghpal
80b7d3d620 fix: OWL template error — Number() not available in template context
Use a formatPrice() method on the component instead of calling Number()
directly in the OWL template. Fixes TypeError: ctx.Number is not a function.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 22:39:50 -04:00