#!/usr/bin/env python3 """Read-only verification for v4928.1.5.132.3 invoice-sent evidence alignment.""" from __future__ import annotations import argparse import json import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) def _self_test() -> int: from app.invoice_evidence import completed_send_invoice_task_evidence invoice = { "id": "f5c53585-d8be-4f6c-b69e-e36202f47559", "external_id": "a2d2118f-b022-4f8f-997b-0d7fa00a1945", "document_number": "FA.FA2026.159", } task = { "action_code": "SEND_INVOICE", "status": "done", "action": "Enviar fatura FA.FA2026.159 ao cliente", "metadata": { "document_id": "e70968b3-d58e-4f4d-864a-54c00108a7bc", "document_number": "ORC.ORC2026.220", "invoice_delivery_context": { "document_id": invoice["id"], "document_number": invoice["document_number"], "document_kind": "invoice", }, }, } assert completed_send_invoice_task_evidence([task], [invoice]) is True task["metadata"]["invoice_delivery_context"] = { "document_id": "22222222-2222-2222-2222-222222222222", "document_number": "FA.FA2026.999", } assert completed_send_invoice_task_evidence([task], [invoice]) is False print("Self-test OK") return 0 def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--opportunity-id") parser.add_argument("--self-test", action="store_true") args = parser.parse_args() if args.self_test: return _self_test() if not args.opportunity_id: parser.error("--opportunity-id is required unless --self-test is used") from app.opportunity_next_action_service import get_opportunity_next_action from app.workflow_guard import blocked_reason, get_workflow_context decision = get_opportunity_next_action(args.opportunity_id) ctx = get_workflow_context(args.opportunity_id) result = { "opportunity_id": args.opportunity_id, "central_action": decision.get("action_code") or (decision.get("next_action") or {}).get("code"), "invoice_sent_evidence": bool(ctx.get("invoice_sent_evidence")), "invoice_sent_task_evidence": bool(ctx.get("invoice_sent_task_evidence")), "invoice_sent_last_action_evidence": bool(ctx.get("invoice_sent_last_action_evidence")), "physical_closed": bool(ctx.get("physical_closed")), "delivered_blocked_reason": blocked_reason(ctx, "delivered"), } print(json.dumps(result, ensure_ascii=False, indent=2, default=str)) return 0 if __name__ == "__main__": raise SystemExit(main())