addons-cm/website_sale_aplicoop/README_DEV.md
GitHub Copilot a4410b9b9e [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>
2026-05-20 16:27:17 +02:00

7.5 KiB
Raw Blame History

Website Sale - Aplicoop

Versión: 18.0.1.9.0 | Licencia: AGPL-3 | Autor: Criptomart SL

Sistema de pedidos colaborativos para grupos de consumo. Reemplaza el legacy Aplicoop con una solución moderna integrada en Odoo 18.

Resumen de funcionalidades

  • 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

Modelos

group.order

Orden de grupo central. Contiene toda la lógica de ciclo de vida.

Campos principales:

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

Métodos clave:

  • _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

group.order.slot (en desarrollo)

Franjas horarias de recogida para una orden de grupo.

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

Extensiones de modelos core

product.template

  • 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 — enlace a la orden de grupo
  • consumer_group_id — propagado desde group_order_id
  • pickup_slot_label — etiqueta legible de la franja de recogida

stock.picking

  • Extensión para agrupación por grupo de consumo en lotes de picking

Controladores

Todos los endpoints viven bajo /eskaera/:

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

Las rutas /cart y /shop de website_sale están redirigidas a /eskaera.

Seguridad portal: los usuarios solo ven órdenes de su consumer_group_id. La regla rule_group_order_company_read incluye guardia user.share.

Templates QWeb

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

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

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

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)

Instalación y actualización

docker-compose exec -T odoo odoo -d odoo -u website_sale_aplicoop --stop-after-init

Para migraciones con cambios de esquema (e.g., nuevas columnas):

docker-compose exec -T odoo odoo -d odoo --update website_sale_aplicoop --stop-after-init

Tests

docker-compose exec -T odoo odoo -d odoo --test-enable --stop-after-init -u website_sale_aplicoop

Los tests están en tests/:

  • 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

Traducciones

# Exportar .pot
docker-compose exec -T odoo odoo -d odoo \
    -i website_sale_aplicoop \
    --i18n-export=/tmp/website_sale_aplicoop.pot \
    --stop-after-init

# Actualizar .po existentes
cd website_sale_aplicoop/i18n
for lang in es eu; do
    msgmerge -U ${lang}.po ../website_sale_aplicoop.pot
done

Ver docs/TRANSLATIONS.md para convenciones.

Repositorio