MOBILE-2856 data: Fix syncing entries with multiple actions
parent
6b0f08695f
commit
fccf79bbd2
|
@ -235,26 +235,32 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider {
|
||||||
protected syncEntry(data: any, entryActions: AddonModDataOfflineAction[], result: any, siteId?: string): Promise<any> {
|
protected syncEntry(data: any, entryActions: AddonModDataOfflineAction[], result: any, siteId?: string): Promise<any> {
|
||||||
let discardError,
|
let discardError,
|
||||||
timePromise,
|
timePromise,
|
||||||
entryId = 0,
|
entryId = entryActions[0].entryid,
|
||||||
offlineId,
|
offlineId,
|
||||||
deleted = false;
|
deleted = false;
|
||||||
|
|
||||||
const promises = [];
|
const editAction = entryActions.find((action) => action.action == 'add' || action.action == 'edit');
|
||||||
|
const approveAction = entryActions.find((action) => action.action == 'approve' || action.action == 'disapprove');
|
||||||
// Sort entries by timemodified.
|
const deleteAction = entryActions.find((action) => action.action == 'delete');
|
||||||
entryActions = entryActions.sort((a: any, b: any) => a.timemodified - b.timemodified);
|
|
||||||
|
|
||||||
entryId = entryActions[0].entryid;
|
|
||||||
|
|
||||||
if (entryId > 0) {
|
if (entryId > 0) {
|
||||||
timePromise = this.dataProvider.getEntry(data.id, entryId, false, siteId).then((entry) => {
|
timePromise = this.dataProvider.getEntry(data.id, entryId, true, siteId).then((entry) => {
|
||||||
return entry.entry.timemodified;
|
return entry.entry.timemodified;
|
||||||
}).catch(() => {
|
}).catch((error) => {
|
||||||
return -1;
|
if (error && this.utils.isWebServiceError(error)) {
|
||||||
|
// The WebService has thrown an error, this means the entry has been deleted.
|
||||||
|
return Promise.resolve(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(error);
|
||||||
});
|
});
|
||||||
} else {
|
} else if (editAction) {
|
||||||
|
// New entry.
|
||||||
offlineId = entryId;
|
offlineId = entryId;
|
||||||
timePromise = Promise.resolve(0);
|
timePromise = Promise.resolve(0);
|
||||||
|
} else {
|
||||||
|
// New entry but the add action is missing, discard.
|
||||||
|
timePromise = Promise.resolve(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return timePromise.then((timemodified) => {
|
return timePromise.then((timemodified) => {
|
||||||
|
@ -266,58 +272,11 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider {
|
||||||
return this.dataOffline.deleteAllEntryActions(data.id, entryId, siteId);
|
return this.dataOffline.deleteAllEntryActions(data.id, entryId, siteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
entryActions.forEach((action) => {
|
if (deleteAction) {
|
||||||
let actionPromise;
|
|
||||||
const proms = [];
|
|
||||||
|
|
||||||
entryId = action.entryid > 0 ? action.entryid : entryId;
|
|
||||||
|
|
||||||
if (action.fields) {
|
|
||||||
action.fields.forEach((field) => {
|
|
||||||
// Upload Files if asked.
|
|
||||||
const value = this.textUtils.parseJSON(field.value);
|
|
||||||
if (value.online || value.offline) {
|
|
||||||
let files = value.online || [];
|
|
||||||
const fileProm = value.offline ? this.dataHelper.getStoredFiles(action.dataid, entryId, field.fieldid) :
|
|
||||||
Promise.resolve([]);
|
|
||||||
|
|
||||||
proms.push(fileProm.then((offlineFiles) => {
|
|
||||||
files = files.concat(offlineFiles);
|
|
||||||
|
|
||||||
return this.dataHelper.uploadOrStoreFiles(action.dataid, 0, entryId, field.fieldid, files, false,
|
|
||||||
siteId).then((filesResult) => {
|
|
||||||
field.value = JSON.stringify(filesResult);
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
actionPromise = Promise.all(proms).then(() => {
|
|
||||||
// Perform the action.
|
|
||||||
switch (action.action) {
|
|
||||||
case 'add':
|
|
||||||
return this.dataProvider.addEntryOnline(action.dataid, action.fields, data.groupid, siteId)
|
|
||||||
.then((result) => {
|
|
||||||
entryId = result.newentryid;
|
|
||||||
});
|
|
||||||
case 'edit':
|
|
||||||
return this.dataProvider.editEntryOnline(entryId, action.fields, siteId);
|
|
||||||
case 'approve':
|
|
||||||
return this.dataProvider.approveEntryOnline(entryId, true, siteId);
|
|
||||||
case 'disapprove':
|
|
||||||
return this.dataProvider.approveEntryOnline(entryId, false, siteId);
|
|
||||||
case 'delete':
|
|
||||||
return this.dataProvider.deleteEntryOnline(entryId, siteId).then(() => {
|
return this.dataProvider.deleteEntryOnline(entryId, siteId).then(() => {
|
||||||
deleted = true;
|
deleted = true;
|
||||||
});
|
}).catch((error) => {
|
||||||
default:
|
if (error && this.utils.isWebServiceError(error)) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
promises.push(actionPromise.catch((error) => {
|
|
||||||
if (error && error.wserror) {
|
|
||||||
// The WebService has thrown an error, this means it cannot be performed. Discard.
|
// The WebService has thrown an error, this means it cannot be performed. Discard.
|
||||||
discardError = this.textUtils.getErrorMessageFromError(error);
|
discardError = this.textUtils.getErrorMessageFromError(error);
|
||||||
} else {
|
} else {
|
||||||
|
@ -328,11 +287,79 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider {
|
||||||
// Delete the offline data.
|
// Delete the offline data.
|
||||||
result.updated = true;
|
result.updated = true;
|
||||||
|
|
||||||
return this.dataOffline.deleteEntry(action.dataid, action.entryid, action.action, siteId);
|
return this.dataOffline.deleteAllEntryActions(deleteAction.dataid, deleteAction.entryid, siteId);
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let editPromise;
|
||||||
|
|
||||||
|
if (editAction) {
|
||||||
|
editPromise = Promise.all(editAction.fields.map((field) => {
|
||||||
|
// Upload Files if asked.
|
||||||
|
const value = this.textUtils.parseJSON(field.value);
|
||||||
|
if (value.online || value.offline) {
|
||||||
|
let files = value.online || [];
|
||||||
|
const fileProm = value.offline ?
|
||||||
|
this.dataHelper.getStoredFiles(editAction.dataid, entryId, field.fieldid) :
|
||||||
|
Promise.resolve([]);
|
||||||
|
|
||||||
|
return fileProm.then((offlineFiles) => {
|
||||||
|
files = files.concat(offlineFiles);
|
||||||
|
|
||||||
|
return this.dataHelper.uploadOrStoreFiles(editAction.dataid, 0, entryId, field.fieldid, files,
|
||||||
|
false, siteId).then((filesResult) => {
|
||||||
|
field.value = JSON.stringify(filesResult);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})).then(() => {
|
||||||
|
if (editAction.action == 'add') {
|
||||||
|
return this.dataProvider.addEntryOnline(editAction.dataid, editAction.fields, editAction.groupid, siteId)
|
||||||
|
.then((result) => {
|
||||||
|
entryId = result.newentryid;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return this.dataProvider.editEntryOnline(entryId, editAction.fields, siteId);
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
if (error && this.utils.isWebServiceError(error)) {
|
||||||
|
// The WebService has thrown an error, this means it cannot be performed. Discard.
|
||||||
|
discardError = this.textUtils.getErrorMessageFromError(error);
|
||||||
|
} else {
|
||||||
|
// Couldn't connect to server, reject.
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
// Delete the offline data.
|
||||||
|
result.updated = true;
|
||||||
|
|
||||||
|
return this.dataOffline.deleteEntry(editAction.dataid, editAction.entryid, editAction.action, siteId);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
editPromise = Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (approveAction) {
|
||||||
|
editPromise = editPromise.then(() => {
|
||||||
|
return this.dataProvider.approveEntryOnline(entryId, approveAction.action == 'approve', siteId);
|
||||||
|
}).catch((error) => {
|
||||||
|
if (error && this.utils.isWebServiceError(error)) {
|
||||||
|
// The WebService has thrown an error, this means it cannot be performed. Discard.
|
||||||
|
discardError = this.textUtils.getErrorMessageFromError(error);
|
||||||
|
} else {
|
||||||
|
// Couldn't connect to server, reject.
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
// Delete the offline data.
|
||||||
|
result.updated = true;
|
||||||
|
|
||||||
|
return this.dataOffline.deleteEntry(approveAction.dataid, approveAction.entryid, approveAction.action, siteId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return editPromise;
|
||||||
|
|
||||||
return Promise.all(promises);
|
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if (discardError) {
|
if (discardError) {
|
||||||
// Submission was discarded, add a warning.
|
// Submission was discarded, add a warning.
|
||||||
|
|
Loading…
Reference in New Issue