"""Legal-aid billing tools: proforma → submission → monthly 320 → email payload.""" from __future__ import annotations import json import re from typing import TYPE_CHECKING if TYPE_CHECKING: from mcp_server.espocrm_client import EspoCrmClient from mcp_server.tools._helpers import ok, fail MONTH_RE = re.compile(r"^\d{4}-\d{2}$") def _money(amount) -> str: try: return f"₪{float(amount):,.2f}" except (TypeError, ValueError): return f"₪{amount}" def register_legal_aid_tools( tools: dict, crm: "EspoCrmClient", case_id: str | None, user_id: str | None, context: dict, ): """Register Israeli Legal-Aid (סיוע משפטי) billing tools.""" async def create_legal_aid_proforma(chargeIds: list[str]) -> str: if not chargeIds: return fail("צריך לפחות מזהה חיוב סיוע משפטי אחד") try: result = await crm.post("Invoice/action/createLegalAidProforma", {"chargeIds": chargeIds}) if not result.get("success"): return fail(f"יצירת חשבון עסקה נכשלה: {result.get('error', 'unknown')}") return ok( f"חשבון עסקה (פרופורמה לסיוע משפטי) נוצר: " f"{result.get('name', '')} (ID: {result.get('id')}, " f"מספר חיובים: {result.get('chargesCount', len(chargeIds))}, " f"סכום כולל: {_money(result.get('totalAmount'))}). " f"כעת יש להגיש ידנית באתר משרד הסיוע ולאחר מכן לקרוא ל-mark_legal_aid_submitted עם מספר הבקשה שהאתר יחזיר." ) except Exception as e: return fail(f"שגיאה ביצירת פרופורמה: {e}") async def mark_legal_aid_submitted(invoiceId: str, legalAidRequestNumber: str) -> str: if not invoiceId: return fail("צריך מזהה חשבון עסקה (פרופורמה)") if not legalAidRequestNumber: return fail("צריך מספר בקשה מאתר משרד הסיוע (לדוגמה: 2026-04-00123)") try: result = await crm.post( f"Invoice/{invoiceId}/action/markLegalAidSubmitted", {"legalAidRequestNumber": legalAidRequestNumber}, ) if not result.get("success"): return fail(f"סימון הגשה נכשל: {result.get('error', 'unknown')}") return ok( f"פרופורמה סומנה כמוגשת. מספר בקשה: {result.get('legalAidRequestNumber')}, " f"זמן הגשה: {result.get('legalAidSubmittedAt')}. " f"כל החיובים המקושרים עברו לסטטוס Submitted." ) except Exception as e: return fail(f"שגיאה בסימון הגשה: {e}") async def legal_aid_monthly_summary(month: str) -> str: if not MONTH_RE.match(month or ""): return fail("פורמט חודש חייב להיות YYYY-MM (לדוגמה 2026-04)") try: result = await crm.get(f"Invoice/action/legalAidMonthlyWrapSummary?month={month}") return ok(json.dumps(result, ensure_ascii=False)) except Exception as e: return fail(f"שגיאה בשליפת סיכום חודשי: {e}") async def create_monthly_legal_aid_invoice(month: str) -> str: if not MONTH_RE.match(month or ""): return fail("פורמט חודש חייב להיות YYYY-MM (לדוגמה 2026-04)") try: result = await crm.post("Invoice/action/createLegalAidMonthlyTaxInvoice", {"month": month}) if not result.get("success"): return fail(f"יצירת חשבונית חודשית נכשלה: {result.get('error', 'unknown')}") return ok( f"חשבונית מס חודשית (320) לחודש {month} נוצרה: " f"{result.get('name', '')} (ID: {result.get('id')}, " f"סכום כולל: {_money(result.get('totalAmount'))}). " f"כעת ניתן להפיק payload לאימייל למשרד המשפטים באמצעות prepare_monthly_320_email." ) except Exception as e: return fail(f"שגיאה ביצירת חשבונית חודשית: {e}") async def prepare_monthly_320_email(invoiceId: str) -> str: if not invoiceId: return fail("צריך מזהה חשבונית 320 חודשית") try: result = await crm.get(f"Invoice/{invoiceId}/action/prepareMonthly320Email") payload = result.get("emailPayload") or result return ok(json.dumps(payload, ensure_ascii=False)) except Exception as e: return fail(f"שגיאה בהכנת payload לאימייל: {e}") async def resubmit_charge(chargeId: str, newActivitySubType: str = "") -> str: if not chargeId: return fail("צריך מזהה חיוב") body = {"id": chargeId} if newActivitySubType: body["newActivitySubType"] = newActivitySubType try: result = await crm.post("Charge/action/resubmit", body) if not result.get("success"): return fail("הגשה מחדש נכשלה") return ok( f"חיוב הוגש מחדש: ID חדש {result.get('newChargeId')} " f"(מס׳ {result.get('newChargeNumber')}), " f"סכום {_money(result.get('newChargeAmount'))}, " f"סוג פעילות {result.get('newChargeActivitySubType')}" ) except Exception as e: return fail(f"שגיאה בהגשה מחדש: {e}") tools["create_legal_aid_proforma"] = { "description": ( "Create a legal-aid Proforma (Invoice type 400, חשבון עסקה) bundling Recorded charges. " "All chargeIds must be legal-aid charges in 'Recorded' status. " "After this, the secretary submits the proforma manually at the official Legal Aid site and gets a request number — " "then call mark_legal_aid_submitted with that number." ), "parameters": { "type": "object", "properties": { "chargeIds": {"type": "array", "items": {"type": "string"}, "description": "Legal-aid charge IDs (status=Recorded)"}, }, "required": ["chargeIds"], }, "handler": create_legal_aid_proforma, } tools["mark_legal_aid_submitted"] = { "description": ( "Mark a legal-aid Proforma as submitted to the official Legal Aid website. " "Requires the legalAidRequestNumber returned by the official site (format like '2026-04-00123'). " "Flips all linked charges from Recorded to Submitted. Do NOT call without an explicit number from the user." ), "parameters": { "type": "object", "properties": { "invoiceId": {"type": "string", "description": "Proforma Invoice ID (documentType=400)"}, "legalAidRequestNumber": {"type": "string", "description": "Request number from official Legal Aid site"}, }, "required": ["invoiceId", "legalAidRequestNumber"], }, "handler": mark_legal_aid_submitted, } tools["legal_aid_monthly_summary"] = { "description": "Preview what a monthly 320 legal-aid tax invoice would contain for a given YYYY-MM. Read-only.", "parameters": { "type": "object", "properties": { "month": {"type": "string", "description": "Month in YYYY-MM format (e.g. 2026-04)"}, }, "required": ["month"], }, "handler": legal_aid_monthly_summary, } tools["create_monthly_legal_aid_invoice"] = { "description": ( "Create the monthly type-320 tax invoice that aggregates all Paid legal-aid charges for the given YYYY-MM. " "Flips all aggregated charges from Paid to Billed (terminal). " "Use legal_aid_monthly_summary first to preview before creating." ), "parameters": { "type": "object", "properties": { "month": {"type": "string", "description": "Month in YYYY-MM format (e.g. 2026-04)"}, }, "required": ["month"], }, "handler": create_monthly_legal_aid_invoice, } tools["prepare_monthly_320_email"] = { "description": ( "Build the email payload (recipient, subject, body, attachment ref) for sending a monthly 320 legal-aid invoice " "to the Justice Ministry. Returns JSON — does NOT actually send. The secretary copy-pastes or pipes via n8n." ), "parameters": { "type": "object", "properties": { "invoiceId": {"type": "string", "description": "Monthly 320 Invoice ID"}, }, "required": ["invoiceId"], }, "handler": prepare_monthly_320_email, } tools["resubmit_charge"] = { "description": ( "Clone a Rejected legal-aid charge as a new Recorded charge, optionally with a corrected activitySubType. " "Use after the Legal Aid office rejects a line in a payment report." ), "parameters": { "type": "object", "properties": { "chargeId": {"type": "string", "description": "ID of the Rejected charge to clone"}, "newActivitySubType": {"type": "string", "description": "Corrected activity sub-type code (optional)"}, }, "required": ["chargeId"], }, "handler": resubmit_charge, }