addons-cm/website_sale_aplicoop/models/js_translations.py
GitHub Copilot 6ba554c91b [ADD] website_sale_aplicoop: online payment per group order
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>
2026-08-16 21:59:35 +02:00

204 lines
5.8 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
"""
JavaScript Translation Strings
This file ensures that all JavaScript-related translatable strings are imported
into Odoo's translation system during module initialization.
CRITICAL: All strings that are dynamically rendered via JavaScript labels must
be included here with _() to ensure they are captured by Odoo's translation
extraction and loaded into the database.
See: docs/TRANSLATIONS_MASTER.md - "JavaScript Translations Must Be in js_translations.py"
"""
from odoo import _
def _register_translations():
"""
Register all JavaScript translation strings.
Called by Odoo's translation extraction system.
These calls populate the POT/PO files for translation.
"""
# ========================
# Action Labels
# ========================
_("Save Cart")
_("Reload Cart")
_("Browse Product Categories")
_("Proceed to Checkout")
_("Confirm Order")
_("Back to Cart")
_("Remove Item")
_("Add to Cart")
_("Save as Draft")
_("Save Draft")
_("Save order as draft")
_("Load Draft")
_("Browse Product Categories")
# ========================
# Online Payment Labels
# ========================
_("Confirm and pay")
_("Confirm the order and go to payment")
_("Order ready for payment")
_("You already placed an order for this cycle.")
_("Online payment is not available right now. Please contact your group.")
# ========================
# Draft Modal Labels
# ========================
_("Draft Already Exists")
_("A saved draft already exists for the current order period.")
_("You have two options:")
_("Option 1: Merge with Existing Draft")
_("Combine your current cart with the existing draft.")
_("Existing draft has")
_("Current cart has")
_("item(s)")
_(
"Products will be merged by adding quantities. If a product exists in both, quantities will be combined."
)
_("Option 2: Replace with Current Cart")
_("Delete the old draft and save only the current cart items.")
_("The existing draft will be permanently deleted.")
_("Merge")
_("Replace")
# ========================
# Draft Save/Load Confirmations
# ========================
_("Are you sure you want to save this cart as draft? Items to save: ")
_("You will be able to reload this cart later.")
_("Are you sure you want to load your last saved draft?")
_("This will replace the current items in your cart")
_("with the saved draft.")
# ========================
# Cart Messages (All Variations)
# ========================
_("Your cart is empty")
_("This order's cart is empty.")
_("This order's cart is empty")
_("added to cart")
_("items")
_("Your cart has been restored")
# ========================
# Confirmation & Validation
# ========================
_("Confirmation")
_("Confirm")
_("Cancel")
_("Please enter a valid quantity")
# ========================
# Error Messages
# ========================
_("Error: Order ID not found")
_("No draft orders found for the current order period")
_("Connection error")
_("Error loading order")
_("Error loading draft")
_("Unknown error")
_("Error saving cart")
_("Error processing response")
# ========================
# Success Messages
# ========================
_("Cart saved as draft successfully")
_("Draft order loaded successfully")
_("Draft merged successfully")
_("Draft replaced successfully")
_("Order loaded")
_("Thank you! Your order has been confirmed.")
_("Quantity updated")
# ========================
# Field Labels
# ========================
_("Product")
_("Supplier")
_("Price")
_("Quantity")
_("Subtotal")
_("Total")
# ========================
# Checkout Page Labels
# ========================
_("Home Delivery")
_("Delivery Information")
_(
"Delivery Information: Your order will be delivered at {pickup_day} {pickup_date}"
)
_("Your order will be delivered the day after pickup between 11:00 - 14:00")
_("Important")
_(
"Once you confirm this order, you will not be able to modify it. Please review carefully before confirming."
)
# ========================
# Search & Filter Labels
# ========================
_("Search")
_("Search products...")
_("No products found")
# Announced with a count in the search results live region, e.g. "7 products found"
_("products found")
_("Categories")
_("All categories")
# ========================
# Accessible Names
# ========================
# Dismiss button of the floating notification (website_sale.js)
_("Close")
# ========================
# Category Labels
# ========================
_("Order Type")
_("Order Period")
_("Cutoff Day")
_("Pickup Day")
_("Store Pickup Day")
_("Open until")
# ========================
# Portal Page Labels (New)
# ========================
_("Load in Cart")
_("Consumer Group")
_("Delivery Information")
_("Delivery Date:")
_("Pickup Date:")
_("Delivery Notice:")
_("No special delivery instructions")
_("Pickup Location:")
# ========================
# Day Names (Required for translations)
# ========================
_("Monday")
_("Tuesday")
_("Wednesday")
_("Thursday")
_("Friday")
_("Saturday")
_("Sunday")
# ========================
# Clear Cart
# ========================
_("Clear Cart")
_(
"Are you sure you want to clear the cart? This will also cancel any saved draft order."
)
_("Cart cleared")
_("draft order cancelled")