2021-10-22 23:08:09 +00:00
|
|
|
import 'package:diameter/models/log_meal.dart';
|
|
|
|
import 'package:diameter/utils/utils.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';
|
|
|
|
import 'package:diameter/models/log_event.dart';
|
|
|
|
|
|
|
|
class LogEntry {
|
|
|
|
late String? objectId;
|
|
|
|
late DateTime time;
|
|
|
|
late int? mgPerDl;
|
|
|
|
late double? mmolPerL;
|
|
|
|
late double? bolusGlucose;
|
|
|
|
late int? delayedBolusDuration;
|
|
|
|
// TODO: either rename this or all other fields using delayedBolusRate
|
|
|
|
late double? delayedBolusRatio;
|
|
|
|
late String? notes;
|
|
|
|
late Future<List<LogEvent>> events;
|
|
|
|
late Future<List<LogEvent>> endedEvents;
|
|
|
|
late Future<List<LogMeal>> meals;
|
|
|
|
|
|
|
|
LogEntry(ParseObject object) {
|
|
|
|
objectId = object.get<String>('objectId');
|
2021-10-26 23:25:40 +00:00
|
|
|
time = object.get<DateTime>('time')!.toLocal();
|
2021-10-22 23:08:09 +00:00
|
|
|
mgPerDl = object.get<num>('mgPerDl') != null
|
|
|
|
? object.get<num>('mgPerDl')!.toInt()
|
|
|
|
: null;
|
|
|
|
mmolPerL = object.get<num>('mmolPerL') != null
|
|
|
|
? object.get<num>('mmolPerL')!.toDouble()
|
|
|
|
: null;
|
|
|
|
bolusGlucose = object.get<num>('bolusGlucose') != null
|
|
|
|
? object.get<num>('bolusGlucose')!.toDouble()
|
|
|
|
: null;
|
|
|
|
delayedBolusDuration = object.get<num>('delayedBolusDuration') != null
|
|
|
|
? object.get<num>('delayedBolusDuration')!.toInt()
|
|
|
|
: null;
|
|
|
|
delayedBolusRatio = object.get<num>('delayedBolusRatio') != null
|
|
|
|
? object.get<num>('delayedBolusRatio')!.toDouble()
|
|
|
|
: null;
|
|
|
|
events = LogEvent.fetchAllForLogEntry(this);
|
|
|
|
endedEvents = LogEvent.fetchAllEndedByEntry(this);
|
|
|
|
meals = LogMeal.fetchAllForLogEntry(this);
|
|
|
|
notes = object.get<String>('notes');
|
|
|
|
}
|
|
|
|
|
2021-10-23 20:57:37 +00:00
|
|
|
static Future<Map<DateTime, List<LogEntry>>> createDailyEntryMap() async {
|
|
|
|
Map<DateTime, List<LogEntry>> dateMap = <DateTime, List<LogEntry>>{};
|
|
|
|
List<LogEntry> entries = await fetchAll();
|
|
|
|
DateTime? date;
|
|
|
|
|
|
|
|
for (LogEntry entry in entries) {
|
|
|
|
date = DateTime.utc(entry.time.year, entry.time.month, entry.time.day);
|
|
|
|
dateMap.putIfAbsent(date, () => <LogEntry>[]).add(entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dateMap;
|
|
|
|
}
|
|
|
|
|
2021-10-22 23:08:09 +00:00
|
|
|
static Future<List<LogEntry>> fetchAllForRange(DateTimeRange range) async {
|
|
|
|
QueryBuilder<ParseObject> query =
|
|
|
|
QueryBuilder<ParseObject>(ParseObject('LogEntry'))
|
2021-10-26 23:25:40 +00:00
|
|
|
..whereGreaterThanOrEqualsTo('time', range.start.toUtc())
|
|
|
|
..whereLessThanOrEqualTo('time', range.end.toUtc())
|
2021-10-23 20:57:37 +00:00
|
|
|
..orderByAscending('time');
|
2021-10-22 23:08:09 +00:00
|
|
|
final ParseResponse apiResponse = await query.query();
|
|
|
|
|
|
|
|
if (apiResponse.success && apiResponse.results != null) {
|
|
|
|
return apiResponse.results!
|
|
|
|
.map((e) => LogEntry(e as ParseObject))
|
|
|
|
.toList();
|
|
|
|
} else {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Future<List<LogEntry>> fetchAll() async {
|
2021-10-23 20:57:37 +00:00
|
|
|
// TODO: consider adding pagination/lazy loading here
|
2021-10-22 23:08:09 +00:00
|
|
|
QueryBuilder<ParseObject> query =
|
2021-10-23 20:57:37 +00:00
|
|
|
QueryBuilder<ParseObject>(ParseObject('LogEntry'))
|
|
|
|
..orderByAscending('time');
|
|
|
|
;
|
2021-10-22 23:08:09 +00:00
|
|
|
final ParseResponse apiResponse = await query.query();
|
|
|
|
|
|
|
|
if (apiResponse.success && apiResponse.results != null) {
|
|
|
|
return apiResponse.results!
|
|
|
|
.map((e) => LogEntry(e as ParseObject))
|
|
|
|
.toList();
|
|
|
|
} else {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Future<LogEntry?> get(String objectId) async {
|
|
|
|
QueryBuilder<ParseObject> query =
|
|
|
|
QueryBuilder<ParseObject>(ParseObject('LogEntry'))
|
|
|
|
..whereEqualTo('objectId', objectId);
|
|
|
|
final ParseResponse apiResponse = await query.query();
|
|
|
|
|
|
|
|
if (apiResponse.success && apiResponse.results != null) {
|
|
|
|
return LogEntry(apiResponse.result.first);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Future<void> save({
|
|
|
|
required DateTime time,
|
|
|
|
int? mgPerDl,
|
|
|
|
double? mmolPerL,
|
|
|
|
double? bolusGlucose,
|
|
|
|
int? delayedBolusDuration,
|
|
|
|
double? delayedBolusRatio,
|
|
|
|
String? notes,
|
|
|
|
}) async {
|
|
|
|
final logEntry = ParseObject('LogEntry')
|
2021-10-26 23:25:40 +00:00
|
|
|
..set('time', time.toUtc())
|
2021-10-22 23:08:09 +00:00
|
|
|
..set('bolusGlucose', bolusGlucose)
|
|
|
|
..set('delayedBolusDuration', delayedBolusDuration)
|
|
|
|
..set('delayedBolusRatio', delayedBolusRatio)
|
|
|
|
..set('notes', notes);
|
|
|
|
|
|
|
|
if (!(mgPerDl == null && mmolPerL == null)) {
|
|
|
|
logEntry.set(
|
|
|
|
'mgPerDl',
|
|
|
|
mgPerDl != null
|
|
|
|
? mgPerDl.round()
|
|
|
|
: Utils.convertMmolPerLToMgPerDl(mmolPerL ?? 0));
|
|
|
|
logEntry.set(
|
|
|
|
'mmolPerL',
|
|
|
|
mmolPerL != null
|
|
|
|
? mmolPerL * 100
|
|
|
|
: Utils.convertMgPerDlToMmolPerL(mgPerDl ?? 0) * 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
await logEntry.save();
|
|
|
|
}
|
|
|
|
|
|
|
|
static Future<void> update(
|
|
|
|
String objectId, {
|
|
|
|
DateTime? time,
|
|
|
|
int? mgPerDl,
|
|
|
|
double? mmolPerL,
|
|
|
|
double? bolusGlucose,
|
|
|
|
int? delayedBolusDuration,
|
|
|
|
double? delayedBolusRatio,
|
|
|
|
String? notes,
|
|
|
|
}) async {
|
|
|
|
final logEntry = ParseObject('LogEntry');
|
|
|
|
|
|
|
|
if (time != null) {
|
2021-10-26 23:25:40 +00:00
|
|
|
logEntry.set('time', time.toUtc());
|
2021-10-22 23:08:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bolusGlucose != null) {
|
|
|
|
logEntry.set('bolusGlucose', bolusGlucose);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (delayedBolusDuration != null) {
|
|
|
|
logEntry.set('delayedBolusDuration', delayedBolusDuration);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (delayedBolusRatio != null) {
|
|
|
|
logEntry.set('delayedBolusRatio', delayedBolusRatio);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (notes != null) {
|
|
|
|
logEntry.set('notes', notes);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(mgPerDl == null && mmolPerL == null)) {
|
|
|
|
logEntry.set(
|
|
|
|
'mgPerDl',
|
|
|
|
mgPerDl != null
|
|
|
|
? mgPerDl.round()
|
|
|
|
: Utils.convertMmolPerLToMgPerDl(mmolPerL ?? 0));
|
|
|
|
logEntry.set(
|
|
|
|
'mmolPerL',
|
|
|
|
mmolPerL != null
|
|
|
|
? mmolPerL * 100
|
|
|
|
: Utils.convertMgPerDlToMmolPerL(mgPerDl ?? 0) * 100);
|
|
|
|
}
|
|
|
|
await logEntry.save();
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> delete() async {
|
|
|
|
var logEntry = ParseObject('LogEntry')..objectId = objectId;
|
|
|
|
await logEntry.delete();
|
|
|
|
}
|
|
|
|
}
|