Initial commit — DLS lab-app Flutter project

This commit is contained in:
egecankomur
2026-06-10 23:22:15 +03:00
commit d1acc1d367
225 changed files with 31294 additions and 0 deletions
@@ -0,0 +1,177 @@
import 'dart:async';
import 'package:pocketbase/pocketbase.dart';
import '../../../core/api/pocketbase_client.dart';
import '../../../core/services/job_history_service.dart';
import '../../../models/job.dart';
const _listExpand = 'clinic_tenant_id,lab_tenant_id';
const _detailExpand = 'clinic_tenant_id,lab_tenant_id,patient_id,prosthetic_id';
class ClinicJobsRepository {
ClinicJobsRepository._();
static final instance = ClinicJobsRepository._();
PocketBase get _pb => PocketBaseClient.instance.pb;
Future<List<Job>> listOutbound(
String clinicTenantId, {
List<String>? statuses,
String? location,
String? filterExtra,
int page = 1,
int limit = 30,
}) async {
final filterParts = ['clinic_tenant_id = "$clinicTenantId"'];
if (statuses != null && statuses.isNotEmpty) {
final statusFilter = statuses.map((s) => 'status = "$s"').join(' || ');
filterParts.add('($statusFilter)');
}
if (location != null) {
filterParts.add('location = "$location"');
}
if (filterExtra != null) {
filterParts.add('($filterExtra)');
}
final result = await _pb.collection('jobs').getList(
page: page,
perPage: limit,
filter: filterParts.join(' && '),
expand: _listExpand,
);
return (result.items.map((r) => Job.fromJson(r.toJson())).toList()
..sort((a, b) => b.dateCreated.compareTo(a.dateCreated)));
}
Future<Job> getJob(String jobId) async {
final record = await _pb.collection('jobs').getOne(jobId, expand: _detailExpand);
return Job.fromJson(record.toJson());
}
Future<Job> createJob({
required String clinicTenantId,
required String labTenantId,
required String patientCode,
required String prostheticId,
required ProstheticType prostheticType,
required List<String> teeth,
String? patientId,
String? color,
String? description,
String? dueDate,
bool provaRequired = true,
}) async {
final record = await _pb.collection('jobs').create(body: {
'clinic_tenant_id': clinicTenantId,
'lab_tenant_id': labTenantId,
'patient_code': patientCode,
if (patientId != null) 'patient_id': patientId,
'prosthetic_id': prostheticId,
'prosthetic_type': prostheticType.value,
'member_count': teeth.length,
'teeth': teeth,
if (color != null) 'color': color,
if (description != null) 'description': description,
if (dueDate != null) 'due_date': dueDate,
'status': 'pending',
'location': 'at_clinic',
'prova_required': provaRequired,
});
return Job.fromJson(record.toJson());
}
Future<Job> approveAtClinic(String jobId, Job job, {String? note}) async {
final nextStep = job.nextStep;
if (nextStep == null) throw Exception('Bu aşamadan ileri gidilemez.');
final record = await _pb.collection('jobs').update(jobId, body: {
'current_step': nextStep.value,
'location': 'at_lab',
});
final updated = Job.fromJson(record.toJson());
unawaited(JobHistoryService.instance.append(
jobId: jobId,
clinicTenantId: job.clinicTenantId,
labTenantId: job.labTenantId,
action: JobHistoryAction.approved,
step: job.currentStep,
note: note,
));
return updated;
}
Future<Job> requestRevision(String jobId, Job job, {required String note}) async {
final record = await _pb.collection('jobs').update(jobId, body: {
'location': 'at_lab',
});
final updated = Job.fromJson(record.toJson());
unawaited(JobHistoryService.instance.append(
jobId: jobId,
clinicTenantId: job.clinicTenantId,
labTenantId: job.labTenantId,
action: JobHistoryAction.revisionRequested,
step: job.currentStep,
note: note,
));
return updated;
}
Future<Job> markDelivered(String jobId, Job job, {String? note}) async {
final record = await _pb.collection('jobs').update(jobId, body: {
'status': 'delivered',
});
unawaited(JobHistoryService.instance.append(
jobId: jobId,
clinicTenantId: job.clinicTenantId,
labTenantId: job.labTenantId,
action: JobHistoryAction.delivered,
note: note,
));
return Job.fromJson(record.toJson());
}
Future<Job> cancelJob(String jobId, Job job) async {
final record = await _pb.collection('jobs').update(jobId, body: {
'status': 'cancelled',
});
unawaited(JobHistoryService.instance.append(
jobId: jobId,
clinicTenantId: job.clinicTenantId,
labTenantId: job.labTenantId,
action: JobHistoryAction.cancelled,
));
return Job.fromJson(record.toJson());
}
Future<List<Map<String, dynamic>>> listApprovedLabs(String clinicTenantId) async {
final result = await _pb.collection('connections').getList(
filter: 'clinic_tenant_id = "$clinicTenantId" && status = "approved"',
expand: 'lab_tenant_id',
perPage: 100,
);
return result.items.map((r) {
final expand = r.toJson()['expand'] as Map<String, dynamic>?;
return expand?['lab_tenant_id'] as Map<String, dynamic>? ?? {'id': r.data['lab_tenant_id']};
}).toList();
}
Future<List<Job>> listJobsByPatient(String patientId, {int limit = 50}) async {
final result = await _pb.collection('jobs').getList(
filter: 'patient_id = "$patientId"',
perPage: limit,
expand: _listExpand,
);
return (result.items.map((r) => Job.fromJson(r.toJson())).toList()
..sort((a, b) => b.dateCreated.compareTo(a.dateCreated)));
}
Future<int> countDelivered(String clinicTenantId, {DateTime? from, DateTime? to}) async {
final parts = ['clinic_tenant_id = "$clinicTenantId"', 'status = "delivered"'];
if (from != null) parts.add('updated >= "${_date(from)}"');
if (to != null) parts.add('updated < "${_date(to)}"');
final r = await _pb.collection('jobs').getList(perPage: 1, filter: parts.join(' && '));
return r.totalItems;
}
static String _date(DateTime d) => d.toIso8601String().split('T').first;
}