upload method
Implementation
Future<List<Event>?> upload(Function(RequestProgress, bool) callback,
{Dio? dioTestClient, String? resource}) 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)
.withDataValues()
.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 = events.map((event) => event.id as String).toList();
final eventUploadPayload = [];
for (Event event in events) {
if (event.programStage != null) {
ProgramStage programStage = await ProgramStageQuery(database: database)
.byId(event.programStage)
.getOne();
dynamic eventPayload = Event.toUpload(event);
eventPayload['program'] = programStage.program;
eventUploadPayload.add(eventPayload);
} else {
dynamic eventPayload = Event.toUpload(event);
eventUploadPayload.add(eventPayload);
}
}
final response = await HttpClient.post(
resource ?? 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.runtimeType == String
? [
{
"responseType": "ImportSummary",
"status": "ERROR",
"reference": "",
"enrollments": {
"responseType": "ImportSummary",
"status": "ERROR",
"imported": 0,
"updated": 0,
"ignored": 1,
"deleted": 0,
"importSummaries:": [],
"total": 0
},
"importCount": {
"imported": 0,
"updated": 0,
"ignored": 1,
"deleted": 0
},
"total": 0,
"importSummaries:": [],
"conflicts": [
{
"object": "Server.ERROR",
"value": '${response.body.toString()}: ${response.statusCode}'
}
]
}
]
: response.body['status'] != null &&
response.body['status'] == 'OK' &&
response.body['validationReport'] != null
? [
{
"responseType": "ImportSummary",
"status": "SUCCESS",
"reference": eventIds[0],
"enrollments": {
"responseType": "ImportSummary",
"status": "ERROR",
"imported": 0,
"updated": 1,
"ignored": 0,
"deleted": 0,
"importSummaries:": [
{
"responseType": "ImportSummary",
"status": "SUCCESS",
"importCount": {
"imported": 0,
"updated": 1,
"ignored": 0,
"deleted": 0
},
"conflicts": [],
"reference": "a6vUjBH0UUj"
}
],
"total": 0
},
"importCount": {
"imported": 1,
"updated": 1,
"ignored": 0,
"deleted": 0
},
"total": 1,
"importSummaries:": [],
"conflicts": []
}
]
: (response.body?['response']?['importSummaries'] ?? []).toList();
final queue = Queue(parallel: 50);
num availableItemCount = 0;
if (instanceVersion != null && instanceVersion! >= 38) {
final lastestVersionResponse =
LatestVersionResponse.fromJson(response.body);
final objectReport = lastestVersionResponse
.bundleReport?.typeReportMap?.event?.objectReports;
events.forEach((event) {
final importSummary =
objectReport?.lastWhere((summary) => summary.uid == event.id);
if (importSummary != null) {
availableItemCount++;
final syncFailed = lastestVersionResponse.status == 'ERROR';
event.synced = !syncFailed;
event.dirty = true;
event.syncFailed = syncFailed;
event.lastSyncDate = DateTime.now().toIso8601String();
event.lastUpdated = DateTime.now().toIso8601String();
queue.add(() => EventQuery(database: database).setData(event).save());
}
});
} else {
events.forEach((event) {
final importSummary = importSummaries.lastWhere(
(summary) =>
summary['reference'] != null && summary['reference'] == event.id,
orElse: () => null,
);
if (importSummary != null) {
availableItemCount++;
final syncFailed = importSummary['status'] == 'ERROR';
event.synced = !syncFailed;
event.dirty = true;
event.syncFailed = syncFailed;
event.lastSyncDate = DateTime.now().toIso8601String();
event.lastUpdated = DateTime.now().toIso8601String();
event.lastSyncSummary = EventImportSummary.fromJson(importSummary);
queue.add(() => EventQuery(database: database).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(database: database).byIds(eventIds).get();
}