89 lines
2.9 KiB
Dart
89 lines
2.9 KiB
Dart
import 'package:pocketbase/pocketbase.dart';
|
|
import '../../../core/api/pocketbase_client.dart';
|
|
import '../../../core/services/finance_service.dart';
|
|
import '../../../models/finance_entry.dart';
|
|
|
|
class ClinicFinanceRepository {
|
|
ClinicFinanceRepository._();
|
|
static final instance = ClinicFinanceRepository._();
|
|
|
|
PocketBase get _pb => PocketBaseClient.instance.pb;
|
|
|
|
Future<List<FinanceEntry>> listEntries(
|
|
String tenantId, {
|
|
String? status,
|
|
int page = 1,
|
|
int limit = 30,
|
|
}) async {
|
|
final filterParts = ['tenant_id = "$tenantId"', 'type = "payable"'];
|
|
if (status == FinanceStatus.pending.value) {
|
|
filterParts.add('(status = "pending" || status = "reported")');
|
|
} else if (status != null) {
|
|
filterParts.add('status = "$status"');
|
|
}
|
|
|
|
final result = await _pb.collection('finance_entries').getList(
|
|
page: page,
|
|
perPage: limit,
|
|
filter: filterParts.join(' && '),
|
|
expand: 'job_id',
|
|
);
|
|
return (result.items.map((r) => FinanceEntry.fromJson(r.toJson())).toList()
|
|
..sort((a, b) => (b.dateCreated ?? '').compareTo(a.dateCreated ?? '')));
|
|
}
|
|
|
|
Future<Map<String, double>> summary(String tenantId) async {
|
|
final all = await listEntries(tenantId, limit: 200);
|
|
double pending = 0, paid = 0;
|
|
for (final e in all) {
|
|
if (e.status.isOpen) {
|
|
pending += e.amount;
|
|
} else {
|
|
paid += e.amount;
|
|
}
|
|
}
|
|
return {'pending': pending, 'paid': paid};
|
|
}
|
|
|
|
Future<List<CounterpartyFinanceSummary>> byCounterparty(
|
|
String tenantId) async {
|
|
final entries = await listEntries(tenantId, limit: 300);
|
|
final map = <String, CounterpartyFinanceSummary>{};
|
|
|
|
for (final entry in entries) {
|
|
final key =
|
|
entry.counterpartyTenantId ?? entry.counterpartyName ?? 'unknown';
|
|
final current = map[key];
|
|
final pending = (current?.pendingAmount ?? 0) +
|
|
(entry.status.isOpen ? entry.amount : 0);
|
|
final paid = (current?.paidAmount ?? 0) +
|
|
(entry.status == FinanceStatus.paid ? entry.amount : 0);
|
|
map[key] = CounterpartyFinanceSummary(
|
|
counterpartyTenantId: entry.counterpartyTenantId,
|
|
counterpartyName: entry.counterpartyName ?? 'Karşı Taraf',
|
|
currency: entry.currency,
|
|
pendingAmount: pending,
|
|
paidAmount: paid,
|
|
entryCount: (current?.entryCount ?? 0) + 1,
|
|
);
|
|
}
|
|
|
|
final list = map.values.toList();
|
|
list.sort((a, b) => b.pendingAmount.compareTo(a.pendingAmount));
|
|
return list;
|
|
}
|
|
|
|
Future<void> reportPayment(String entryId) async {
|
|
final record = await _pb.collection('finance_entries').getOne(entryId);
|
|
final jobId = record.data['job_id']?.toString();
|
|
if (jobId == null || jobId.isEmpty) {
|
|
await _pb.collection('finance_entries').update(entryId, body: {
|
|
'status': 'reported',
|
|
'paid_at': null,
|
|
});
|
|
return;
|
|
}
|
|
await FinanceService.instance.reportJobPayment(jobId);
|
|
}
|
|
}
|