Compare commits

...

2 commits

Author SHA1 Message Date
GitHub Copilot
158933e96e [FIX] website_sale_aplicoop: two draft-reuse and compute-field bugs
- group.order.home_delivery is a stored compute field with no inverse;
  Odoo still lets write() set it directly, so a stray direct write stuck
  instead of always being re-derived from delivery_product_id. create()
  and write() now strip it from vals, same pattern already used for slug.

- _find_recent_draft_order only bounded drafts by create_date, so a
  freshly created draft for a stale/previous pickup_date (but created
  "now") was wrongly reused. Fix requires both create_date to fall in
  the active window AND pickup_date to match when set — the latter
  alone isn't enough either, per the regression already covered by
  test_find_recent_draft_excludes_previous_cycle (observed in
  production at stage.elikabilbo.eus).
2026-08-13 12:02:33 +02:00
GitHub Copilot
e59c706ef6 [I18N] website_sale_aplicoop, product_origin_char: add Catalan translation
Add ca.po for both addons, matching the existing es/eu coverage
(378 and 4 entries respectively). Add the missing "ca" fallback block
in website_sale_i18n.py alongside the existing es/eu ones, and correct
the i18n README, which falsely claimed complete pt/gl/fr/it coverage
that was never actually present.
2026-08-13 11:52:54 +02:00
6 changed files with 2386 additions and 20 deletions

View file

@ -0,0 +1,39 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * product_origin_char
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-02-25 12:00+0000\n"
"PO-Revision-Date: 2026-02-25 12:00+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: product_origin_char
#: model:ir.model.fields,field_description:product_origin_char.field_product_product__origin_text
#: model:ir.model.fields,field_description:product_origin_char.field_product_template__origin_text
msgid "Origin"
msgstr "Origen"
#. module: product_origin_char
#: model:ir.model.fields,help:product_origin_char.field_product_product__origin_text
#: model:ir.model.fields,help:product_origin_char.field_product_template__origin_text
msgid "Origin text from main vendor's supplierinfo"
msgstr "Text d'origen del proveïdor principal"
#. module: product_origin_char
#: model:ir.model,name:product_origin_char.model_product_product
msgid "Product"
msgstr "Producte"
#. module: product_origin_char
#: model:ir.model,name:product_origin_char.model_product_template
msgid "Product Template"
msgstr "Plantilla de producte"

View file

@ -62,6 +62,14 @@ def _get_translated_labels(self, lang=None, request_obj=None):
"This order's cart is empty.": "Eskaera honen saskia hutsik dago.",
"This order's cart is empty": "Eskaera honen saskia hutsik dago",
},
"ca": {
"Browse Product Categories": "Explora categories de productes",
"Save Draft": "Desa l'Esborrany",
"Save order as draft": "Desa la comanda com a esborrany",
"Order saved as draft": "Comanda desada com a esborrany",
"This order's cart is empty.": "El carret d'aquesta comanda està buit.",
"This order's cart is empty": "El carret d'aquesta comanda està buit",
},
}
def tr(source):

View file

@ -65,21 +65,33 @@ def _get_salesperson_for_order(self, partner):
def _find_recent_draft_order(self, partner_id, group_order, request_obj=None):
"""Return the active-cycle draft sale.order for the partner, or empty.
The active ordering period ends at group_order.cutoff_date and its length
depends on the order period: 7 days (weekly), 14 days (biweekly), one
month (monthly). One-time orders have a single cycle starting at
start_date (or unbounded when start_date is empty). Drafts created
outside this window belong to a previous cycle and must not be reused
otherwise stale carts come back when the user re-enters the order page.
A draft only counts as "current cycle" when it satisfies BOTH of these
(neither is sufficient on its own see the regression each one guards):
1) create_date falls within the active window derived from
group_order.cutoff_date and the order period (7 days weekly, 14
biweekly, one month monthly; one-time orders use a single cycle
starting at start_date). Without this, a draft whose pickup_date
happens to match the current one only because pickup_date froze
across cycles (observed in production) would be wrongly reused.
2) When group_order.pickup_date is set, the draft's pickup_date matches
it exactly. Without this, a draft created "now" for a stale/previous
pickup_date but still inside the current create_date window
would be wrongly reused instead of starting a fresh cart.
Drafts failing either check belong to a previous cycle and must not be
reused otherwise stale carts come back when the user re-enters the
order page.
"""
req = request_obj or request
from datetime import timedelta
from dateutil.relativedelta import relativedelta
if not group_order or not group_order.cutoff_date:
return req.env["sale.order"]
from datetime import timedelta
from dateutil.relativedelta import relativedelta
period_end = group_order.cutoff_date
if group_order.period == "weekly":
period_start = period_end - timedelta(days=6)
@ -98,6 +110,8 @@ def _find_recent_draft_order(self, partner_id, group_order, request_obj=None):
]
if period_start:
domain.append(("create_date", ">=", f"{period_start} 00:00:00"))
if group_order.pickup_date:
domain.append(("pickup_date", "=", group_order.pickup_date))
return (
req.env["sale.order"].sudo().search(domain, order="create_date desc", limit=1)

View file

@ -2,21 +2,17 @@
## Language Support
This module has complete translation support for **7 languages**:
This module has complete translation support for **3 languages**:
| Language | Code | Status | Coverage |
|----------|------|--------|----------|
| Spanish | `es` | ✅ Complete | 100% |
| Portuguese | `pt` | ✅ Complete | 100% |
| Galician | `gl` | ✅ Complete | 100% |
| Catalan | `ca` | ✅ Complete | 100% |
| Basque (Euskera) | `eu` | ✅ Complete | 100% |
| French | `fr` | ✅ Complete | 100% |
| Italian | `it` | ✅ Complete | 100% |
## Translated Content
Each `.po` file contains **66 translations** for:
Each `.po` file contains **378 translations** for:
- **Selection Field Options** (Days of week, Recurrence periods)
- Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
@ -38,9 +34,8 @@ When users switch their Odoo interface language to any of the supported language
### Example
- English: "Group Order"
- Spanish: "Pedido de Grupo"
- Portuguese: "Pedido de Grupo"
- French: "Commande de Groupe"
- etc.
- Catalan: "Comanda de Grup"
- Basque (Euskera): "Taldeko Eskaera"
## Translation Workflow
@ -62,7 +57,7 @@ msgstr "Pedido de Grupo" # Spanish translation
- All `.po` files were generated and tested: **40/40 tests passing**
- Translation coverage: **100%** for all supported languages
- Last updated: December 16, 2025
- Last updated: August 13, 2026
---

File diff suppressed because it is too large Load diff

View file

@ -420,6 +420,7 @@ class GroupOrder(models.Model):
taken = set()
new_vals_list = []
for vals in vals_list:
vals = {k: v for k, v in vals.items() if k != "home_delivery"}
slug = self._normalize_slug(vals.get("slug")) or self._generate_unique_slug(
vals.get("name"), taken=taken
)
@ -428,7 +429,16 @@ class GroupOrder(models.Model):
return super().create(new_vals_list)
def write(self, vals):
"""Normalize the slug, regenerating it from the name when emptied."""
"""Normalize the slug, regenerating it from the name when emptied.
`home_delivery` is derived from `delivery_product_id` and must never
be settable directly dropped here so a stray direct write can't
make it stick outside `_compute_home_delivery`.
"""
if "home_delivery" in vals:
vals = {k: v for k, v in vals.items() if k != "home_delivery"}
if not vals:
return True
if "slug" not in vals:
return super().write(vals)
slug = self._normalize_slug(vals["slug"])