|
|
|
|
@ -4,13 +4,17 @@ import 'package:hmg_patient_app_new/features/active_prescriptions/models/active_
|
|
|
|
|
import 'package:hmg_patient_app_new/features/active_prescriptions/active_prescriptions_repo.dart';
|
|
|
|
|
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
|
|
|
|
|
|
|
|
|
|
class ActivePrescriptionsViewModel extends ChangeNotifier {
|
|
|
|
|
class ActivePrescriptionsViewModel extends ChangeNotifier {
|
|
|
|
|
bool isActivePrescriptionsDetailsLoading = false;
|
|
|
|
|
|
|
|
|
|
late ActivePrescriptionsRepo activePrescriptionsRepo;
|
|
|
|
|
late ActivePrescriptionsRepo activePrescriptionsRepo;
|
|
|
|
|
late ErrorHandlerService errorHandlerService;
|
|
|
|
|
|
|
|
|
|
// Prescription Orders Lists
|
|
|
|
|
ActivePrescriptionsViewModel({
|
|
|
|
|
required this.activePrescriptionsRepo,
|
|
|
|
|
required this.errorHandlerService,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
List<ActivePrescriptionsResponseModel> activePrescriptionsDetailsList = [];
|
|
|
|
|
|
|
|
|
|
initActivePrescriptionsViewModel() {
|
|
|
|
|
@ -20,38 +24,172 @@ class ActivePrescriptionsViewModel extends ChangeNotifier {
|
|
|
|
|
|
|
|
|
|
setPrescriptionsDetailsLoading() {
|
|
|
|
|
isActivePrescriptionsDetailsLoading = true;
|
|
|
|
|
// activePrescriptionsDetailsList.clear();
|
|
|
|
|
notifyListeners();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> getActiveMedications( {Function(dynamic)? onSuccess, Function(String)? onError})
|
|
|
|
|
async {
|
|
|
|
|
// Get medications list
|
|
|
|
|
Future<void> getActiveMedications({
|
|
|
|
|
Function(dynamic)? onSuccess,
|
|
|
|
|
Function(String)? onError,
|
|
|
|
|
}) async {
|
|
|
|
|
final result = await activePrescriptionsRepo.getActivePrescriptionsDetails();
|
|
|
|
|
result.fold(
|
|
|
|
|
(failure) async => await errorHandlerService.handleError(failure: failure),
|
|
|
|
|
(apiResponse) {
|
|
|
|
|
if (apiResponse.messageStatus == 2) {
|
|
|
|
|
// dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
|
|
|
|
|
} else if (apiResponse.messageStatus == 1) {
|
|
|
|
|
activePrescriptionsDetailsList = apiResponse.data!;
|
|
|
|
|
isActivePrescriptionsDetailsLoading = false;
|
|
|
|
|
if (apiResponse.messageStatus == 1) {
|
|
|
|
|
activePrescriptionsDetailsList = apiResponse.data ?? [];
|
|
|
|
|
notifyListeners();
|
|
|
|
|
if (onSuccess != null) {
|
|
|
|
|
onSuccess(apiResponse);
|
|
|
|
|
print(activePrescriptionsDetailsList.length);
|
|
|
|
|
}
|
|
|
|
|
if (onSuccess != null) onSuccess(apiResponse.data);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DateTime parseDate(String? date) {
|
|
|
|
|
if (date == null) return DateTime.now();
|
|
|
|
|
final regex = RegExp(r"\/Date\((\d+)([+-]\d+)?\)\/");
|
|
|
|
|
final match = regex.firstMatch(date);
|
|
|
|
|
if (match != null) {
|
|
|
|
|
final millis = int.parse(match.group(1)!);
|
|
|
|
|
return DateTime.fromMillisecondsSinceEpoch(millis);
|
|
|
|
|
}
|
|
|
|
|
return DateTime.tryParse(date) ?? DateTime.now();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Extract numeric value ( "3 / week" → 3)
|
|
|
|
|
int extractNumberFromFrequency(String? frequency) {
|
|
|
|
|
if (frequency == null) return 1;
|
|
|
|
|
final m = RegExp(r'(\d+)').firstMatch(frequency);
|
|
|
|
|
if (m != null) return int.tryParse(m.group(1)!) ?? 1;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate medication days based on frequency text
|
|
|
|
|
List<DateTime> generateMedicationDays(ActivePrescriptionsResponseModel med) {
|
|
|
|
|
final start = parseDate(med.startDate);
|
|
|
|
|
final duration = med.days ?? 0;
|
|
|
|
|
final frequency = (med.frequency ?? "").toLowerCase().trim();
|
|
|
|
|
|
|
|
|
|
List<DateTime> result = [];
|
|
|
|
|
if (duration <= 0) return result;
|
|
|
|
|
|
|
|
|
|
// Every N hours ( "Every Six Hours", "Every 8 hours")
|
|
|
|
|
if (frequency.contains("hour")) {
|
|
|
|
|
final match = RegExp(r'every\s+(\d+)').firstMatch(frequency);
|
|
|
|
|
int intervalHours = 0;
|
|
|
|
|
|
|
|
|
|
if (match != null) {
|
|
|
|
|
intervalHours = int.tryParse(match.group(1)!) ?? 0;
|
|
|
|
|
} else {
|
|
|
|
|
// handle text numbers like "Every six hours"
|
|
|
|
|
final textNum = {
|
|
|
|
|
"one": 1,
|
|
|
|
|
"two": 2,
|
|
|
|
|
"three": 3,
|
|
|
|
|
"four": 4,
|
|
|
|
|
"five": 5,
|
|
|
|
|
"six": 6,
|
|
|
|
|
"seven": 7,
|
|
|
|
|
"eight": 8,
|
|
|
|
|
"nine": 9,
|
|
|
|
|
"ten": 10,
|
|
|
|
|
"twelve": 12,
|
|
|
|
|
};
|
|
|
|
|
for (var key in textNum.keys) {
|
|
|
|
|
if (frequency.contains(key)) {
|
|
|
|
|
intervalHours = textNum[key]!;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (intervalHours > 0) {
|
|
|
|
|
for (int day = 0; day < duration; day++) {
|
|
|
|
|
final dayStart = start.add(Duration(days: day));
|
|
|
|
|
for (int hour = 0; hour < 24; hour += intervalHours) {
|
|
|
|
|
result.add(DateTime(dayStart.year, dayStart.month, dayStart.day, hour));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Daily (every day)
|
|
|
|
|
if (frequency.contains("day") &&
|
|
|
|
|
!frequency.contains("every other") &&
|
|
|
|
|
!frequency.contains("every ")) {
|
|
|
|
|
for (int i = 0; i < duration; i++) {
|
|
|
|
|
result.add(start.add(Duration(days: i)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Every other day
|
|
|
|
|
else if (frequency.contains("every other day")) {
|
|
|
|
|
for (int i = 0; i < duration; i += 2) {
|
|
|
|
|
result.add(start.add(Duration(days: i)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Every N days → e.g. "Every 3 days", "Every 5 days"
|
|
|
|
|
else if (frequency.contains("every") && frequency.contains("day")) {
|
|
|
|
|
final match = RegExp(r'every\s+(\d+)').firstMatch(frequency);
|
|
|
|
|
final interval = match != null ? int.tryParse(match.group(1)!) ?? 1 : 1;
|
|
|
|
|
for (int i = 0; i < duration; i += interval) {
|
|
|
|
|
result.add(start.add(Duration(days: i)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Once or twice a week
|
|
|
|
|
else if (frequency.contains("once a week")) {
|
|
|
|
|
for (int i = 0; i < duration; i += 7) {
|
|
|
|
|
result.add(start.add(Duration(days: i)));
|
|
|
|
|
}
|
|
|
|
|
} else if (frequency.contains("twice a week")) {
|
|
|
|
|
for (int i = 0; i < duration; i += 3) {
|
|
|
|
|
result.add(start.add(Duration(days: i)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Numeric frequency like "3 / week", "2 / week"
|
|
|
|
|
else if (frequency.contains("week")) {
|
|
|
|
|
int timesPerWeek = extractNumberFromFrequency(frequency);
|
|
|
|
|
double interval = 7 / timesPerWeek;
|
|
|
|
|
double dayPointer = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < duration; i++) {
|
|
|
|
|
if (i >= dayPointer.floor()) {
|
|
|
|
|
result.add(start.add(Duration(days: i)));
|
|
|
|
|
dayPointer += interval;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
result.add(start);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final unique = <String, DateTime>{};
|
|
|
|
|
for (final d in result) {
|
|
|
|
|
unique["${d.year}-${d.month}-${d.day}"] = d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return unique.values.toList()..sort((a, b) => a.compareTo(b));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool sameYMD(DateTime a, DateTime b) =>
|
|
|
|
|
a.year == b.year && a.month == b.month && a.day == b.day;
|
|
|
|
|
|
|
|
|
|
// Filter medications for selected day
|
|
|
|
|
List<ActivePrescriptionsResponseModel> getMedsForSelectedDay(DateTime selectedDate) {
|
|
|
|
|
final target = DateTime(selectedDate.year, selectedDate.month, selectedDate.day);
|
|
|
|
|
return activePrescriptionsDetailsList.where((med) {
|
|
|
|
|
final days = generateMedicationDays(med);
|
|
|
|
|
return days.any((d) => sameYMD(d, target));
|
|
|
|
|
}).toList();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|