From a4410b9b9e38537188bf82179766af23895674c4 Mon Sep 17 00:00:00 2001 From: GitHub Copilot Date: Wed, 20 May 2026 16:27:17 +0200 Subject: [PATCH 1/3] =?UTF-8?q?[DOC]=20actualizar=20y=20sincronizar=20docu?= =?UTF-8?q?mentaci=C3=B3n=20de=20todos=20los=20addons?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - README.md: reescrito con tabla completa de los 14 addons (6 OCA + 8 custom), versiones actuales, árbol de dependencias y comandos de desarrollo - docs/README.md: simplificado a índice limpio, eliminadas referencias rotas - website_sale_aplicoop/CHANGELOG.md: añadidas versiones 1.7.0, 1.8.0 y 1.9.0 con los cambios agrupados por temática desde el último registro (1.6.0) - website_sale_aplicoop/README_DEV.md: reescrito para reflejar v1.9.0 — modelos actuales (group.order.slot), controladores /eskaera, catálogo whitelist/blacklist, lazy loading, crons y árbol de dependencias Co-Authored-By: Claude Sonnet 4.6 --- README.md | 87 +++++- docs/README.md | 65 ++-- website_sale_aplicoop/CHANGELOG.md | 65 ++++ website_sale_aplicoop/README_DEV.md | 440 ++++++++++------------------ 4 files changed, 312 insertions(+), 345 deletions(-) diff --git a/README.md b/README.md index cb91d3e..8dbf2e0 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,81 @@ -# Oddo Addons Criptomart +# Odoo Addons — Criptomart -## Addons +Colección de addons Odoo 18.0 para Criptomart / Elika Bilbo. Incluye addons OCA incluidos como dependencias y addons custom desarrollados internamente. -| Addon | Propósito | Estado | -|-------|-----------|--------| -| [account_invoice_triple_discount_readonly](account_invoice_triple_discount_readonly/) | Fix para bug de descuentos acumulados | Alpha | -| [product_price_category_supplier](product_price_category_supplier/) | Gestión de categorías por proveedor | Alpha | -| [product_sale_price_from_pricelist](product_sale_price_from_pricelist/) | Auto-cálculo precio venta desde compra | Alpha | -| [website_sale_aplicoop](website_sale_aplicoop/) | Sistema completo de pedidos para grupos de consumo | Alpha | +## Addons OCA (dependencias incluidas) + +Addons del ecosistema [OCA](https://github.com/OCA) incorporados al repositorio. No se modifican salvo hotfixes puntuales. + +| Addon | Versión | Descripción | +| ----- | ------- | ----------- | +| [account_invoice_triple_discount](account_invoice_triple_discount/) | 18.0.1.0.0 | Triple descuento en líneas de factura | +| [product_get_price_helper](product_get_price_helper/) | 18.0.1.1.0 | Helper para obtener precios de producto respetando tarifas | +| [product_main_seller](product_main_seller/) | 18.0.1.0.0 | Campo "proveedor principal" en producto | +| [product_origin_char](product_origin_char/) | 18.0.2.0.0 | Campo de texto libre para origen del producto | +| [product_price_category](product_price_category/) | 18.0.1.0.0 | Categoría de precio en producto + aplicación masiva vía tarifas | +| [purchase_triple_discount](purchase_triple_discount/) | 18.0.1.0.0 | Triple descuento en líneas de pedido de compra | + +## Addons Custom + +Addons desarrollados por Criptomart para necesidades específicas del proyecto. + +| Addon | Versión | Descripción | +| ----- | ------- | ----------- | +| [account_invoice_triple_discount_readonly](account_invoice_triple_discount_readonly/) | 18.0.1.0.0 | Corrige bug de acumulación de descuentos y pone descuento total en solo lectura | +| [membership_expiry_reminder](membership_expiry_reminder/) | 18.0.1.0.0 | Recordatorio por email de membresías próximas a vencer | +| [portal_event_registration](portal_event_registration/) | 18.0.1.0.0 | Vista portal de inscripciones a eventos con adjuntos al chatter | +| [product_price_category_supplier](product_price_category_supplier/) | 18.0.1.0.0 | Categoría de precio por defecto en proveedor + actualización masiva de productos | +| [product_pricelist_total_margin](product_pricelist_total_margin/) | 18.0.1.2.0 | Margen aditivo (no compuesto) en tarifas encadenadas, con límites globales | +| [product_sale_price_from_pricelist](product_sale_price_from_pricelist/) | 18.0.2.7.0 | Calcula precio de venta desde último precio de compra vía tarifa configurable | +| [stock_picking_batch_custom](stock_picking_batch_custom/) | 18.0.1.0.0 | Columnas extra en operaciones detalladas de lotes: partner, categoría, recogido | +| [website_sale_aplicoop](website_sale_aplicoop/) | 18.0.1.9.0 | Sistema de pedidos colaborativos para grupos de consumo (reemplazo de Aplicoop) | + +## Dependencias entre addons custom + +```text +website_sale_aplicoop + └── product_sale_price_from_pricelist + └── product_pricelist_total_margin + └── product_price_category + └── product_main_seller + └── product_price_category_supplier + └── product_price_category + +account_invoice_triple_discount_readonly + └── account_invoice_triple_discount + └── purchase_triple_discount +``` + +## Desarrollo + +### Instalación / actualización de un addon + +```bash +docker-compose exec -T odoo odoo -d odoo -u --stop-after-init +``` + +### Tests + +```bash +docker-compose exec -T odoo odoo -d odoo --test-enable --stop-after-init -u +``` + +### Linters + +```bash +# Python +black . && isort . && flake8 . && pylint --load-plugins=pylint_odoo / + +# JS +npx eslint /static/src/ +``` + +Ver [docs/LINTERS_README.md](docs/LINTERS_README.md) para configuración completa. + +### Traducciones + +Ver [docs/TRANSLATIONS.md](docs/TRANSLATIONS.md). + +## Documentación técnica + +Ver carpeta [docs/](docs/) para documentación transversal (instalación, lazy loading, QWeb, etc.). diff --git a/docs/README.md b/docs/README.md index 9faa4dc..cc60c1f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,57 +1,28 @@ # Documentación Técnica -Esta carpeta contiene documentación técnica y de referencia del proyecto. +Documentación transversal del proyecto (no específica de un addon individual). -## Contenido +## Configuración y desarrollo -### � Cambios Recientes +- [LINTERS_README.md](LINTERS_README.md) — Configuración de herramientas de calidad: black, isort, flake8, pylint, eslint +- [TRANSLATIONS.md](TRANSLATIONS.md) — Guía completa del sistema de traducciones (i18n/l10n) +- [QWEB_BEST_PRACTICES.md](QWEB_BEST_PRACTICES.md) — Buenas prácticas para templates QWeb (evitar errores comunes) +- [OCA_DOCUMENTATION.md](OCA_DOCUMENTATION.md) — Notas sobre integración con el ecosistema OCA -- **[RECENT_CHANGES.md](RECENT_CHANGES.md)** - 🆕 Resumen de todos los cambios recientes (Feb 2026) +## Instalación -### �🚀 Performance & Features (Nuevas) +- [INSTALACION_COMPLETA.md](INSTALACION_COMPLETA.md) — Proceso completo de instalación con Docker +- [RESUMEN_INSTALACION.md](RESUMEN_INSTALACION.md) — Resumen ejecutivo de instalación -- **[LAZY_LOADING_QUICK_START.md](LAZY_LOADING_QUICK_START.md)** - ⚡ Guía rápida (5 min) si solo necesitas lo esencial -- **[LAZY_LOADING_DOCS_INDEX.md](LAZY_LOADING_DOCS_INDEX.md)** - Índice centralizado de documentación de lazy loading (v18.0.1.3.0) -- **[LAZY_LOADING.md](LAZY_LOADING.md)** - Documentación técnica completa de lazy loading en website_sale_aplicoop -- **[UPGRADE_INSTRUCTIONS_v18.0.1.3.0.md](UPGRADE_INSTRUCTIONS_v18.0.1.3.0.md)** - Guía de actualización e instalación de lazy loading +## website_sale_aplicoop -### Configuración y Desarrollo +- [LAZY_LOADING.md](LAZY_LOADING.md) — Documentación técnica completa de paginación de productos +- [UPGRADE_INSTRUCTIONS_v18.0.1.3.0.md](UPGRADE_INSTRUCTIONS_v18.0.1.3.0.md) — Instrucciones de upgrade para la versión con lazy loading +- [CORRECCION_PRECIOS_IVA.md](CORRECCION_PRECIOS_IVA.md) — Correcciones de precios con IVA +- [TEST_MANUAL.md](TEST_MANUAL.md) — Guía de pruebas manuales -- **[LINTERS_README.md](LINTERS_README.md)** - Guía de herramientas de calidad de código (black, isort, flake8, pylint) -- **[TRANSLATIONS.md](TRANSLATIONS.md)** - Guía completa del sistema de traducciones (IMPORTANTE) -- **[INSTALACION_COMPLETA.md](INSTALACION_COMPLETA.md)** - Documentación detallada del proceso de instalación -- **[RESUMEN_INSTALACION.md](RESUMEN_INSTALACION.md)** - Resumen ejecutivo de la instalación +## Documentación principal -### Resolución de Problemas - -- **[FINAL_SOLUTION_SUMMARY.md](FINAL_SOLUTION_SUMMARY.md)** - Solución definitiva para errores de templates QWeb en website_sale_aplicoop -- **[FIX_TEMPLATE_ERROR_SUMMARY.md](FIX_TEMPLATE_ERROR_SUMMARY.md)** - Resumen de correcciones de templates -- **[QWEB_BEST_PRACTICES.md](QWEB_BEST_PRACTICES.md)** - Mejores prácticas para templates QWeb (CRÍTICO) -- **[TEMPLATE_FIX_INDEX.md](TEMPLATE_FIX_INDEX.md)** - Índice de documentación de fixes de templates -- **[CORRECCION_PRECIOS_IVA.md](CORRECCION_PRECIOS_IVA.md)** - Correcciones relacionadas con precios e IVA -- **[TEST_MANUAL.md](TEST_MANUAL.md)** - Guía de tests manuales - -## Documentación Principal - -Para información general del proyecto y cómo empezar, ver: - -- **[README.md](../README.md)** - Documentación principal del repositorio -- **[.github/copilot-instructions.md](../.github/copilot-instructions.md)** - Instrucciones para GitHub Copilot - -## Documentación por Addon - -Cada addon tiene su propio README: - -### Addons Custom -- [account_invoice_triple_discount_readonly](../account_invoice_triple_discount_readonly/README.md) -- [product_price_category_supplier](../product_price_category_supplier/README.md) -- [product_sale_price_from_pricelist](../product_sale_price_from_pricelist/README.md) -- [website_sale_aplicoop](../website_sale_aplicoop/README.md) - -### Addons OCA Modificados -- [account_invoice_triple_discount](../account_invoice_triple_discount/README.rst) -- [purchase_triple_discount](../purchase_triple_discount/README.rst) -- [product_origin](../product_origin/README.md) -- [product_get_price_helper](../product_get_price_helper/README.md) -- [product_main_seller](../product_main_seller/README.md) -- [product_price_category](../product_price_category/README.rst) +- [README.md](../README.md) — Tabla de todos los addons con versiones y descripción +- [website_sale_aplicoop/README_DEV.md](../website_sale_aplicoop/README_DEV.md) — Documentación técnica del addon principal +- [website_sale_aplicoop/CHANGELOG.md](../website_sale_aplicoop/CHANGELOG.md) — Historial de cambios completo diff --git a/website_sale_aplicoop/CHANGELOG.md b/website_sale_aplicoop/CHANGELOG.md index d4d5f44..1eaa993 100644 --- a/website_sale_aplicoop/CHANGELOG.md +++ b/website_sale_aplicoop/CHANGELOG.md @@ -1,5 +1,70 @@ # Changelog - Website Sale Aplicoop +## [18.0.1.9.0] - 2026-05-20 + +### Added + +- **Category sequence**: New `sequence` field on `product.category` for controlling product display order on the web shop. Migration adds the column with default 10. +- **Stock availability check on history orders**: When loading a historical order, products are validated against current stock (`virtual_available`). Out-of-stock items are flagged before adding to cart. + +### Changed + +- **Cart disabled / redirected to /eskaera**: Standard `website_sale` cart is fully hidden — header cart icon removed, add-to-cart buttons removed from standard shop, `/cart` and `/shop` routes redirect to `/eskaera`. Customers interact exclusively through the group order flow. +- **Product card UI overhaul**: Improved responsive layout, placeholder image for products without photo, better accessibility markup, and professional styling for mobile. +- **Stock check uses `virtual_available`**: Replaces `qty_available` so forecasted quantity (including incoming moves) is considered. + +### Fixed + +- Lint fixes: exception chaining (`raise ... from exc`), unused imports/vars, `disable attribute-string-redundant` annotations. + +--- + +## [18.0.1.8.0] - 2026-04-08 + +### Added + +- **Clear cart button**: New button in the sidebar to empty the current group order cart in one click (`eskaera_clear_cart` route). + +### Changed + +- **Portal access restricted to consumer group**: Portal users can only see group orders belonging to their consumer group. Security rule `rule_group_order_company_read` updated with `user.share` guard. +- **Controller filtering by consumer group**: `eskaera_list` and `eskaera_shop` routes filter orders by the logged-in user's consumer group, not just by company. + +### Fixed + +- Stale cart invalidation: carts linked to closed/cancelled group orders are cleared on next access. +- Home delivery draft flow: fixed state transition for home delivery orders. +- Auto-confirm `sale.order` on cutoff day: fixed off-by-one (`>` vs `>=`) in cutoff guard so orders on the cutoff day are correctly confirmed. +- Pickup dates frozen after cron confirm: cron no longer overwrites pickup dates on already-confirmed orders. +- Cron hardened against missing/invalid group order configurations. +- Cart layout: moved cart sidebar before product grid. +- i18n: added missing ES/EU translations for checkout, cart labels, Save Draft button, and weekday strings. Removed legacy `week_draft` translation keys. + +--- + +## [18.0.1.7.0] - 2026-03-06 + +### Added + +- **Automatic batch picking creation**: After the cutoff cron confirms sale orders, picking batches are automatically created grouped by consumer group and pickup date. +- **Consumer group propagation**: `consumer_group_id` is now propagated directly from the `group.order` to linked `sale.order` records, eliminating manual assignment. +- **Out-of-stock blocking**: Add-to-cart button is hard-disabled for out-of-stock products. `allow_out_of_stock_order` flag on product is respected. + +### Changed + +- **Cron auto-confirm sale orders**: Daily cron (`_cron_confirm_group_orders`) now confirms linked sale orders on the cutoff date instead of requiring manual action. +- **Order card meta extracted**: Order card metadata (dates, state badge) moved to a reusable `_eskaera_order_card_meta` template for cleaner rendering. +- Delivery toggle (reparto/envío a domicilio) wired directly from the cart sidebar. +- Pricing alignment: theoretical price and displayed price reconciled for orders with home delivery. + +### Fixed + +- Fixed broken `aplicoopShop` → `groupOrderShop` JS class reference. +- Ensured add-to-cart event listeners are re-attached after infinite scroll loads new products. +- i18n: translated weekday names (ES/EU). + +--- + ## [18.0.1.6.0] - 2026-02-22 ### Added diff --git a/website_sale_aplicoop/README_DEV.md b/website_sale_aplicoop/README_DEV.md index 101a5e1..650289c 100644 --- a/website_sale_aplicoop/README_DEV.md +++ b/website_sale_aplicoop/README_DEV.md @@ -1,336 +1,196 @@ # Website Sale - Aplicoop -**Author:** Criptomart -**License:** AGPL-3 -**Maintainer:** Criptomart SL +**Versión:** 18.0.1.9.0 | **Licencia:** AGPL-3 | **Autor:** Criptomart SL -## Summary +Sistema de pedidos colaborativos para grupos de consumo. Reemplaza el legacy Aplicoop con una solución moderna integrada en Odoo 18. -Modern replacement for legacy Aplicoop - Cooperative group ordering system with separate carts and multi-language support. +## Resumen de funcionalidades -## Description +- Gestión completa de órdenes de grupo (draft → confirmed → collected → invoiced → completed) +- Carrito separado por grupo de consumo; tienda estándar de `website_sale` deshabilitada +- Control de catálogo por listas de inclusión (proveedores, categorías, productos) y exclusión (blacklists) +- Cron diario de auto-confirmación + creación automática de lotes de picking +- Paginación de productos (lazy loading) para cargas rápidas +- Soporte multilingüe: ES, EU, PT, GL, CA, FR, IT +- Restricción de acceso portal por grupo de consumo -Website Sale Aplicoop provides a complete group ordering system designed for cooperative consumption groups. It replaces the legacy Aplicoop system with a modern, scalable solution where customers organize collaborative orders, manage group memberships, and handle separate shopping carts. Perfect for food cooperatives, buying groups, and collective purchasing organizations. +## Modelos -## Features +### `group.order` -- ✅ Group order management with full lifecycle (draft → confirmed → completed) -- ✅ Separate shopping carts per order group -- ✅ Group membership tracking with active/inactive states -- ✅ Order collection and cutoff dates with validation -- ✅ Pickup day configuration and fulfillment tracking -- ✅ Multi-language support (ES, PT, GL, CA, EU, FR, IT) -- ✅ Partner location management for group coordination -- ✅ Product ecosystem integration (ribbons, pricing, margins) -- ✅ Order state transitions with email notifications -- ✅ Delivery tracking and group order fulfillment -- ✅ Financial tracking per group member -- ✅ Automatic translation of UI elements -- ✅ **Lazy Loading**: Configurable product pagination for fast page loads +Orden de grupo central. Contiene toda la lógica de ciclo de vida. -## Installation +**Campos principales:** -1. Place addon in Odoo addons folder: `/addons/website_sale_aplicoop` -2. Activate developer mode -3. Go to **Apps** → **Update Apps List** -4. Search for "Website Sale - Aplicoop" -5. Click **Install** +| Campo | Tipo | Descripción | +| ----- | ---- | ----------- | +| `name` | Char | Identificador de la orden | +| `consumer_group_id` | Many2one → `res.partner` | Grupo de consumo | +| `state` | Selection | draft / confirmed / collected / invoiced / completed / cancelled | +| `cutoff_date` | Datetime | Hasta cuándo se pueden añadir productos | +| `pickup_date` | Date | Día de recogida para los socios | +| `delivery_date` | Date | Fecha de entrega (almacenada, calculada por cron) | +| `product_ids` | Many2many | Productos incluidos directamente | +| `category_ids` | Many2many | Categorías incluidas (y sus subcategorías) | +| `supplier_ids` | Many2many | Proveedores incluidos (por `main_seller_id`) | +| `excluded_product_ids` | Many2many | Blacklist de productos | +| `excluded_supplier_ids` | Many2many | Blacklist de proveedores | +| `excluded_category_ids` | Many2many | Blacklist de categorías (recursiva) | +| `allow_home_delivery` | Boolean | Permite envío a domicilio además de recogida | -### Requirements +**Métodos clave:** -- Odoo 18.0+ -- Website module -- Sale module -- Product module -- Account module +- `_get_products_for_group_order()` — catálogo efectivo aplicando whitelist + blacklist +- `_get_products_paginated(page, per_page)` — paginación para lazy loading +- `_cron_confirm_group_orders()` — auto-confirma órdenes pasado el cutoff y crea lotes de picking +- `_cron_update_dates()` — recalcula fechas de entrega/recogida diariamente -### Dependencies +### `group.order.slot` *(en desarrollo)* -``` -- base -- web -- website -- sale -- product -- account -``` +Franjas horarias de recogida para una orden de grupo. -## Usage +| Campo | Tipo | Descripción | +| ----- | ---- | ----------- | +| `group_order_id` | Many2one | Orden de grupo | +| `weekday` | Selection (0–6) | Día de la semana (0 = lunes) | +| `start_hour` / `end_hour` | Float | Horario en formato decimal (9.5 = 09:30) | +| `sequence` | Integer | Orden de visualización | -### Administrator Setup - -#### 1. Create a Group Order - -1. Go to **Website Sale** → **Group Orders** (or **Coops** → **Órdenes de Grupo**) -2. Click **Create** -3. Fill in: - - **Name**: e.g., "Weekly Cooperative Order #5" - - **Group**: Select the cooperative group - - **Collection Date**: When orders will be collected - - **Cutoff Date**: Last moment to add items - - **Pickup Date**: When group members collect their orders -4. Save - -#### 2. Configure Pickup Dates - -1. Go to **Settings** → **Website** → **Shop Settings** -2. Configure **Pickup Days**: Define which days are available -3. Set **Group Settings**: Default locations, delivery partners - -#### 3. Add Group Members - -1. Open a Group Order -2. In the **Members** tab, click **Add** -3. Select partner(s) -4. Set active/inactive status -5. Save - -### Customer Experience - -#### For Group Members on Website - -1. **Browse Products**: Members see products with eco-ribbons, pricing, margin info -2. **Add to Cart**: Select items (cart is separate per group order) -3. **Review Cart**: See order summary before cutoff date -4. **Submit Order**: Confirm before cutoff time -5. **Receive Notification**: Get email with pickup details -6. **Pickup**: Collect order on designated pickup date - -#### Order Workflow - -``` -Draft → Confirmed → Collected → Invoiced → Completed - ↓ -Cancelled (if member opts out) -``` - -## Configuration - -### Basic Configuration - -**Required:** -1. Create group orders with collection/cutoff/pickup dates -2. Assign group members to orders -3. Set available pickup dates - -**Optional:** -1. Configure custom email templates -2. Set up product-specific group restrictions -3. Customize group order report - -### Multi-Language Setup - -The addon automatically translates: -- Interface elements -- Form labels -- Report headers -- Email notifications - -**Supported Languages:** ES, PT, GL, CA, EU, FR, IT - -**Translations are managed in:** -- `i18n/[language].po` files -- Auto-extracted from templates -- See `docs/TRANSLATION_CONVENTIONS.md` for translation patterns - -### Website Customization - -Edit templates in: `views/website_templates.xml` - -Key customizable sections: -- `eskaera_page`: Main group order display -- `eskaera_details`: Order details view -- `member_cart`: Individual member cart interface - -## Technical Details - -### Core Models - -**`group.order`** (Main group order) -- `name` (Char): Order identifier -- `group_id` (Many2one): Link to group -- `state` (Selection): draft/confirmed/collected/invoiced/completed/cancelled -- `collection_date` (Date): When group collects -- `cutoff_date` (Datetime): Last moment to order -- `pickup_date` (Date): Member pickup day -- `line_ids` (One2many): Order lines -- `member_ids` (One2many): Group members -- `active` (Boolean): Soft delete - -**`group.order.line`** (Order items per member) -- `order_id` (Many2one): Parent group order -- `member_id` (Many2one): Which group member -- `product_id` (Many2one): Ordered product -- `quantity` (Float): Amount ordered -- `unit_price` (Float): Price per unit -- `subtotal` (Float): Computed (qty × price) - -**`group.partner`** (Group member tracking) -- `partner_id` (Many2one): Odoo partner -- `group_id` (Many2one): Which group -- `active` (Boolean): Active member status -- `role` (Selection): admin/member - -### Extended Models +### Extensiones de modelos core **`product.template`** -- `group_order_allowed` (Boolean): Can be in group orders -- `eco_ribbon_id` (Many2one): Environmental ribbon -- `margin_type_id` (Many2one): Pricing margin + +- `main_seller_id` — proveedor principal (de `product_main_seller`) +- `sequence` en `product.category` — orden de visualización en la tienda web **`sale.order`** -- `group_order_id` (Many2one): Parent group order (if applicable) -### Views & Templates +- `group_order_id` — enlace a la orden de grupo +- `consumer_group_id` — propagado desde `group_order_id` +- `pickup_slot_label` — etiqueta legible de la franja de recogida -**Backend Views:** -- `group.order` list/form views -- `group.order.line` inline form -- `group.partner` configuration view +**`stock.picking`** -**Frontend Templates:** -- `eskaera_page`: Main group order display -- `eskaera_details`: Order details/summary -- `member_cart`: Individual cart interface -- `group_members`: Member list view +- Extensión para agrupación por grupo de consumo en lotes de picking -## Integration Points +## Controladores -This addon integrates with: +Todos los endpoints viven bajo `/eskaera/`: -- **Product Modules** - - `product_eco_ribbon` - Eco-friendly product indicators - - `product_margin_type` - Dynamic product pricing - - `product_pricing_margins` - Cost management +| Ruta | Descripción | +| ---- | ----------- | +| `GET /eskaera` | Lista de órdenes de grupo activas del usuario | +| `GET /eskaera/` | Tienda de la orden (con lazy loading) | +| `GET /eskaera//load-page?page=N` | Carga AJAX de página de productos | +| `POST /eskaera//add` | Añadir producto al carrito | +| `POST /eskaera//confirm` | Confirmar carrito (sale.order en draft) | +| `POST /eskaera/clear-cart` | Limpiar carrito actual | -- **Website/E-commerce** - - `elika_bilbo_website_theme` - Custom website theme - - `website_sale` - Core shop functionality - - `website_legal_es` - Legal compliance (Spanish) +Las rutas `/cart` y `/shop` de `website_sale` están redirigidas a `/eskaera`. -- **Sales/Accounting** - - `sale` - Sales order generation - - `account` - Invoicing +**Seguridad portal:** los usuarios solo ven órdenes de su `consumer_group_id`. La regla `rule_group_order_company_read` incluye guardia `user.share`. -## Testing +## Templates QWeb -Run tests with: +| Template | Descripción | +| -------- | ----------- | +| `eskaera_list` | Lista de órdenes activas | +| `eskaera_shop` | Página de la tienda (incluye `eskaera_shop_products`) | +| `eskaera_shop_products` | Grid de productos (reutilizable por lazy loading + initial render) | +| `eskaera_cart` | Sidebar del carrito | +| `eskaera_checkout` | Confirmación del pedido | +| `load_from_history` | Cargar productos de una orden histórica | -```bash -cd /home/snt/Documentos/lab/odoo/kidekoop/odoo-addons -python -m pytest website_sale_aplicoop/tests/ -v +## JavaScript (`website_sale.js`) + +Clase `GroupOrderShop` (extiende `publicWidget.Widget`): + +- `_attachEventListeners()` — inicializa todos los listeners +- `_attachLoadMoreListener()` — botón "Cargar más" para lazy loading (AJAX) +- `_onAddToCart()` — añadir al carrito con feedback visual +- `_onClearCart()` — limpiar carrito +- `_onDeliveryToggle()` — toggle envío a domicilio / recogida + +## Control del catálogo + +La lógica en `_get_products_for_group_order()` aplica en este orden: + +1. **Whitelist**: unión de `product_ids` + productos de `category_ids` (recursivo) + productos de `supplier_ids` (por `main_seller_id`) +2. **Blacklist**: se restan `excluded_product_ids`, productos con `main_seller_id` en `excluded_supplier_ids`, y productos en `excluded_category_ids` (recursivo) +3. La blacklist tiene prioridad absoluta sobre cualquier fuente de inclusión + +## Lazy loading + +Configurable desde **Ajustes > Website > Shop**: + +- `website_sale_aplicoop.lazy_loading_enabled` (default: `True`) +- `website_sale_aplicoop.products_per_page` (default: `20`) + +La página inicial renderiza la primera página server-side. El botón "Cargar más" hace peticiones AJAX al endpoint `/load-page` que devuelve HTML parcial con el template `eskaera_shop_products`. + +## Cron jobs + +| Cron | Frecuencia | Acción | +| ---- | ---------- | ------ | +| `_cron_confirm_group_orders` | Diario (medianoche) | Confirma sale.orders pasado el cutoff; crea lotes de picking agrupados por consumer_group + pickup_date | +| `_cron_update_dates` | Diario | Recalcula `delivery_date` y `pickup_date` en órdenes activas | + +## Dependencias + +```text +website_sale_aplicoop + ├── website_sale (Odoo core) + ├── sale (Odoo core) + ├── product_main_seller (OCA) + ├── product_sale_price_from_pricelist (custom) + │ └── product_pricelist_total_margin (custom) + │ └── product_price_category (OCA) + └── stock_picking_batch_custom (custom) ``` -**Test Coverage:** -- ✅ Group order creation/deletion -- ✅ Member management -- ✅ Order line addition/removal -- ✅ State transitions -- ✅ Cutoff date validation -- ✅ Pickup date assignment -- ✅ Translation extraction (7 languages) -- ✅ Website template rendering +## Instalación y actualización -## Known Limitations +```bash +docker-compose exec -T odoo odoo -d odoo -u website_sale_aplicoop --stop-after-init +``` -- Group orders are company-specific -- Cannot change pickup date after order is confirmed -- Members cannot modify orders after cutoff -- Automatic invoicing must be triggered manually +Para migraciones con cambios de esquema (e.g., nuevas columnas): -## Changelog +```bash +docker-compose exec -T odoo odoo -d odoo --update website_sale_aplicoop --stop-after-init +``` -### 18.0.1.3.1 (2026-02-18) -- **Date Calculation Fixes (Critical)**: - - Fixed `_compute_cutoff_date` logic: Changed `days_ahead <= 0` to `days_ahead < 0` to allow cutoff_date to be the same day as today - - Enabled `store=True` for `delivery_date` field to persist calculated values and enable database filtering - - Added constraint `_check_cutoff_before_pickup` to validate that pickup_day >= cutoff_day in weekly orders - - Added `@api.onchange` methods for immediate UI feedback when changing cutoff_day or pickup_day -- **Automatic Date Updates**: - - Created daily cron job `_cron_update_dates` to automatically recalculate dates for active orders - - Ensures computed dates stay current as time passes -- **UI Improvements**: - - Added "Calculated Dates" section in form view showing readonly cutoff_date, pickup_date, and delivery_date - - Improved visibility of automatically calculated dates for administrators -- **Testing**: - - Added 6 regression tests with `@tagged('post_install', 'date_calculations')`: - - `test_cutoff_same_day_as_today_bug_fix`: Validates cutoff can be today - - `test_delivery_date_stored_correctly`: Ensures delivery_date persistence - - `test_constraint_cutoff_before_pickup_invalid`: Tests invalid configurations are rejected - - `test_constraint_cutoff_before_pickup_valid`: Tests valid configurations work - - `test_all_weekday_combinations_consistency`: Tests all 49 date combinations - - `test_cron_update_dates_executes`: Validates cron job execution -- **Documentation**: - - Documented that this is a more robust fix than v18.0.1.2.0, addressing edge cases in date calculations +## Tests -### 18.0.1.3.0 (2026-02-16) -- **Performance**: Lazy loading of products for faster page loads - - Configurable product pagination (default: 20 per page) - - New Settings: Enable Lazy Loading, Products Per Page - - Page 1: 500-800ms load time (vs 10-20s before) - - Subsequent pages: 200-400ms via AJAX - - New endpoint: `GET /eskaera//load-page?page=N` -- **Templates**: Split product rendering into reusable template - - New: `eskaera_shop_products` template - - Backend: `_get_products_paginated()` in group_order model -- **JavaScript**: Load More button with event handling - - `_attachLoadMoreListener()` for AJAX pagination - - Spinner during load (button disabled + "Loading..." text) - - Re-attach event listeners for new products - - Auto-hide button when no more products -- Documentation: Added `docs/LAZY_LOADING.md` with full technical details +```bash +docker-compose exec -T odoo odoo -d odoo --test-enable --stop-after-init -u website_sale_aplicoop +``` -### 18.0.1.2.0 (2026-02-02) -- UI Improvements: - - Increased cart text size (2x) for better readability - - Increased cart icon sizes (1.2rem) with proper button proportions - - Enlarged "Save as Draft" button in checkout (2x text and icon) -- Date Calculation Fixes: - - Fixed pickup_date calculation (was adding extra week incorrectly) - - Simplified pickup_date computation logic -- Display Enhancements: - - Added delivery_date display to all order pages - - Improved date field visibility on order cards and product pages +Los tests están en `tests/`: -### 18.0.1.0.0 (2024-12-20) -- Initial release -- Core group order functionality -- Multi-language translation support -- Complete member management -- Order state machine implementation +- `test_group_order.py` — ciclo de vida básico, fechas, cron +- `test_product_discovery.py` — whitelist/blacklist (productos, proveedores, categorías) +- `test_confirm_eskaera.py` — integración: confirmación de carrito y generación de sale.order -### 18.0.1.1.0 (2025-01-10) -- Fixed translation extraction for "Pickup day" and "Cutoff day" -- Improved QWeb template for better performance -- Added comprehensive documentation +## Traducciones -## Support +```bash +# Exportar .pot +docker-compose exec -T odoo odoo -d odoo \ + -i website_sale_aplicoop \ + --i18n-export=/tmp/website_sale_aplicoop.pot \ + --stop-after-init -For issues, feature requests, or contributions: -- **Repository**: https://git.criptomart.net/KideKoop/kidekoop/odoo-addons -- **Main Documentation**: `/docs/` folder (transversal docs) -- **Addon Documentation**: This README + `/docs/ODOO18_TRANSLATIONS_LEARNINGS.md` -- **Maintainer**: Criptomart SL +# Actualizar .po existentes +cd website_sale_aplicoop/i18n +for lang in es eu; do + msgmerge -U ${lang}.po ../website_sale_aplicoop.pot +done +``` -## Documentation References +Ver [docs/TRANSLATIONS.md](../docs/TRANSLATIONS.md) para convenciones. -- **Translation Patterns**: See `docs/TRANSLATION_CONVENTIONS.md` -- **Translation Examples**: See `docs/TRANSLATION_EXAMPLES.md` -- **Odoo 18 Translation Guide**: See `docs/ODOO18_TRANSLATIONS_LEARNINGS.md` -- **Project Architecture**: See `docs/ARCHITECTURE.md` +## Repositorio -## Related Modules - -- `product_eco_ribbon` - Product environmental classification -- `product_margin_type` - Dynamic product pricing -- `product_pricing_margins` - Complete pricing system -- `elika_bilbo_website_theme` - Custom website theme -- `website_legal_es` - Legal compliance - ---- - -**Version:** 18.0.1.3.1 -**Odoo:** 18.0+ -**License:** AGPL-3 -**Maintainer:** Criptomart -**Repository:** https://git.criptomart.net/criptomart/addons-cm +- Repo: +- Changelog: [CHANGELOG.md](CHANGELOG.md) From eb81e7db6a160214cad9b7847770a96418e648ef Mon Sep 17 00:00:00 2001 From: GitHub Copilot Date: Wed, 20 May 2026 17:02:33 +0200 Subject: [PATCH 2/3] =?UTF-8?q?[IMP]=20website=5Fsale=5Faplicoop:=20ajusta?= =?UTF-8?q?r=20CSS=20tarjeta=20producto=20=E2=80=94=20placeholder=20y=20co?= =?UTF-8?q?mpresi=C3=B3n=20m=C3=B3vil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - product-img-cover: max-height → height fija para que placeholder y imagen real ocupen exactamente el mismo bloque (120px/90px/60px según breakpoint) - product-img-placeholder: reemplaza SVG inline por flex centrado, más limpio - Reducir padding/márgenes generales en card-body, title, supplier, tags y precio - Dos breakpoints responsivos: ≤768px (tablet, imagen 90px) y ≤480px (móvil, imagen 60px, fuentes y márgenes mínimos) Co-Authored-By: Claude Sonnet 4.6 --- .../src/css/components/product-card.css | 99 +++++++++++-------- 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/website_sale_aplicoop/static/src/css/components/product-card.css b/website_sale_aplicoop/static/src/css/components/product-card.css index fd36a45..d3d6671 100644 --- a/website_sale_aplicoop/static/src/css/components/product-card.css +++ b/website_sale_aplicoop/static/src/css/components/product-card.css @@ -36,13 +36,14 @@ } .product-img-cover { - max-height: 120px; + height: 120px; width: 100%; object-fit: cover; border-radius: 8px 8px 0 0; box-shadow: 0 2px 8px rgba(40, 39, 39, 0.09); background: #f3f3f3; display: block; + flex-shrink: 0; } .product-card .card-body { @@ -50,7 +51,7 @@ flex-direction: column; height: 100%; flex-grow: 1; - padding: 0.6rem 0.7rem 0.7rem 0.7rem; + padding: 0.4rem 0.55rem 0.5rem; position: relative; background: linear-gradient(135deg, rgba(0, 123, 255, 0.07) 0%, rgba(0, 123, 255, 0.04) 100%); transition: background 0.3s; @@ -67,13 +68,13 @@ .product-card .card-title { flex-grow: 1; - margin: 0 0 0.15rem 0; + margin: 0 0 0.1rem 0; min-height: auto; display: block; word-wrap: break-word; overflow-wrap: break-word; - font-size: 1.08rem !important; - line-height: 1.1; + font-size: 1rem !important; + line-height: 1.15; text-align: center; font-weight: 600; color: #1a202c; @@ -81,9 +82,9 @@ } .product-card .card-text { - margin-bottom: 0.12rem; + margin-bottom: 0.08rem; text-align: center; - font-size: 1rem; + font-size: 0.95rem; } .product-card .card-text strong { @@ -97,19 +98,19 @@ text-align: center; color: #4a5568; font-weight: 400; - margin-bottom: 0.12rem; - font-size: 0.92rem !important; + margin-bottom: 0.08rem; + font-size: 0.85rem !important; } .product-tags { text-align: center; display: flex; flex-wrap: wrap; - gap: 0.18rem; + gap: 0.12rem; justify-content: center; font-weight: 400; - font-size: 1.1rem !important; - margin: 0; + font-size: 1rem !important; + margin: 0 0 0.08rem 0; padding: 0; } @@ -129,15 +130,15 @@ .card-body p.card-text { text-align: center; - margin-bottom: 0.6rem; - min-height: 1.7rem; + margin-bottom: 0.35rem; + min-height: 1.5rem; display: flex; align-items: center; justify-content: center; background-color: var(--primary-color, #007bff); color: #fff; border-radius: 0.18rem; - font-size: 1.05rem; + font-size: 0.98rem; } .card-body p.card-text strong { @@ -160,53 +161,73 @@ .product-img-placeholder { height: 120px; width: 100%; - object-fit: cover; border-radius: 8px 8px 0 0; - background: #f3f3f3 - url('data:image/svg+xml;utf8,Sin imagen') - no-repeat center center; - display: block; + background: #f3f3f3; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + color: #ccc; } -/* Responsive: mejorar altura y espaciado en móvil */ -@media (max-width: 600px) { +/* Responsive: tablet (≤768px) — compresión moderada */ +@media (max-width: 768px) { + .product-card .product-image, + .product-img-cover, + .product-img-fixed, + .product-img-placeholder { + height: 90px; + } + .product-card .card-body { + padding: 0.35rem 0.45rem 0.4rem; + } + .card-body p.card-text { + margin-bottom: 0.25rem; + min-height: 1.4rem; + } +} + +/* Responsive: móvil (≤480px) — compresión máxima */ +@media (max-width: 480px) { .product-card { - padding: 0.25rem; - border-radius: 8px; + padding: 0.15rem; + border-radius: 6px; } .product-card .product-image, .product-img-cover, .product-img-fixed, .product-img-placeholder { - height: 70px; - max-height: 70px; - min-height: 70px; - border-radius: 6px 6px 0 0; + height: 60px; + border-radius: 5px 5px 0 0; } .product-card .card-body { - padding: 0.4rem 0.4rem 0.5rem 0.4rem; + padding: 0.25rem 0.3rem 0.3rem; } .product-card .card-title { - font-size: 0.98rem !important; - margin-bottom: 0.08rem; + font-size: 0.82rem !important; + line-height: 1.15; + margin-bottom: 0.05rem; } .product-card .card-text { - font-size: 0.92rem; + font-size: 0.8rem; } .badge-km { - font-size: 0.58rem !important; - padding: 0.13rem 0.22rem !important; + font-size: 0.55rem !important; + padding: 0.1rem 0.18rem !important; } .product-tags { - font-size: 0.95rem !important; + font-size: 0.82rem !important; + gap: 0.08rem; + margin-bottom: 0.05rem; } .card-body p.card-text { - min-height: 1.1rem; - font-size: 0.95rem; - margin-bottom: 0.3rem; + min-height: 1rem; + font-size: 0.85rem; + margin-bottom: 0.2rem; } .product-card .product-supplier { - font-size: 0.82rem !important; + font-size: 0.72rem !important; + margin-bottom: 0.05rem; } } From b14a6f84ed0ffe67e46aa4f266e2718c61d4374d Mon Sep 17 00:00:00 2001 From: GitHub Copilot Date: Wed, 20 May 2026 17:06:38 +0200 Subject: [PATCH 3/3] [IMP] website_sale_aplicoop: mostrar franjas de recogida en formulario group.order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Añadir reglas de acceso para group.order.slot en ir.model.access.csv - Añadir pestaña "Pickup Slots" en el formulario de group.order con lista editable (handle de secuencia, día, etiqueta, hora inicio/fin, activo) - Corregir valores del campo weekday: de dígitos numéricos a nombres de día (Monday...Sunday) para mejor usabilidad Co-Authored-By: Claude Sonnet 4.6 --- website_sale_aplicoop/models/group_order_slot.py | 10 +++++++++- website_sale_aplicoop/security/ir.model.access.csv | 2 ++ website_sale_aplicoop/views/group_order_views.xml | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/website_sale_aplicoop/models/group_order_slot.py b/website_sale_aplicoop/models/group_order_slot.py index b261aaa..e9f736b 100644 --- a/website_sale_aplicoop/models/group_order_slot.py +++ b/website_sale_aplicoop/models/group_order_slot.py @@ -23,7 +23,15 @@ class GroupOrderSlot(models.Model): ) weekday = fields.Selection( - [(str(i), str(i)) for i in range(7)], + [ + ("0", "Monday"), + ("1", "Tuesday"), + ("2", "Wednesday"), + ("3", "Thursday"), + ("4", "Friday"), + ("5", "Saturday"), + ("6", "Sunday"), + ], string="Weekday", required=True, help="Day of week for this slot (0=Monday)", diff --git a/website_sale_aplicoop/security/ir.model.access.csv b/website_sale_aplicoop/security/ir.model.access.csv index 10027e4..8879454 100644 --- a/website_sale_aplicoop/security/ir.model.access.csv +++ b/website_sale_aplicoop/security/ir.model.access.csv @@ -4,3 +4,5 @@ access_group_order_user,group.order user,model_group_order,website_sale_aplicoop access_group_order_manager,group.order manager,model_group_order,website_sale_aplicoop.group_group_order_manager,1,1,1,1 access_group_order_portal,group.order portal,model_group_order,base.group_portal,1,0,0,0 access_product_supplierinfo_portal,product.supplierinfo portal,product.model_product_supplierinfo,base.group_portal,1,0,0,0 +access_group_order_slot_base,group.order.slot base,model_group_order_slot,,1,1,1,0 +access_group_order_slot_manager,group.order.slot manager,model_group_order_slot,website_sale_aplicoop.group_group_order_manager,1,1,1,1 diff --git a/website_sale_aplicoop/views/group_order_views.xml b/website_sale_aplicoop/views/group_order_views.xml index 17984d2..140a98d 100644 --- a/website_sale_aplicoop/views/group_order_views.xml +++ b/website_sale_aplicoop/views/group_order_views.xml @@ -92,6 +92,20 @@ + + + + + + + + + + + + + +