Files
lab-app/lib/core/services/finance_service.dart
T
2026-06-20 18:24:40 +03:00

134 lines
3.4 KiB
Dart

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> 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<void> 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<void> 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<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);
}
}