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> {
|
||||
let discardError,
|
||||
timePromise,
|
||||
entryId = 0,
|
||||
entryId = entryActions[0].entryid,
|
||||
offlineId,
|
||||
deleted = false;
|
||||
|
||||
const promises = [];
|
||||
|
||||
// Sort entries by timemodified.
|
||||
entryActions = entryActions.sort((a: any, b: any) => a.timemodified - b.timemodified);
|
||||
|
||||
entryId = entryActions[0].entryid;
|
||||
const editAction = entryActions.find((action) => action.action == 'add' || action.action == 'edit');
|
||||
const approveAction = entryActions.find((action) => action.action == 'approve' || action.action == 'disapprove');
|
||||
const deleteAction = entryActions.find((action) => action.action == 'delete');
|
||||
|
||||
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;
|
||||
}).catch(() => {
|
||||
return -1;
|
||||
}).catch((error) => {
|
||||
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;
|
||||
timePromise = Promise.resolve(0);
|
||||
} else {
|
||||
// New entry but the add action is missing, discard.
|
||||
timePromise = Promise.resolve(-1);
|
||||
}
|
||||
|
||||
return timePromise.then((timemodified) => {
|
||||
|
@ -266,58 +272,11 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider {
|
|||
return this.dataOffline.deleteAllEntryActions(data.id, entryId, siteId);
|
||||
}
|
||||
|
||||
entryActions.forEach((action) => {
|
||||
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(() => {
|
||||
deleted = true;
|
||||
});
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
promises.push(actionPromise.catch((error) => {
|
||||
if (error && error.wserror) {
|
||||
if (deleteAction) {
|
||||
return this.dataProvider.deleteEntryOnline(entryId, siteId).then(() => {
|
||||
deleted = true;
|
||||
}).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 {
|
||||
|
@ -328,11 +287,79 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider {
|
|||
// Delete the offline data.
|
||||
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(() => {
|
||||
if (discardError) {
|
||||
// Submission was discarded, add a warning.
|
||||
|
|
Loading…
Reference in New Issue