feat: improve patient flow and pricing workflow
This commit is contained in:
@@ -21,6 +21,7 @@ class FinanceEntry {
|
||||
required this.amount,
|
||||
required this.currency,
|
||||
required this.status,
|
||||
this.counterpartyTenantId,
|
||||
this.paidAt,
|
||||
this.counterpartyName,
|
||||
this.patientCode,
|
||||
@@ -34,6 +35,7 @@ class FinanceEntry {
|
||||
final double amount;
|
||||
final String currency;
|
||||
final FinanceStatus status;
|
||||
final String? counterpartyTenantId;
|
||||
final String? paidAt;
|
||||
final String? counterpartyName;
|
||||
final String? patientCode;
|
||||
@@ -53,6 +55,7 @@ class FinanceEntry {
|
||||
currency: j['currency'] as String? ?? 'TRY',
|
||||
status: FinanceStatus.values.firstWhere((e) => e.value == j['status'],
|
||||
orElse: () => FinanceStatus.pending),
|
||||
counterpartyTenantId: _str(j['counterparty_tenant_id']),
|
||||
paidAt: _str(j['paid_at']),
|
||||
counterpartyName: _str(j['counterparty_name']),
|
||||
patientCode: jobExp?['patient_code'] as String?,
|
||||
@@ -60,3 +63,23 @@ class FinanceEntry {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CounterpartyFinanceSummary {
|
||||
const CounterpartyFinanceSummary({
|
||||
required this.counterpartyName,
|
||||
required this.currency,
|
||||
required this.pendingAmount,
|
||||
required this.paidAmount,
|
||||
required this.entryCount,
|
||||
this.counterpartyTenantId,
|
||||
});
|
||||
|
||||
final String counterpartyName;
|
||||
final String currency;
|
||||
final double pendingAmount;
|
||||
final double paidAmount;
|
||||
final int entryCount;
|
||||
final String? counterpartyTenantId;
|
||||
|
||||
double get totalAmount => pendingAmount + paidAmount;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ enum JobStep {
|
||||
|
||||
enum JobLocation { atClinic, atLab }
|
||||
|
||||
enum JobWorkflowType { arjinat, geleneksel, dijital }
|
||||
|
||||
enum ProstheticType {
|
||||
metalPorselen,
|
||||
zirkonyum,
|
||||
@@ -81,6 +83,20 @@ extension JobStepExt on JobStep {
|
||||
};
|
||||
}
|
||||
|
||||
extension JobWorkflowTypeExt on JobWorkflowType {
|
||||
String get label => switch (this) {
|
||||
JobWorkflowType.arjinat => 'Arjinat',
|
||||
JobWorkflowType.geleneksel => 'Geleneksel',
|
||||
JobWorkflowType.dijital => 'Dijital',
|
||||
};
|
||||
|
||||
String get value => switch (this) {
|
||||
JobWorkflowType.arjinat => 'arjinat',
|
||||
JobWorkflowType.geleneksel => 'geleneksel',
|
||||
JobWorkflowType.dijital => 'dijital',
|
||||
};
|
||||
}
|
||||
|
||||
// ── Prosthetic type ───────────────────────────────────────────────────────────
|
||||
|
||||
extension ProstheticTypeExt on ProstheticType {
|
||||
@@ -146,7 +162,9 @@ class Job {
|
||||
required this.status,
|
||||
required this.dateCreated,
|
||||
this.patientId,
|
||||
this.patientName,
|
||||
this.prostheticId,
|
||||
this.prostheticName,
|
||||
this.teeth = const [],
|
||||
this.color,
|
||||
this.description,
|
||||
@@ -154,6 +172,7 @@ class Job {
|
||||
this.currency,
|
||||
this.currentStep,
|
||||
this.location = JobLocation.atClinic,
|
||||
this.workflowType,
|
||||
this.dueDate,
|
||||
this.clinicName,
|
||||
this.labName,
|
||||
@@ -165,8 +184,10 @@ class Job {
|
||||
final String clinicTenantId;
|
||||
final String labTenantId;
|
||||
final String? patientId;
|
||||
final String? patientName;
|
||||
final String patientCode;
|
||||
final String? prostheticId;
|
||||
final String? prostheticName;
|
||||
final ProstheticType prostheticType;
|
||||
final int memberCount;
|
||||
final List<String> teeth;
|
||||
@@ -177,6 +198,7 @@ class Job {
|
||||
final JobStatus status;
|
||||
final JobStep? currentStep;
|
||||
final JobLocation location;
|
||||
final JobWorkflowType? workflowType;
|
||||
final DateTime? dueDate;
|
||||
final DateTime dateCreated;
|
||||
final List<String> attachments;
|
||||
@@ -192,6 +214,7 @@ class Job {
|
||||
JobStatus? status,
|
||||
JobStep? currentStep,
|
||||
JobLocation? location,
|
||||
JobWorkflowType? workflowType,
|
||||
String? clinicName,
|
||||
String? labName,
|
||||
bool clearCurrentStep = false,
|
||||
@@ -201,8 +224,10 @@ class Job {
|
||||
clinicTenantId: clinicTenantId,
|
||||
labTenantId: labTenantId,
|
||||
patientId: patientId,
|
||||
patientName: patientName,
|
||||
patientCode: patientCode,
|
||||
prostheticId: prostheticId,
|
||||
prostheticName: prostheticName,
|
||||
prostheticType: prostheticType,
|
||||
memberCount: memberCount,
|
||||
teeth: teeth,
|
||||
@@ -213,6 +238,7 @@ class Job {
|
||||
status: status ?? this.status,
|
||||
currentStep: clearCurrentStep ? null : (currentStep ?? this.currentStep),
|
||||
location: location ?? this.location,
|
||||
workflowType: workflowType ?? this.workflowType,
|
||||
dueDate: dueDate,
|
||||
dateCreated: dateCreated,
|
||||
attachments: attachments,
|
||||
@@ -240,6 +266,8 @@ class Job {
|
||||
final expand = j['expand'] as Map<String, dynamic>?;
|
||||
final clinicExp = expand?['clinic_tenant_id'] as Map<String, dynamic>?;
|
||||
final labExp = expand?['lab_tenant_id'] as Map<String, dynamic>?;
|
||||
final patientExp = expand?['patient_id'] as Map<String, dynamic>?;
|
||||
final prostheticExp = expand?['prosthetic_id'] as Map<String, dynamic>?;
|
||||
String? str(dynamic v) {
|
||||
final s = v as String?;
|
||||
return (s == null || s.isEmpty) ? null : s;
|
||||
@@ -250,8 +278,10 @@ class Job {
|
||||
clinicTenantId: j['clinic_tenant_id'] as String,
|
||||
labTenantId: j['lab_tenant_id'] as String,
|
||||
patientId: str(j['patient_id']),
|
||||
patientName: _patientName(patientExp),
|
||||
patientCode: j['patient_code'] as String,
|
||||
prostheticId: str(j['prosthetic_id']),
|
||||
prostheticName: prostheticExp?['name'] as String?,
|
||||
prostheticType: _parseProstheticType(j['prosthetic_type'] as String),
|
||||
memberCount: (j['member_count'] as num).toInt(),
|
||||
teeth: j['teeth'] is List
|
||||
@@ -267,6 +297,9 @@ class Job {
|
||||
: null,
|
||||
location:
|
||||
j['location'] == 'at_lab' ? JobLocation.atLab : JobLocation.atClinic,
|
||||
workflowType: str(j['workflow_type']) != null
|
||||
? _parseWorkflowType(j['workflow_type'] as String)
|
||||
: null,
|
||||
dueDate: str(j['due_date']) != null
|
||||
? DateTime.parse(j['due_date'] as String)
|
||||
: null,
|
||||
@@ -299,6 +332,25 @@ class Job {
|
||||
_ => JobStep.olcu,
|
||||
};
|
||||
|
||||
static JobWorkflowType _parseWorkflowType(String s) => switch (s) {
|
||||
'arjinat' => JobWorkflowType.arjinat,
|
||||
'dijital' => JobWorkflowType.dijital,
|
||||
_ => JobWorkflowType.geleneksel,
|
||||
};
|
||||
|
||||
static String? _patientName(Map<String, dynamic>? patientExp) {
|
||||
if (patientExp == null) return null;
|
||||
final first = (patientExp['first_name'] as String?)?.trim();
|
||||
final last = (patientExp['last_name'] as String?)?.trim();
|
||||
final parts = [first, last]
|
||||
.where((part) => part != null && part.isNotEmpty)
|
||||
.cast<String>()
|
||||
.toList();
|
||||
if (parts.isNotEmpty) return parts.join(' ');
|
||||
final code = (patientExp['patient_code'] as String?)?.trim();
|
||||
return (code == null || code.isEmpty) ? null : code;
|
||||
}
|
||||
|
||||
static ProstheticType _parseProstheticType(String s) => switch (s) {
|
||||
'zirkonyum' => ProstheticType.zirkonyum,
|
||||
'implant_ustu_zirkonyum'=> ProstheticType.implantUstuZirkonyum,
|
||||
|
||||
Reference in New Issue
Block a user