v1.0.175: виртуальные группы + classify_raw + stepper
This commit is contained in:
+38
-12
@@ -33,8 +33,9 @@ def group_documents(batch_id):
|
||||
1. Отделить contract от supplement/specification
|
||||
2. Каждый contract → якорь группы
|
||||
3. Для каждого supplement: найти contract по parent_number (нормализованный)
|
||||
4. Несматченные → группа "__unresolved__"
|
||||
5. Внутри группы сортировка по doc_date
|
||||
4. Оставшиеся supplement/spec → виртуальные группы по parent_number/own_number
|
||||
5. Совсем без номеров → группа "__unresolved__"
|
||||
6. Внутри группы сортировка по doc_date
|
||||
|
||||
Возвращает {ok, groups: [{contract_number, counterparty, documents: [...]}], total_docs}.
|
||||
"""
|
||||
@@ -79,18 +80,43 @@ def group_documents(batch_id):
|
||||
|
||||
groups.append(group)
|
||||
|
||||
# Unmatched documents → "unresolved" group (including failed/pending)
|
||||
unmatched = [s for s in supplements_list if s.get("doc_type") != "contract"]
|
||||
# ── Virtual groups: unmatched supplements grouped by number ──────────
|
||||
# Group remaining supplements/specs by normalized parent_number (priority) or own_number
|
||||
virtual = {}
|
||||
for s in supplements_list:
|
||||
num = normalize_number(s.get("parent_number") or s.get("own_number") or "")
|
||||
if not num:
|
||||
continue # no number → stays in supplements_list for unresolved
|
||||
if num not in virtual:
|
||||
# Use counterparty from first doc in group
|
||||
cp = s.get("counterparty") or ""
|
||||
virtual[num] = {
|
||||
"contract_number": s.get("parent_number") or s.get("own_number") or "?",
|
||||
"counterparty": cp,
|
||||
"documents": [],
|
||||
}
|
||||
virtual[num]["documents"].append(s)
|
||||
# Update counterparty if current doc has a better one
|
||||
if not virtual[num]["counterparty"] and s.get("counterparty"):
|
||||
virtual[num]["counterparty"] = s.get("counterparty")
|
||||
|
||||
for vnum, vgroup in virtual.items():
|
||||
vgroup["documents"].sort(key=lambda x: x.get("doc_date") or "")
|
||||
groups.append(vgroup)
|
||||
# Remove grouped docs from supplements_list
|
||||
for s in vgroup["documents"]:
|
||||
supplements_list.remove(s)
|
||||
|
||||
# ── Unresolved: everything left (no number, failed, pending, other) ──
|
||||
unmatched = [s for s in supplements_list] # remaining after virtual grouping
|
||||
unmatched += [d for d in docs if d.get("classify_status") != "classified"]
|
||||
|
||||
if unmatched or len(contracts_list) == 0:
|
||||
# Put unmatched into a separate group
|
||||
if unmatched:
|
||||
groups.append({
|
||||
"contract_number": "__unresolved__",
|
||||
"counterparty": "",
|
||||
"documents": unmatched,
|
||||
})
|
||||
if unmatched:
|
||||
groups.append({
|
||||
"contract_number": "__unresolved__",
|
||||
"counterparty": "",
|
||||
"documents": unmatched,
|
||||
})
|
||||
|
||||
return {"ok": True, "groups": groups, "total_docs": len(docs)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user