feat: improve patient flow and pricing workflow
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
|
||||
import '../api/pocketbase_client.dart';
|
||||
|
||||
class FinanceService {
|
||||
FinanceService._();
|
||||
static final instance = FinanceService._();
|
||||
|
||||
PocketBase get _pb => PocketBaseClient.instance.pb;
|
||||
|
||||
Future<void> 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<void> markJobPaid(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<void> deletePendingEntriesForJob(String jobId) async {
|
||||
final existing = await _pb.collection('finance_entries').getFullList(
|
||||
filter: 'job_id = "$jobId" && status = "pending"',
|
||||
batch: 200,
|
||||
);
|
||||
for (final record in existing) {
|
||||
await _pb.collection('finance_entries').delete(record.id);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _upsertEntry({
|
||||
required List<RecordModel> 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user