[DOC] actualizar y sincronizar documentación de todos los addons

- 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 <noreply@anthropic.com>
This commit is contained in:
GitHub Copilot 2026-05-20 16:27:17 +02:00
parent 91cfb9e137
commit a4410b9b9e
4 changed files with 312 additions and 345 deletions

View file

@ -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 (06) | 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/<order_id>` | Tienda de la orden (con lazy loading) |
| `GET /eskaera/<order_id>/load-page?page=N` | Carga AJAX de página de productos |
| `POST /eskaera/<order_id>/add` | Añadir producto al carrito |
| `POST /eskaera/<order_id>/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/<order_id>/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: <https://git.criptomart.net/criptomart/addons-cm>
- Changelog: [CHANGELOG.md](CHANGELOG.md)