[REF] product_origin_char: simplify to template-based origin

- Move origin_text field from product.supplierinfo to product.template
- Add related field in product.product for variant access
- Remove dependency on product_main_seller
- Update views to show field near category (editable)
- Rewrite tests for new architecture
- Update all documentation (README, readme/ fragments)
- Bump version to 18.0.2.0.0
This commit is contained in:
snt 2026-03-06 17:43:20 +01:00
parent e2ced75ecd
commit 5efe57dc19
15 changed files with 180 additions and 402 deletions

View file

@ -4,111 +4,88 @@
### Architecture
This module extends the product origin information system to use free-text fields instead of structured country/state fields.
This module adds a simple free-text origin field to products.
**Models:**
1. **product.supplierinfo** - Base model with the `origin_text` field
- Field: `origin_text` (Char, translate=True)
1. **product.template** - Base model with the `origin_text` field
- Field: `origin_text` (Char)
- This is where the actual data is stored
- Each supplier can have a different origin text for the same product
- Editable directly on the product form
2. **product.template** - Computed field
- Field: `origin_text` (Char, computed, store=False)
- Computes from main vendor's supplierinfo
- Depends on: `main_seller_id`, `variant_seller_ids.origin_text`
2. **product.product** - Related field for variant access
- Field: `origin_text` (Char, related to `product_tmpl_id.origin_text`)
- `readonly=False` allows editing from variant views
- Changes propagate to the template
3. **product.product** - Computed field (variant level)
- Field: `origin_text` (Char, computed, store=False)
- Computes from main vendor's supplierinfo
- Depends on: `product_tmpl_id.main_seller_id`, `seller_ids.origin_text`
### Why This Architecture?
### Why Computed Fields Instead of Related?
The `origin_text` field is stored in `product.template` because:
The `origin_text` field in `product.template` and `product.product` cannot be a simple `related` field because:
- Origin typically applies to all variants of a product
- Simplifies data management (one source of truth)
- Avoids duplication across variants
- Standard Odoo pattern for product-level attributes
- `main_seller_id` is a `res.partner` record
- `origin_text` is stored in `product.supplierinfo` records
- We need to find the supplierinfo record where `partner_id == main_seller_id`
The related field in `product.product` with `readonly=False` allows:
This requires a computed field with custom logic to filter and find the correct supplierinfo record.
- Seamless access from variant views
- Editing from either template or variant forms
- Automatic synchronization between template and variants
### Translation Support
### Previous Architecture (Deprecated)
The `origin_text` field in `product.supplierinfo` uses `translate=True`, which means:
The previous version stored `origin_text` in `product.supplierinfo` with computed
fields in template/product. This was deprecated because:
- Each language can have a different value
- Translations are stored in Odoo's translation system
- When switching languages, the field shows the translated value
- If no translation exists, it falls back to the default language value
### Store Strategy
The computed fields in product template and product use `store=False` because:
- The value should always reflect the current main vendor
- If the main vendor changes or its origin text is updated, the product's origin should update automatically
- No need to store redundant data
- Reduces database size and update complexity
- Supplierinfo records don't always exist when products are created
- Added unnecessary complexity with computed fields
- Required `product_main_seller` dependency
- Origin semantically belongs to the product, not the supplier relationship
### Dependencies
- **product** - Core product module
- **product_main_seller** - Provides `main_seller_id` computed field for products
### Relationship to product_origin
This module is a replacement/alternative to the OCA `product_origin` module:
- `product_origin` provides structured fields (country_id, state_id)
- `product_origin_char` provides free-text field (origin_text)
- Both cannot be installed simultaneously without potential conflicts
- This module was created because suppliers use creative, non-standardized origin descriptions
- **product** - Core product module (only dependency)
### Performance Considerations
- Computed fields with `store=False` are calculated on-the-fly
- Performance is acceptable because the computation is simple (filter + get first)
- If performance becomes an issue, consider:
- Adding `store=True` with proper dependencies
- Adding database indexes on frequently searched fields
- Caching strategies
- Simple stored field with no computation overhead
- Related field access is efficient in Odoo ORM
- No additional queries needed for variant access
### Testing Strategy
Tests cover:
1. **Basic field storage** - Create supplierinfo with origin_text
2. **Computed field** - Verify product shows main vendor's origin
3. **Main vendor change** - Verify origin updates when main vendor changes
4. **Translation** - Verify field is translatable (multilingual support)
5. **Empty cases** - Product without vendors, vendor without origin
### Future Improvements
Potential enhancements:
- Add migration script from `product_origin` to convert country/state to text
- Add bulk update wizard to set origin for multiple products
- Add origin text to purchase order lines
- Add search/group by origin in product lists
- Add validation rules (max length, format checks)
1. **Basic field storage** - Set origin on template
2. **Related field access** - Verify variant sees template origin
3. **Write from variant** - Verify changes propagate to template
4. **Empty cases** - Products without origin
5. **Multiple products** - Independent origins
6. **Variants** - All variants share same origin
## Code Quality
- Follows OCA guidelines
- Black formatted (line length 88)
- isort sorted imports
- Passes flake8 and pylint checks
- Full test coverage
- Documented with docstrings
- Translatable strings handled correctly (no `_()` in field definitions)
- isort for imports
- Minimal dependencies (only `product`)
## Migration from v1.x
If upgrading from the previous supplier-based architecture:
1. Data in `product.supplierinfo.origin_text` will need manual migration
2. Run migration script to copy main supplier origin to product template
3. Remove dependency on `product_main_seller` if no longer needed
## Version History
- **18.0.1.0.0** (2026-02-25) - Initial release
- **18.0.2.0.0** (2026-03-06) - Simplified architecture
- Field directly on product.template
- Related field in product.product
- Removed dependency on product_main_seller
- **18.0.1.0.0** (2026-02-25) - Initial release (deprecated)
- Free-text origin field per supplier
- Automatic display based on main vendor
- Multi-language support
- Full test coverage
- OCA documentation structure