upload method
Implementation
Future<List<Event>?> upload(Function(RequestProgress, bool) callback,
{Dio? dioTestClient}) async {
callback(
RequestProgress(
resourceName: this.apiResourceName as String,
message:
'Retrieving ${this.apiResourceName?.toLowerCase()} from phone database....',
status: '',
percentage: 0),
false);
List<Event> events = await this
.where(attribute: 'synced', value: false)
.where(attribute: 'dirty', value: true)
.get();
callback(
RequestProgress(
resourceName: this.apiResourceName as String,
message:
'${events.length} ${this.apiResourceName?.toLowerCase()} retrieved successfully',
status: '',
percentage: 50),
false);
callback(
RequestProgress(
resourceName: this.apiResourceName as String,
message:
'Uploading ${events.length} ${this.apiResourceName?.toLowerCase()} into the server...',
status: '',
percentage: 51),
false);
List<String> eventIds = [];
List<String> eventProgramStageIds = [];
events.forEach((event) {
eventIds.add(event.id as String);
eventProgramStageIds.removeWhere((id) => id == event.programStage);
eventProgramStageIds.add(event.programStage);
});
List<EventDataValue> eventDataValues = await EventDataValueQuery()
.whereIn(attribute: 'event', values: eventIds, merge: false)
.get();
List<ProgramStage> programStages =
await ProgramStageQuery().byIds(eventProgramStageIds).get();
final eventUploadPayload = events.map((event) {
event.dataValues = eventDataValues
.where((dataValue) => dataValue.event == event.id)
.toList();
event.programStage = programStages
.lastWhere((programStage) => programStage.id == event.programStage)
.toJson();
return Event.toUpload(event);
}).toList();
final response = await HttpClient.post(
this.apiResourceName as String, {'events': eventUploadPayload},
database: this.database, dioTestClient: dioTestClient);
callback(
RequestProgress(
resourceName: this.apiResourceName as String,
message:
'Upload for ${events.length} ${this.apiResourceName?.toLowerCase()} is completed.',
status: '',
percentage: 75),
true);
callback(
RequestProgress(
resourceName: this.apiResourceName as String,
message: 'Saving import summaries into the phone database...',
status: '',
percentage: 76),
true);
final List<dynamic> importSummaries =
(response.body?['response']?['importSummaries'] ?? []).toList();
final queue = Queue(parallel: 50);
num availableItemCount = 0;
events.forEach((event) {
final importSummary = importSummaries.lastWhere((summary) =>
summary['reference'] != null && summary['reference'] == event.id);
if (importSummary != null) {
availableItemCount++;
final syncFailed = importSummary['status'] == 'ERROR';
event.synced = !syncFailed;
event.dirty = true;
event.syncFailed = syncFailed;
event.lastSyncDate = DateTime.now().toIso8601String().split('.')[0];
event.lastSyncSummary = importSummary.toString();
queue.add(() => EventQuery().setData(event).save());
}
});
if (availableItemCount == 0) {
queue.cancel();
} else {
await queue.onComplete;
}
callback(
RequestProgress(
resourceName: this.apiResourceName as String,
message: 'Import summaries saved succussfully',
status: '',
percentage: 100),
true);
return await EventQuery().byIds(eventIds).get();
}