enum FinanceType { receivable, payable } extension FinanceTypeX on FinanceType { String get value => name; String get label => this == FinanceType.receivable ? 'Alacak' : 'Borç'; } enum FinanceStatus { pending, reported, paid } extension FinanceStatusX on FinanceStatus { String get value => name; String get label { switch (this) { case FinanceStatus.pending: return 'Bekliyor'; case FinanceStatus.reported: return 'Onay Bekliyor'; case FinanceStatus.paid: return 'Onaylandı'; } } bool get isOpen => this == FinanceStatus.pending || this == FinanceStatus.reported; } class FinanceEntry { const FinanceEntry({ required this.id, required this.tenantId, required this.jobId, required this.type, required this.amount, required this.currency, required this.status, this.counterpartyTenantId, this.paidAt, this.counterpartyName, this.patientCode, this.dateCreated, }); final String id; final String tenantId; final String jobId; final FinanceType type; final double amount; final String currency; final FinanceStatus status; final String? counterpartyTenantId; final String? paidAt; final String? counterpartyName; final String? patientCode; final String? dateCreated; factory FinanceEntry.fromJson(Map j) { final expand = j['expand'] as Map?; final jobExp = expand?['job_id'] as Map?; String? parseOptionalString(dynamic v) { final s = v as String?; return (s == null || s.isEmpty) ? null : s; } return FinanceEntry( id: j['id'] as String, tenantId: j['tenant_id'] as String, jobId: j['job_id'] as String, type: FinanceType.values.firstWhere((e) => e.value == j['type'], orElse: () => FinanceType.receivable), amount: (j['amount'] as num).toDouble(), currency: j['currency'] as String? ?? 'TRY', status: FinanceStatus.values.firstWhere((e) => e.value == j['status'], orElse: () => FinanceStatus.pending), counterpartyTenantId: parseOptionalString(j['counterparty_tenant_id']), paidAt: parseOptionalString(j['paid_at']), counterpartyName: parseOptionalString(j['counterparty_name']), patientCode: jobExp?['patient_code'] as String?, dateCreated: j['created'] as String?, ); } } class CounterpartyFinanceSummary { const CounterpartyFinanceSummary({ required this.counterpartyName, required this.currency, required this.pendingAmount, required this.paidAmount, required this.entryCount, this.counterpartyTenantId, }); final String counterpartyName; final String currency; final double pendingAmount; final double paidAmount; final int entryCount; final String? counterpartyTenantId; double get totalAmount => pendingAmount + paidAmount; }