import 'package:pocketbase/pocketbase.dart'; import '../api/pocketbase_client.dart'; class FinanceService { FinanceService._(); static final instance = FinanceService._(); PocketBase get _pb => PocketBaseClient.instance.pb; Future ensureEntriesForJob({ required String jobId, required String clinicTenantId, required String labTenantId, required String clinicName, required String labName, required double amount, required String currency, }) async { if (amount <= 0) return; final existing = await _pb.collection('finance_entries').getFullList( filter: 'job_id = "$jobId"', batch: 200, ); await _upsertEntry( existing: existing, jobId: jobId, tenantId: clinicTenantId, counterpartyTenantId: labTenantId, counterpartyName: labName, type: 'payable', amount: amount, currency: currency, ); await _upsertEntry( existing: existing, jobId: jobId, tenantId: labTenantId, counterpartyTenantId: clinicTenantId, counterpartyName: clinicName, type: 'receivable', amount: amount, currency: currency, ); } Future reportJobPayment(String jobId) async { final existing = await _pb.collection('finance_entries').getFullList( filter: 'job_id = "$jobId"', batch: 200, ); for (final record in existing) { await _pb.collection('finance_entries').update( record.id, body: { 'status': 'reported', 'paid_at': null, }, ); } } Future confirmJobPayment(String jobId) async { final existing = await _pb.collection('finance_entries').getFullList( filter: 'job_id = "$jobId"', batch: 200, ); final paidAt = DateTime.now().toIso8601String(); for (final record in existing) { await _pb.collection('finance_entries').update( record.id, body: { 'status': 'paid', 'paid_at': paidAt, }, ); } } Future deletePendingEntriesForJob(String jobId) async { final existing = await _pb.collection('finance_entries').getFullList( filter: 'job_id = "$jobId" && (status = "pending" || status = "reported")', batch: 200, ); for (final record in existing) { await _pb.collection('finance_entries').delete(record.id); } } Future _upsertEntry({ required List existing, required String jobId, required String tenantId, required String counterpartyTenantId, required String counterpartyName, required String type, required double amount, required String currency, }) async { RecordModel? match; try { match = existing.firstWhere( (record) => record.data['tenant_id'] == tenantId && record.data['type'] == type, ); } catch (_) { match = null; } final body = { 'tenant_id': tenantId, 'job_id': jobId, 'type': type, 'amount': amount, 'currency': currency, 'status': 'pending', 'paid_at': null, 'counterparty_tenant_id': counterpartyTenantId, 'counterparty_name': counterpartyName, }; if (match == null) { await _pb.collection('finance_entries').create(body: body); return; } await _pb.collection('finance_entries').update(match.id, body: body); } }