addons-cm/website_sale_aplicoop
GitHub Copilot 3e4bd5e5db [ADD] website_sale_aplicoop: restore the test coverage lost with the dead code
The dead-code cleanup dropped 11 test files that were never wired into
tests/__init__.py. Reviewing what they covered turned up real holes, so the
worthwhile ones come back, rewritten against the current schema.

Blacklists were the serious gap: product, supplier and category exclusions
have absolute priority over product discovery and nothing exercised them.
The old file had two separate defects. Its supplier fixtures wrote
`main_seller_id` directly, but product_main_seller computes that field from
`variant_seller_ids`, so the compute reset it to False and the blacklist had
nothing to exclude; they now create real supplierinfo records. Worse, four
whole classes asserted against `group_order.product_ids` -- the m2m *input* --
instead of the discovery result, so they set `category_ids` and then checked a
field they never touched. Those go through `_get_products_for_group_order`
now, and three tests that had no assertions at all got some.

The remaining three failures were test bugs too, all Odoo 17->18 leftovers:

* Date cases assumed `pickup_date` derives from `start_date`. The chain is
  cutoff -> pickup -> delivery, and a recurring order whose start date has
  passed rolls forward to the current cycle, so a 2024 order has no 2024
  pickup. The new file anchors on future dates and finds the next 29 February
  dynamically, with a class documenting the roll-forward itself.
* `/eskaera/labels` is `type="json"`; the old test hit it with a plain GET and
  read the resulting 400 as a bug. It is called over JSON-RPC now, and a test
  pins the 400 so nobody repeats it. Also `uom.uom.categ` -> `uom.category`.
* `price_include` is computed in 18.0, so fixtures must set
  `price_include_override`. On top of that `_get_price` filters taxes by
  company and defaults to `env.company`, not the fixture's, which left the
  tax list empty -- `tax_included` was False for the wrong reason.

Two of the portal tests were passing for the wrong reason as well: the access
guard bounced them to /eskaera, which also answers 200. Membership has to be
set from the member side with `is_group`, and a new test checks the final URL
rather than the status alone. Each fixture that can silently build the wrong
thing now carries a guard test.

Left out on purpose: three files were unimplemented placeholders, and
test_draft_persistence still deserves recovering (see the notes file).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 17:24:31 +02:00
..
controllers [REM] website_sale_aplicoop: remove dead code and orphaned tests 2026-08-16 22:31:13 +02:00
data [IMP] website_sale_aplicoop: render user-defined website_sale ribbon alongside stock ribbon 2026-05-29 18:11:47 +02:00
demo demo files 2026-02-27 13:43:56 +01:00
i18n [REM] website_sale_aplicoop: remove dead code and orphaned tests 2026-08-16 22:31:13 +02:00
migrations [FIX] website_sale_aplicoop: three defects in the group order slug 2026-08-11 22:53:09 +02:00
models [REM] website_sale_aplicoop: remove dead code and orphaned tests 2026-08-16 22:31:13 +02:00
readme [ADD] website_sale_aplicoop: online payment per group order 2026-08-16 21:59:35 +02:00
security [IMP] website_sale_aplicoop: mostrar franjas de recogida en formulario group.order 2026-05-20 17:06:38 +02:00
static [REM] website_sale_aplicoop: remove dead code and orphaned tests 2026-08-16 22:31:13 +02:00
tests [ADD] website_sale_aplicoop: restore the test coverage lost with the dead code 2026-08-17 17:24:31 +02:00
views [REM] website_sale_aplicoop: remove dead code and orphaned tests 2026-08-16 22:31:13 +02:00
.codeclimate.yml [FIX] website_sale_aplicoop: Remove redundant string= attributes and fix OCA linting warnings 2026-02-18 17:54:43 +01:00
.editorconfig Aplicoop desde el repo de kidekoop 2026-02-11 15:32:11 +01:00
.gitignore Aplicoop desde el repo de kidekoop 2026-02-11 15:32:11 +01:00
.pre-commit-config.yaml [FIX] website_sale_aplicoop: Remove redundant string= attributes and fix OCA linting warnings 2026-02-18 17:54:43 +01:00
__init__.py Aplicoop desde el repo de kidekoop 2026-02-11 15:32:11 +01:00
__manifest__.py [REM] website_sale_aplicoop: remove dead code and orphaned tests 2026-08-16 22:31:13 +02:00
CHANGELOG.md [IMP] website_sale_aplicoop: readable slug in the group order URL 2026-08-11 16:49:54 +02:00
COBERTURA_TESTS_PENDIENTE.md [ADD] website_sale_aplicoop: restore the test coverage lost with the dead code 2026-08-17 17:24:31 +02:00
LICENSE.txt Aplicoop desde el repo de kidekoop 2026-02-11 15:32:11 +01:00
README.rst [IMP] website_sale_aplicoop: readable slug in the group order URL 2026-08-11 16:49:54 +02:00
README_DEV.md [ADD] website_sale_disable_cart: extract cart restriction from website_sale_aplicoop 2026-08-06 11:34:59 +02:00
setup.py [FIX] website_sale_aplicoop: Remove redundant string= attributes and fix OCA linting warnings 2026-02-18 17:54:43 +01:00

========================
Website Sale - Aplicoop
========================

.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg
   :target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
   :alt: License: AGPL-3
.. image:: https://img.shields.io/badge/Python-3.9%2B-blue
   :alt: Python: 3.9+
.. image:: https://img.shields.io/badge/Odoo-18.0-blue
   :alt: Odoo: 18.0

**Website Sale - Aplicoop** is a modern Odoo 18 module that replaces the legacy Aplicoop application with a complete solution for managing collaborative consumption group orders (*eskaera* in Basque).

Description
===========

This module replaces the legacy Aplicoop application with a modern, scalable solution for managing collaborative consumption group orders (*eskaera* in Basque) within Odoo's standard website sales framework.

Features
~~~~~~~~

- **Group Order Management**: Create and manage group orders (eskaera) with customizable state transitions (draft → open → closed/cancelled)
- **Weekly Activity Filtering**: Automatically filter active orders for the current week based on start/end dates and time windows
- **Flexible Scheduling**: Support for optional start/end times to define order availability windows within a day
- **Cutoff Day Support**: Define weekly cutoff days for group orders to control when purchases can be made
- **Product Association**: Link products to specific group orders through Many2many relationships
- **Partner Group Association**: Link partners (users) to groups via Many2many relationships for group-based shopping
- **i18n Support**: Full internationalization with translations for 7 languages (Spanish, French, Catalan, Basque, Galician, Italian, Portuguese)
- **OCA Compliant**: AGPL-3.0 licensed, follows OCA standards for documentation, testing, and code structure

Context / Use Cases
===================

Group orders (*eskaera*) are a business model for collaborative consumption where groups of users collectively purchase products within defined time windows. This module was created to replace the legacy Aplicoop application, providing:

**Business Value:**

- Streamlined group purchasing workflows within Odoo's standard sales framework
- Flexible scheduling to accommodate different group shopping patterns (daily, weekly, biweekly, monthly)
- Clear separation between temporary shopping carts and permanent sales orders
- Support for multiple groups with different suppliers, products, and categories

**Use Cases:**

- Cooperative grocery purchasing groups
- Bulk order consolidation for community members
- Time-limited promotional campaigns with group participation
- Multi-location organizations with shared procurement

Usage
=====

Creating a Group Order
~~~~~~~~~~~~~~~~~~~~~~

1. Go to **Website Sale > Group Orders > Create**
2. Fill in the order details:

   - **Order Name**: Descriptive name (e.g., "Weekly Vegetable Order")
   - **Start Date**: When the order opens for shopping (mandatory)
   - **End Date**: When the order closes (optional; leave empty for permanent orders)
   - **Cutoff Day**: Day of week when purchases stop (0=Monday, 6=Sunday) - mandatory
   - **Start Time**: Optional time when order becomes active (0-24 hours)
   - **End Time**: Optional time when order closes (0-24 hours)
   - **Recurrence Period**: How often the order repeats (daily, weekly, biweekly, monthly)
   - **Suppliers**: Link to product suppliers
   - **Categories**: Product categories available in this order
   - **Groups**: Which user groups can participate

3. Click **Save** and transition the order to **Open** state to allow shopping

Shopping for a Group Order
~~~~~~~~~~~~~~~~~~~~~~~~~~~

1. Navigate to the website storefront at ``/eskaera`` (group orders page)
2. View active group orders for your participating groups
3. Select an order to view available products
4. Add products to your cart (separate cart per order)
5. At checkout, confirm your order to convert items to a sales order draft
6. Proceed through standard Odoo checkout workflow

Configuration
~~~~~~~~~~~~~~

**Managing Groups**

1. Go to **Contacts > Groups** (res.partner with is_group=True)
2. Create groups for user communities
3. Add partners/users to groups via the **Members** tab

**Managing Products**

1. Products are linked to group orders via the **Group Orders** field in product settings
2. Set pricing and availability per group order
3. Assign products to categories used in group orders

**Public URLs**

1. Each group order is published under a readable slug: ``/eskaera/<slug>``
2. The slug is generated from the order name and can be edited on the form (empty it to regenerate it)
3. Links to ``/eskaera/<id>`` still work and redirect to the slug URL
4. The ``/eskaera`` prefix can be renamed per website (e.g. ``/escolas``) with a **308 Redirect / Rewrite** rule in Website > Configuration > Redirects — see ``readme/CONFIGURE.rst``

**Date & Time Validation**

- ``start_date`` must be ≤ ``end_date`` (when both filled)
- ``start_time`` must be < ``end_time`` (when both filled)
- Times must be between 0-24 hours
- Empty end_date = permanent order
- Empty times = no time-based restrictions

Credits
=======

This module was developed by Criptomart in 2025 as a modernization of the Aplicoop application, integrating collaborative consumption group order management directly into Odoo's website sales framework.

The implementation follows OCA standards for:

- Code quality and testing (26 passing tests)
- Documentation structure and multilingual support
- Security and access control
- API design for extensibility

Authors
=======

* Criptomart

Funding
=======

* Elika Bilbo

Contributors
============

* `Criptomart <https://criptomart.net>`_:

  * Project lead and main development
  * Architecture and implementation

**Historical References:**

This module was inspired by the original **Aplicoop** project:

* https://sourceforge.net/projects/aplicoop/
* Original creators: Ekaitz Mendiluze, Joseba Legarreta, and other contributors

The original Aplicoop project served as a pioneering solution for collaborative consumption group orders, and this module brings its functionality to the modern Odoo platform.

Notes - Standard shop and cart
==============================

This module adds the "eskaera" group order flow (``/eskaera``); it no longer
touches the standard ``website_sale`` storefront. The default ``/shop`` and its
shopping cart keep working as usual after installing it.

Sites that want the standard cart disabled — so that the group order flow is
the single shopping experience — should additionally install
``website_sale_disable_cart``, which hides the cart UI and redirects the
standard cart endpoints to a configurable URL. That behaviour used to live in
this module (up to 18.0.1.11.0) and was extracted in 18.0.1.12.0.

::

      docker-compose run --rm odoo odoo -d odoo -i website_sale_disable_cart --stop-after-init

Then set *Website > Configuration > Settings > Disabled Cart > Cart Redirect
URL* to ``/eskaera``.