diff --git a/modules/purchase_trade/purchase.py b/modules/purchase_trade/purchase.py
index be305ba..2d09ed0 100755
--- a/modules/purchase_trade/purchase.py
+++ b/modules/purchase_trade/purchase.py
@@ -529,6 +529,138 @@ class PriceComposition(ModelSQL,ModelView):
component = fields.Char("Component")
price = fields.Numeric("Price")
+class AssayImporter:
+
+ def __init__(self):
+ pool = Pool()
+ self.AssayLine = pool.get('assay.line')
+ self.Element = pool.get('assay.element')
+ self.Uom = pool.get('product.uom')
+
+ # -----------------------------
+ # PUBLIC ENTRYPOINT
+ # -----------------------------
+ def import_from_json(self, data: dict, assay):
+ self._update_assay(data,assay)
+ lines = self._create_lines(data, assay)
+
+ self.AssayLine.save(lines)
+ return assay
+
+ # -----------------------------
+ # HEADER
+ # -----------------------------
+ def _update_assay(self, data):
+ Party = Pool().get('party.party')
+ metadata = data.get('document_metadata', {})
+
+ assay = self.Assay()
+
+ assay.reference = metadata.get('report_reference')
+ assay.date = self._parse_date(metadata.get('issue_date'))
+ assay.type = self._map_type(metadata.get('status'))
+ assay.status = 'draft'
+ assay.lab = Party.getPartyByName(metadata.get('lab_name'))
+
+ assay.save()
+ return assay
+
+ # -----------------------------
+ # LINES
+ # -----------------------------
+ def _create_lines(self, data, assay):
+ lines = []
+
+ # assays
+ for item in data.get('assays', []):
+ lines.append(self._build_line(item, assay, category='assay'))
+
+ # penalties
+ for item in data.get('penalties', []):
+ lines.append(self._build_line(item, assay, category='penalty'))
+
+ # moisture
+ moisture = data.get('weights_and_moisture', {}).get('moisture')
+ if moisture and moisture.get('value') is not None:
+ lines.append(self._build_line({
+ "element": "H2O",
+ "value": moisture.get('value'),
+ "unit": moisture.get('unit')
+ }, assay, category='moisture'))
+
+ return lines
+
+ # -----------------------------
+ # LINE BUILDER
+ # -----------------------------
+ def _build_line(self, item, assay, category):
+ line = self.AssayLine()
+
+ line.assay = assay
+ line.element = self._get_or_create_element(item.get('element'))
+ line.value = self._safe_float(item.get('value'))
+ line.unit = self._get_uom(item.get('unit'))
+ line.category = category
+
+ line.method = item.get('method')
+ line.is_payable = item.get('is_payable', False)
+
+ return line
+
+ # -----------------------------
+ # HELPERS
+ # -----------------------------
+ def _get_or_create_element(self, code):
+ if not code:
+ return None
+
+ elements = self.Element.search([('name', '=', code)])
+ if elements:
+ return elements[0]
+
+ # auto-create (optionnel mais pratique)
+ element = self.Element()
+ element.name = code
+ element.save()
+ return element
+
+ def _get_uom(self, unit_name):
+ if not unit_name:
+ return None
+
+ uoms = self.Uom.search([('symbol', '=', unit_name)])
+ if uoms:
+ return uoms[0]
+
+ return None # ou lever une erreur selon ton besoin
+
+ def _parse_date(self, date_str):
+ if not date_str:
+ return None
+ try:
+ return datetime.datetime.strptime(date_str, "%Y-%m-%d").date()
+ except Exception:
+ return None
+
+ def _safe_float(self, value):
+ try:
+ return float(value)
+ except Exception:
+ return None
+
+ def _map_type(self, status):
+ if not status:
+ return 'provisional'
+
+ status = status.lower()
+
+ if 'final' in status:
+ return 'final'
+ if 'umpire' in status:
+ return 'umpire'
+
+ return 'provisional'
+
class Assay(ModelSQL, ModelView):
"Assay"
__name__ = 'assay.assay'
@@ -549,7 +681,7 @@ class Assay(ModelSQL, ModelView):
('validated', 'Validated'),
], "Status")
- laboratory = fields.Char("Laboratory")
+ lab = fields.Many2One('party.party',"Laboratory")
lines = fields.One2Many(
'assay.line', 'assay', "Assay Lines"
@@ -973,7 +1105,15 @@ class Line(metaclass=PoolMeta):
f = Fee(line.fee_)
f.purchase = line.purchase
Fee.save([f])
-
+
+ if line.assays:
+ for assay in line.assays:
+ if not assay.lines and assay.document:
+ data = json.load(f)
+ importer = AssayImporter()
+ importer.import_from_json(data,assay)
+ logger.info("Updated assay:%s", assay.id)
+
def check_from_to(self,tr):
if tr.pricing_period:
date_from,date_to, d, include, dates = tr.getDateWithEstTrigger(1)
diff --git a/modules/purchase_trade/view/assay_form.xml b/modules/purchase_trade/view/assay_form.xml
index f9f763f..0208528 100644
--- a/modules/purchase_trade/view/assay_form.xml
+++ b/modules/purchase_trade/view/assay_form.xml
@@ -7,8 +7,8 @@
-
-
+
+
diff --git a/modules/purchase_trade/view/assay_tree.xml b/modules/purchase_trade/view/assay_tree.xml
index 621c570..df9b59b 100644
--- a/modules/purchase_trade/view/assay_tree.xml
+++ b/modules/purchase_trade/view/assay_tree.xml
@@ -3,6 +3,6 @@
-
+
\ No newline at end of file