diff --git a/modules/purchase_trade/docs/business-rules.md b/modules/purchase_trade/docs/business-rules.md
index 21a3bdc..9ea948d 100644
--- a/modules/purchase_trade/docs/business-rules.md
+++ b/modules/purchase_trade/docs/business-rules.md
@@ -910,3 +910,8 @@ Pour cette regle, couvrir au minimum:
- Le widget SAO `tolerance_gauge` est autorise dans les schemas de vues
`form` et `tree` avec `min`, `max`, `min_field`, `max_field`, `center` et
`digits`.
+- En formulaire de ligne (`purchase.line` / `sale.line`), ne pas encapsuler
+ `tolerance_gauge` et `targeted_qt` dans un sous-groupe `colspan="4"`: cela
+ decale visuellement le bloc vers la droite dans SAO. Les placer directement
+ dans la grille principale et forcer `xalign="0"` sur la jauge et sur
+ `targeted_qt` pour garder un alignement a gauche stable.
diff --git a/modules/purchase_trade/docs/business/lots-and-quantities.en.md b/modules/purchase_trade/docs/business/lots-and-quantities.en.md
index b0b0b65..c9a455f 100644
--- a/modules/purchase_trade/docs/business/lots-and-quantities.en.md
+++ b/modules/purchase_trade/docs/business/lots-and-quantities.en.md
@@ -339,6 +339,10 @@ them with Python guards and SQL diagnostics.
Matching gauge |
In Go to matching, the gauge projects already matched + Qt to match against quantity_theorical, with -tol_min / tol_max bounds. |
+
+| Line gauge layout |
+On purchase.line / sale.line forms, place the gauge and targeted_qt directly in the main grid, without a colspan="4" subgroup, and use xalign="0" to avoid a double right shift. |
+
diff --git a/modules/purchase_trade/docs/business/lots-and-quantities.md b/modules/purchase_trade/docs/business/lots-and-quantities.md
index 54d5766..302408c 100644
--- a/modules/purchase_trade/docs/business/lots-and-quantities.md
+++ b/modules/purchase_trade/docs/business/lots-and-quantities.md
@@ -338,6 +338,10 @@ puis les sécuriser par des checks Python et des diagnostics SQL.
Jauge matching |
Dans Go to matching, la jauge projette déjà matché + Qt to match contre quantity_theorical, avec bornes -tol_min / tol_max. |
+
+| Layout jauge ligne |
+En formulaire purchase.line / sale.line, placer la jauge et targeted_qt directement dans la grille principale, sans sous-groupe colspan="4", et utiliser xalign="0" pour éviter un double décalage vers la droite. |
+
diff --git a/modules/purchase_trade/docs_source/business/lots-and-quantities.en.md b/modules/purchase_trade/docs_source/business/lots-and-quantities.en.md
index 3d864b6..73be150 100644
--- a/modules/purchase_trade/docs_source/business/lots-and-quantities.en.md
+++ b/modules/purchase_trade/docs_source/business/lots-and-quantities.en.md
@@ -127,6 +127,7 @@ quantity_theorical
| Line gauge | On a line with physical lots, the gauge uses the sum of physical lots; without physical lots, it uses the sum of linked `lot.qt`. |
| Header gauge | The purchase/sale gauge is the weighted average of line gauges, weighted by `quantity_theorical`. |
| Matching gauge | In `Go to matching`, the gauge projects `already matched + Qt to match` against `quantity_theorical`, with `-tol_min` / `tol_max` bounds. |
+| Line gauge layout | On `purchase.line` / `sale.line` forms, place the gauge and `targeted_qt` directly in the main grid, without a `colspan="4"` subgroup, and use `xalign="0"` to avoid a double right shift. |
## Developer Section
diff --git a/modules/purchase_trade/docs_source/business/lots-and-quantities.md b/modules/purchase_trade/docs_source/business/lots-and-quantities.md
index 216e3cf..8aaeab5 100644
--- a/modules/purchase_trade/docs_source/business/lots-and-quantities.md
+++ b/modules/purchase_trade/docs_source/business/lots-and-quantities.md
@@ -126,6 +126,7 @@ quantity_theorical
| Jauge ligne | Sur une ligne avec lots physiques, la jauge utilise la somme des physiques ; sans physique, elle utilise la somme des `lot.qt` liés. |
| Jauge header | La jauge purchase/sale est la moyenne pondérée des jauges de lignes au prorata de `quantity_theorical`. |
| Jauge matching | Dans `Go to matching`, la jauge projette `déjà matché + Qt to match` contre `quantity_theorical`, avec bornes `-tol_min` / `tol_max`. |
+| Layout jauge ligne | En formulaire `purchase.line` / `sale.line`, placer la jauge et `targeted_qt` directement dans la grille principale, sans sous-groupe `colspan="4"`, et utiliser `xalign="0"` pour éviter un double décalage vers la droite. |
## Section développeur
diff --git a/modules/purchase_trade/purchase.py b/modules/purchase_trade/purchase.py
index b8a3a21..940fb02 100755
--- a/modules/purchase_trade/purchase.py
+++ b/modules/purchase_trade/purchase.py
@@ -1691,8 +1691,9 @@ class Line(metaclass=PoolMeta):
def _get_basis_component_price(self):
price = Decimal(0)
- if self.terms:
- for t in self.terms:
+ terms = getattr(self, 'terms', None)
+ if terms:
+ for t in terms:
price += (t.manual_price if t.manual_price else Decimal(0))
else:
if not self.price_components:
diff --git a/modules/purchase_trade/tests/test_module.py b/modules/purchase_trade/tests/test_module.py
index 70d5164..13be345 100644
--- a/modules/purchase_trade/tests/test_module.py
+++ b/modules/purchase_trade/tests/test_module.py
@@ -1588,7 +1588,6 @@ class PurchaseTradeTestCase(ModuleTestCase):
line.id = 1
line.price_type = 'basis'
line.price_components = []
- line.terms = []
line.enable_linked_currency = False
line.linked_currency = None