Members can now pay their eskaera at checkout, through the standard Odoo payment machinery. Enabled per group order with a new `online_payment` boolean, off by default: an order without it behaves exactly as before, members save a draft and the cutoff cron confirms them in bulk. The flow mirrors website_sale's: the checkout button becomes "Confirm and pay", saving the cart redirects to a new /eskaera/<slug>/payment step that renders `payment.form` from `sale`'s `_get_payment_values`, and the standard /my/orders/<id>/transaction route takes it from there. This addon ships no provider and configures none; the co-op publishes whichever it wants. `website_sale`'s `_get_shop_payment_values` is deliberately not reused: it runs `_get_shop_payment_errors`, which blocks on shippable products without a delivery method — exactly an eskaera order, collected at the co-op with no carrier. For the same reason the transaction route stays the portal one, which does not call `_check_cart_is_ready_to_be_paid()`. Payment confirms the order, which has three consequences handled here: * `payment.transaction._check_amount_and_confirm_order` now confirms group orders with `from_orderpoint=True`, the way the cutoff cron already does. Without it a product with a broken replenishment route raises inside `_post_process`, and `/payment/status/poll` rolls back and re-raises: the member sees a payment error over a `done` transaction and the retry cron fails forever. * `_confirm_linked_sale_orders` also sweeps the cycle's already confirmed orders into the picking batch, scoped by `pickup_date`. Its early return on "no drafts" ran before any batching, so a fully prepaid cycle produced no batch at all. `_cron_batch_paid_orders_of_closed_cycles` covers the same hole for cycles closed by hand. * A duplicate-order guard answers 409 on save-order, add-to-cart and load-draft, and shows a notice on the shop, so a member whose order is already placed cannot build and pay for a second one. The payment policy lives in the model rather than the controller: there are three sale.order creation paths and two are live, so `_compute_require_payment` and `_compute_prepayment_percent` are extended instead of patching five vals dicts. Orders are also created under the group order's company, which is what filters the payment providers. Along the way: eskaera drafts were invisible in /my/orders. The portal rule is `message_partner_ids child_of` and sale.order only subscribes the customer on send or confirm, never on a draft create, so the `_prepare_orders_domain` override that includes drafts never had any effect. Fixed with an explicit `message_subscribe`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| __init__.py | ||
| ca.po | ||
| es.po | ||
| eu.po | ||
| README.md | ||
Website Sale Aplicoop - Translations
Language Support
This module has complete translation support for 3 languages:
| Language | Code | Status | Coverage |
|---|---|---|---|
| Spanish | es |
✅ Complete | 100% |
| Catalan | ca |
✅ Complete | 100% |
| Basque (Euskera) | eu |
✅ Complete | 100% |
Translated Content
Each .po file contains 388 translations for:
-
Selection Field Options (Days of week, Recurrence periods)
- Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
- Daily, Weekly, Biweekly, Monthly
-
Order States
- Draft, Open, Closed, Cancelled
-
Order Types
- Regular Order, Special Order, Promotional Order
-
Field Labels & Help Text
- 40+ field definitions with labels, help text, and descriptions
Usage
When users switch their Odoo interface language to any of the supported languages, all UI strings will automatically display in that language.
Example
- English: "Group Order"
- Spanish: "Pedido de Grupo"
- Catalan: "Comanda de Grup"
- Basque (Euskera): "Taldeko Eskaera"
Translation Workflow
To add or update translations:
- Edit the corresponding
.pofile withpolib(nevermsgmerge, it corrupts them) - Update the
msgstrvalues (keepmsgidunchanged) - Save and reload the module in Odoo
- Translations apply immediately
Adding a new string is not just a .po edit
website_sale_aplicoop.pot is generated by Odoo and is gitignored, but it is not
optional: Odoo merges every .po against it before importing, and polib's merge()
drops entries the POT does not have and replaces their occurrences with the POT's.
A brand new string, or an existing one that just became a view term, needs the POT
regenerated (from the Odoo UI, against a database without demo data) before its
translation applies anywhere.
Three failure modes that produce no error at all — an untranslatable attribute
(data-bs-title is not on QWeb's list, title is), a missing
model_terms:ir.ui.view reference in the POT, and a missing #. odoo-python
comment on _() strings — are written up in
docs/TRANSLATIONS.md, under Troubleshooting.
Example entry in a .po file:
#. module: website_sale_aplicoop
msgid "Group Order"
msgstr "Pedido de Grupo" # Spanish translation
Maintenance
- All
.pofiles were generated and tested: 40/40 tests passing - Translation coverage: 100% for all supported languages
- Last updated: August 16, 2026
Note: The module includes English strings by default. No en.po file is needed as English is the source language.