upload method
Implementation
Future<List<TrackedEntityInstance>?> 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<TrackedEntityInstance> trackedEntityInstances = await this
.where(attribute: 'synced', value: false)
.where(attribute: 'dirty', value: true)
.get();
callback(
RequestProgress(
resourceName: this.apiResourceName as String,
message:
'${trackedEntityInstances.length} ${this.apiResourceName?.toLowerCase()} retrieved successfully',
status: '',
percentage: 50),
false);
callback(
RequestProgress(
resourceName: this.apiResourceName as String,
message:
'Uploading ${trackedEntityInstances.length} ${this.apiResourceName?.toLowerCase()} into the server...',
status: '',
percentage: 51),
false);
final List<String> trackedEntityInstanceIds = trackedEntityInstances
.map((trackedEntityInstance) => trackedEntityInstance.id as String)
.toList();
List<TrackedEntityAttributeValue> attributes =
await TrackedEntityAttributeValueQuery()
.whereIn(
attribute: 'trackedEntityInstance',
values: trackedEntityInstanceIds,
merge: false)
.get();
List<Enrollment> enrollments = await EnrollmentQuery()
.whereIn(
attribute: 'trackedEntityInstance',
values: trackedEntityInstanceIds,
merge: false)
.get();
final trackedEntityInstanceUploadPayload =
trackedEntityInstances.map((trackedEntityInstance) {
trackedEntityInstance.attributes = attributes
.where((attribute) =>
attribute.trackedEntityInstance == trackedEntityInstance.id)
.toList();
trackedEntityInstance.enrollments = enrollments
.where((enrollment) =>
enrollment.trackedEntityInstance == trackedEntityInstance.id)
.toList();
return TrackedEntityInstance.toUpload(trackedEntityInstance);
}).toList();
final response = await HttpClient.post(this.apiResourceName as String,
{'trackedEntityInstances': trackedEntityInstanceUploadPayload},
database: this.database, dioTestClient: dioTestClient);
callback(
RequestProgress(
resourceName: this.apiResourceName as String,
message:
'Upload for ${trackedEntityInstances.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;
trackedEntityInstances.forEach((trackedEntityInstance) {
final importSummary = importSummaries.lastWhere(
(summary) => summary['reference'] == trackedEntityInstance.id,
orElse: (() => null));
if (importSummary != null) {
availableItemCount++;
final syncFailed = importSummary['status'] == 'ERROR';
trackedEntityInstance.synced = !syncFailed;
trackedEntityInstance.dirty = true;
trackedEntityInstance.syncFailed = syncFailed;
trackedEntityInstance.lastSyncDate =
DateTime.now().toIso8601String().split('.')[0];
trackedEntityInstance.lastSyncSummary = importSummary.toString();
queue.add(() =>
TrackedEntityInstanceQuery().setData(trackedEntityInstance).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 TrackedEntityInstanceQuery()
.byIds(trackedEntityInstanceIds)
.get();
}