Commit graph

285 commits

Author SHA1 Message Date
snt
e2ced75ecd [ADD] website_sale_aplicoop: create picking batches after cutoff
- Add stock_picking_batch dependency to manifest
- Add cutoff date validation in _confirm_linked_sale_orders()
- Create _create_picking_batches_for_sale_orders() method
- Group pickings by consumer_group_id into separate batches
- Set batch scheduled_date from group order pickup_date
- Add test_cron_picking_batch.py with 7 tests covering:
  - Skip orders before cutoff
  - Confirm orders after cutoff
  - Separate batches per consumer group
  - Same group orders in same batch
  - Batch has scheduled_date
  - No duplicate batches on re-run
  - Closed group orders not processed
2026-03-06 15:45:12 +01:00
snt
c3173a32c9 [IMP] website_sale_aplicoop: extract order card meta to separate template
- Create eskaera_order_card_meta template for cleaner code
- Simplify layout: horizontal meta-grid instead of table
- Fix t-if conditions on container elements
- Show only relevant fields: cutoff, pickup, delivery
- Add meta-grid CSS styles for compact horizontal display
- Home delivery badge only shown when enabled
2026-03-06 14:10:58 +01:00
snt
80539f3e36 [IMP] website_sale_aplicoop: propagate consumer_group_id directly from group_order
- Add consumer_group_id to sale.order for tracking the consumer group
- Fix stock.picking consumer_group_id to use sale_id.consumer_group_id
- Add group_ids inverse relation in res.partner for bidirectional access
- Remove auto-calculation of consumer_group_id, data comes directly from group_order.group_ids[0]
- Add debug logging for consumer_group propagation
- commitment_date propagates directly from group_order (no recalculation)
2026-03-06 13:49:13 +01:00
snt
4141fc5ab1 [IMP] website_sale_aplicoop: respect allow_out_of_stock_order
Added website_sale_stock dependency and modified _compute_stock_ribbons
to respect the allow_out_of_stock_order field:
- If allow_out_of_stock_order=True: product can always be added to cart
- If allow_out_of_stock_order=False and qty<=0: add-to-cart is blocked

The JS logic already checks data-out-of-stock attribute from template,
so no frontend changes were needed.

Version bump: 18.0.1.7.0 -> 18.0.1.8.0
2026-03-05 22:15:50 +01:00
snt
d3f26120b0 [FIX] website_sale_aplicoop: fix aplicoopShop -> groupOrderShop reference
After infinite scroll loads new products, the event listeners were
never re-attached because the code was looking for window.aplicoopShop
but the actual object is window.groupOrderShop.
2026-03-05 22:03:34 +01:00
snt
3eeca66551 [FIX] stock_picking_batch_custom: prevent product_id null error on summary lines
- Use regular dict instead of defaultdict to avoid empty entries
- Make summary_line_ids readonly=True to prevent UI from inserting empty lines
- Add SQL constraint CHECK(product_id IS NOT NULL) as safeguard
- Use boolean_toggle widget for is_collected field
- Fix tests to use TransactionCase and invalidate_recordset
- Add test for empty batch + add pickings + confirm flow
2026-03-05 21:47:18 +01:00
snt
ad8b759643 [ADD] stock_picking_batch_custom: product summary 2026-03-05 20:29:17 +01:00
snt
9c14e1dc1a [FIX] website_sale_aplicoop: ensure add-to-cart on infinite scroll 2026-03-05 18:57:10 +01:00
snt
eaedf0b421 [FIX] website_sale_aplicoop: hard block out-of-stock button 2026-03-03 15:49:19 +01:00
snt
33c148e6a1 [FIX] website_sale_aplicoop: block out-of-stock add 2026-03-03 15:30:43 +01:00
snt
9bd48654fd [I18N] website_sale_aplicoop: Translate weekdays 2026-03-03 15:26:01 +01:00
snt
62a1c4e1e9 [FIX] website_sale_aplicoop: force enable cart buttons 2026-03-03 15:09:16 +01:00
snt
6cc0a18de3 [FIX] website_sale_aplicoop: enable add to cart 2026-03-03 14:58:47 +01:00
snt
a9c1f1f609 [FIX] website_sale_aplicoop: align pricing and drafts 2026-02-27 19:39:25 +01:00
snt
aef57a3de4 [DOC] product_sale_price_from_pricelist: actualizar documentación v18.0.2.7.0
- CHANGELOG: documentar nueva funcionalidad de actualización de órdenes de venta
- README: añadir sección sobre Update Sales Orders from List Price
- README_DEV: incluir uso de la acción en workflow
- readme/USAGE: detallar paso a paso para actualizar órdenes

Funcionalidad documentada:
- Botón/acción para actualizar líneas de orden de venta con precio actual del producto
- Solo procesa órdenes no facturadas/canceladas
- Preserva descuentos, omite notas/secciones y anticipos
- Disponible en vista formulario y lista
2026-02-27 17:10:53 +01:00
snt
d294843241 [DOC] stock_picking_batch_custom: documentación OCA 2026-02-27 17:09:22 +01:00
snt
55497327e8 [ADD] product_sale_price_from_pricelist: update sale orders from list price 2026-02-27 17:05:54 +01:00
snt
ced21cc489 [ADD] stock_picking_batch_custom: columnas opcionales partner y categoría 2026-02-27 16:03:25 +01:00
snt
97dc41d212 [FIX] website_sale_aplicoop: toggle reparto desde carrito 2026-02-27 15:43:59 +01:00
snt
2f57a5d14e [IMP] group_order: confirmar sale orders en cron diario 2026-02-27 15:19:41 +01:00
snt
6935d8fc83 [FIX] website_sale_aplicoop: save draft on checkout button 2026-02-27 14:58:20 +01:00
snt
6f593c6240 [ADD] product_main_seller: Restore OCA addon from original version
- Restored product_main_seller addon to fix dependency chain
- Addon required by product_origin_char and website_sale_aplicoop

[IMP] website_sale_aplicoop: Add demo data configuration to manifest

- Updated __manifest__.py to include demo data files
- Demo data includes partners, suppliers, products, group orders, and sale orders
- Demo data successfully loads during module installation
2026-02-27 14:07:41 +01:00
snt
a483925005 demo files 2026-02-27 13:43:56 +01:00
snt
6381a2d985 cleaned OCA addon 2026-02-27 13:42:41 +01:00
snt
d58c621ef1 [FIX] website_sale_aplicoop: enable add to cart 2026-02-27 13:30:00 +01:00
snt
130a5ff6c4 [FIX] website_sale_aplicoop: Arreglar botón Home Delivery en shop (añadir/remover producto de entrega al carrito) 2026-02-26 15:12:06 +01:00
snt
4a668b3240 [REF] website_sale_aplicoop: Mejorar legibilidad del XML (reformatear con mejor indentación) 2026-02-26 14:59:34 +01:00
snt
67215f7684 [FIX] website_sale_aplicoop: Remover _() de template QWeb (no funciona en contexto QWeb) 2026-02-26 14:45:35 +01:00
snt
9937e987f4 [I18N] website_sale_aplicoop: Limpieza de traducciones y etiquetas UI en inglés por defecto 2026-02-26 14:33:44 +01:00
snt
c2f9f347b7 chore: eliminar módulo obsoleto product_origin
Eliminado product_origin (antiguo) que ha sido reemplazado por product_origin_char.
El nuevo módulo product_origin_char usa tipo Char en vez de Selection para el campo origin.
2026-02-25 20:19:05 +01:00
snt
2a005a9d5a feat(website_sale_aplicoop): sistema de ribbons basado en stock
- Añadidos ribbons 'Sin Stock' (rojo) y 'Pocas Existencias' (amarillo)
- Nuevo campo configurable: umbral de stock bajo (default: 5.0)
- Campos computed en product.product:
  * is_out_of_stock: True cuando qty_available <= 0
  * is_low_stock: True cuando 0 < qty_available <= threshold
  * dynamic_ribbon_id: ribbon automático según nivel de stock
- Ordenamiento mejorado: productos con stock primero, sin stock al final
- Template actualizado:
  * Muestra ribbon de stock en tarjeta de producto
  * Deshabilita botón add-to-cart cuando producto sin stock
  * Cambia icono a 'fa-ban' en productos sin stock
- Vista de configuración: campo 'Low Stock Threshold' en Settings > Shop Performance
- Solo aplica a productos type='consu' (almacenables)
- Tests: 112 pasados, 0 fallos
2026-02-25 19:48:39 +01:00
snt
539cd5cccd feat(website_sale_aplicoop): ordenar productos por website_sequence y nombre
- Ordena productos primero por website_sequence y luego alfabéticamente por nombre (case-insensitive)
- Fix test: cambiar tipo de producto de 'product' a 'consu' (Odoo 18 compatibility)
2026-02-25 19:34:49 +01:00
snt
3f822a28cf [FIX] mypy: Configure to ignore missing Odoo imports globally
- Set ignore_missing_imports = True at global [mypy] level
- Add explicit sections for odoo, odoo.*, and odoo.addons.*
- Fixes pre-commit hook failures when mypy checks Odoo addon files
- Resolves 'Cannot find implementation or library stub for module named odoo' errors

This is a known issue with Odoo stubs not being fully compatible with mypy.
2026-02-25 19:01:28 +01:00
snt
1779c42e9b [IMP] website_sale_aplicoop: Replace product_origin with product_origin_char
- Replace dependency from product_origin to product_origin_char
- Update product card template to show origin_text field instead of country_id/state_id
- Simpler and more flexible: free text origin per supplier instead of structured fields
- Version: 18.0.1.6.0 -> 18.0.1.7.0

The new field is more suitable for creative product origins like 'Valencia, Huerta de...'
or 'Región de Murcia, cooperativa XX' which don't fit the rigid country/state structure.
2026-02-25 18:55:33 +01:00
snt
e4e03d4794 tmp/ 2026-02-25 18:43:46 +01:00
snt
c8b83cc333 [ADD] product_origin_char: Free text origin field per supplier
New addon to replace structured country/state fields with flexible
free-text origin descriptions.

Features:
- Translatable origin_text field in product.supplierinfo
- Computed origin field in products based on main_seller_id
- Support for creative supplier origin descriptions
- Full OCA documentation structure
- ES/EU translations included
- 8 unit tests (all passing)

Replaces product_origin for use cases where suppliers use non-standardized
origin descriptions (e.g., 'Valencia, Spain', 'Huerta de...', etc.)

Depends on: product, product_main_seller
Author: Criptomart
Funding: Elika Bilbo
2026-02-25 18:42:54 +01:00
snt
1a8f92a01e iconos 2026-02-25 18:41:16 +01:00
snt
c367e20fc5 [DOC] Limpiar documentación temporal y scripts de test obsoletos 2026-02-25 17:47:33 +01:00
snt
464ca48127 [IMP] website_sale_aplicoop: quantity_step multilingüe usando XML IDs de UoM. Detecta peso, volumen, longitud, superficie independiente del idioma. 2026-02-25 17:45:45 +01:00
snt
92b35ccd6d [FIX] website_sale_aplicoop: step de cantidad correcto tras filtrar categoría. El JS ahora usa data-quantity-step generado por backend, evitando sobrescribir el step correcto en inputs de productos a peso/unidad. 2026-02-25 17:17:06 +01:00
snt
7b343ef198 [FIX] website_sale_aplicoop: Fix category filter ignoring blacklists
Critical fix for category filter in product discovery:

- BREAKING BUG: Category filter was doing a new search() that
  completely ignored product/supplier/category blacklists
- FIX: Now filters from filtered_products (which has blacklists applied)
  instead of doing a fresh search() from database
- This ensures blacklist rules are ALWAYS respected

Added detailed logging for debugging empty category results:
- Log collected category IDs (including children)
- Log before/after product counts
- If result is empty, log sample product categories to help debug
- Helps identify configuration issues vs code bugs

This fixes user report: 'no muestra ningún producto' in some categories
The issue was that filtered products were being replaced with a fresh
search that bypassed all blacklist filters.
2026-02-23 16:09:29 +01:00
snt
c1226e720b [ADD] website_sale_aplicoop: Category blacklist with recursive exclusion
- Add comprehensive test suite for excluded_category_ids
- 9 tests covering: single category, recursive subcategories,
  parent exclusion, direct product override, unrelated categories,
  empty blacklist, multiple exclusions, combined blacklists,
  available_products_count validation
- Update UI to show excluded_category_ids in 'Productos Excluidos'
- Bump version to 18.0.1.6.0
- Update CHANGELOG with category blacklist documentation

Technical notes:
- Category blacklist was already implemented in model/logic
- This commit adds missing tests and documentation
- Recursive exclusion via get_all_excluded_descendants()
- Blacklist has absolute priority over all inclusion sources
2026-02-22 23:04:33 +01:00
snt
d90f2cdc61 [ADD] website_sale_aplicoop: Supplier blacklist feature for group orders
- Add excluded_supplier_ids field for supplier exclusion
- Filter products by main_seller_id (from product_main_seller addon)
- Blacklist has absolute priority over all inclusion sources
- Products with blacklisted main supplier never appear in orders
- Update _get_products_for_group_order() with supplier blacklist logic
- Add excluded_supplier_ids to 'Productos Excluidos' section in form view
- Add comprehensive test suite (TestSupplierBlacklist class with 9 tests):
  * Test exclusion by main_seller_id
  * Test multiple supplier exclusion
  * Test products without main seller not affected
  * Test blacklist with direct product inclusion
  * Test blacklist priority over supplier inclusion
  * Test combined product and supplier blacklist
  * Test available_products_count with supplier blacklist
- Add Spanish and Euskera translations
- Update available_products_count computation to include excluded_supplier_ids
- Version bump to 18.0.1.5.0

Use case: Exclude all products from specific supplier (e.g., temporary unavailability)
Example: Category with 100 products, exclude supplier X → all products from X excluded
Workflow: Bulk inclusion via categories + supplier-level exclusion + product-level exclusion
2026-02-22 21:35:40 +01:00
snt
75ebb7b907 [ADD] website_sale_aplicoop: Product blacklist feature for group orders
- Add excluded_product_ids field for explicit product exclusion
- Blacklist has absolute priority over all inclusion sources (product_ids, category_ids, supplier_ids)
- Update _get_products_for_group_order() with blacklist filter logic
- Rename 'Associations' section to 'Catálogo de Productos' with subsections:
  * Productos Incluidos (whitelist: suppliers, categories, direct products)
  * Productos Excluidos (blacklist: explicit exclusions)
- Add comprehensive test suite (TestProductBlacklist class with 7 tests)
- Add Spanish and Euskera translations
- Update available_products_count computation to include excluded_product_ids
- Version bump to 18.0.1.4.0

Use case: Bulk inclusion via categories/suppliers + fine-grained exclusion via blacklist
Example: Select a category with 100 products, exclude 5 unwanted → 95 available
2026-02-22 20:41:11 +01:00
snt
4a4639f13a [DOC] Actualizar documentación a estándares OCA y preparar logo CriptoMart
- Renombrar README.md a README_DEV.md en todos los addons custom
- Crear README.rst siguiendo estructura OCA oficial
- Crear directorios readme/ con fragmentos .rst (DESCRIPTION, INSTALL, CONFIGURE, USAGE, CONTRIBUTORS, CREDITS)
- Actualizar créditos: Criptomart (autor) + Elika Bilbo (financiador)
- Actualizar __manifest__.py con maintainers correctos
- Crear estructura static/description/ para logo en 5 addons
- Agregar documentación de logo (LOGO_INSTRUCTIONS.md, install_logo.sh)
- Actualizar copilot-instructions.md con referencias a OCA_DOCUMENTATION.md
- Crear docs/OCA_DOCUMENTATION.md con guía completa de estructura
- Crear docs/RESUMEN_CAMBIOS_DOCUMENTACION.md con resumen detallado

Addons actualizados:
- website_sale_aplicoop
- product_sale_price_from_pricelist
- product_pricelist_total_margin
- product_price_category_supplier
- account_invoice_triple_discount_readonly
2026-02-21 19:55:57 +01:00
snt
b31df7b9d8 [DOC] product_pricelist_total_margin: Update docs and version to 18.0.1.2.0
Changelog:
- Document global_margin_type feature for independent global limits calculation
- Update version from 18.0.1.1.0 to 18.0.1.2.0
- Update test coverage count (11 → 13 tests)
- Update manifest summary to include global limits enforcement
2026-02-21 19:19:25 +01:00
snt
449bb75bb6 [IMP] product_pricelist_total_margin: Add global_margin_type for min/max limits
- Add global_margin_type field in res.config.settings
  * Options: 'markup' (default) or 'margin' (commercial margin)
  * Determines how global min/max percentages are interpreted
- Refactor _apply_global_margin_limits():
  * Now receives price instead of margin percentage
  * Calculates min/max prices based on global_margin_type
  * Returns adjusted price instead of adjusted margin
  * Supports both markup and commercial margin formulas
- Update _compute_price() to apply limits after price calculation
- Update res_config_settings_views.xml to show global_margin_type selector
- Update help texts with examples for both calculation methods
- Add 2 new tests to validate global limits with commercial margin type:
  * test_global_minimum_with_commercial_margin_type
  * test_global_maximum_with_commercial_margin_type
- All 13 tests passing (11 existing + 2 new)

Example with global min 25%:
- Markup: Min price = Cost × 1.25
- Commercial Margin: Min price = Cost / 0.75 (ensures 25% margin on PVP)
2026-02-21 19:16:16 +01:00
snt
07cc0eb517 [DOC] product_pricelist_total_margin: Update documentation for v1.1.0
- Update README with margin_type field documentation
- Add detailed explanations for both calculation methods:
  * Markup (on cost): PVP = Cost × (1 + markup%)
  * Commercial Margin (on PVP): PVP = Cost / (1 - margin%)
- Add examples comparing both methods
- Update features list with new capabilities
- Update configuration steps to include margin_type selector
- Update technical details with new field specifications
- Update test coverage section (11 tests)
- Add logging examples for both methods
- Update changelog with v18.0.1.1.0 release notes
- Bump version to 18.0.1.1.0 in __manifest__.py
- Update summary to reflect new features
2026-02-21 19:11:01 +01:00
snt
55406ca22d [FIX] product_pricelist_total_margin: Change field string to avoid redundancy
- Change margin_type string from 'Margin Type' to 'Calculation Method'
- Fixes pylint warning W8113 (attribute-string-redundant)
2026-02-21 18:55:00 +01:00
snt
0f239601ce [IMP] product_pricelist_total_margin: Add margin_type selector (Markup vs Commercial Margin)
- Add margin_type field to choose between calculation methods:
  * Markup (on cost): PVP = Cost × (1 + markup%)
  * Commercial Margin (on PVP): PVP = Cost / (1 - margin%)
- Update _compute_price() to apply correct formula based on margin_type
- Add safety cap for commercial margin >= 100% (caps at 99%)
- Add detailed logging for both calculation types
- Update views to show margin_type field when use_total_margin is enabled
- Add 2 new tests to validate both calculation methods:
  * test_total_margin_markup_type: validates markup formula
  * test_total_margin_commercial_margin_type: validates commercial margin formula
- All 11 tests passing (9 existing + 2 new)

Example with Commercial Margin:
Base: 4.68€, Total Margin: 20%
- Markup: 4.68 × 1.20 = 5.616€ (margin = 16.67% of PVP)
- Commercial Margin: 4.68 / 0.80 = 5.85€ (margin = 20% of PVP) ✓
2026-02-21 18:54:38 +01:00