module.exports = (data, progress, resolve, reject) => { const loggedProfileRef = firebase.database() .ref(`loggedActivities/${data.datetime}/${data.profileUid}`); const profileChallengesRef = firebase.database() .ref(`profileChallenges/${data.profileUid}`); const selectedActivity = getActivity(activities, data.activityKey); const selectedActivitySubCategory = getSubCategory(activities, data.activityKey); const transactionCallback = toggleLoggedActivity(data, activities, selectedActivity, selectedActivitySubCategory); let existingActivities = {}; let updatedActivities = {}; let loggedActivitiesDetails = []; let activeChallengesKeys = []; let pointsToBeModified = 0; let co2ToBeModified = 0; utils.getValue(loggedProfileRef) .then((value) => { if (value !== null) { existingActivities = value.activities; } }) .then(() => { return loggedProfileRef.transaction(transactionCallback); }) .then((result) => { if (result.committed === true) { updatedActivities = result.snapshot.val().activities || {}; if (Object.keys(updatedActivities).length === 0) { loggedProfileRef.remove(); } const tobeModifiedValues = calculatePointsCo2Modified(data, existingActivities, updatedActivities, activities, selectedActivity); co2ToBeModified = tobeModifiedValues.tobeModifiedCo2; pointsToBeModified = tobeModifiedValues.toBeModifiedPoints; loggedActivitiesDetails = tobeModifiedValues.loggedActivitiesPointsCo2; } }) .then(() => { const profileCo2PointsRef = firebase.database().ref(`profiles/${data.profileUid}`); const profileTransactionCallback = updateProfileCo2Points(pointsToBeModified, co2ToBeModified); return profileCo2PointsRef.transaction(profileTransactionCallback); }) .then(() => { const profileActivityCountRef = firebase.database().ref(`profiles/${data.profileUid}/activitiesCount`); const profileTransactionCallback = updateProfileActivityCount(data, existingActivities, updatedActivities); return profileActivityCountRef.transaction(profileTransactionCallback); }) .then(() => { return utils.getValue(profileChallengesRef.orderByChild('challengeEndDatetime') .startAt(Date.now())); }) .then((value) => { if (value) { activeChallengesKeys = Object.keys(value).filter((challengeKey) => { return !Boolean(value[challengeKey].leftDatetime); }); } }) .then(() => { const challengesPointsTransactions = activeChallengesKeys.map((activeChallengeKey) => { const challengesPointsRef = firebase.database() .ref(`challengesPoints/${activeChallengeKey}/${data.datetime}`); const challengesPointsTransactionCallback = updateChallengesPoints(data, pointsToBeModified, co2ToBeModified, loggedActivitiesDetails); return challengesPointsRef.transaction(challengesPointsTransactionCallback); }); return Promise.all(challengesPointsTransactions); }) .then(() => { const challengesAveragePointsTransactions = activeChallengesKeys.map((activeChallengeKey) => { const challengesAveragePointsRef = firebase.database() .ref(`challengesAveragePoints/${activeChallengeKey}/${data.datetime}`); const challengesAveragePointsTransactionCallback = updateChallengesAveragePoints(data, pointsToBeModified, loggedActivitiesDetails); return challengesAveragePointsRef.transaction(challengesAveragePointsTransactionCallback); }); return Promise.all(challengesAveragePointsTransactions); }) .then(() => { const challengesLeaderboardDataTransactions = activeChallengesKeys.map((activeChallengeKey) => { const challengesLeaderboardDataRef = firebase.database() .ref(`challengesLeaderboard/${activeChallengeKey}/${data.profileUid}`); const challengesLeaderboardDataTransactionCallback = updateLeaderboardData(data, pointsToBeModified, co2ToBeModified, loggedActivitiesDetails); return challengesLeaderboardDataRef.transaction(challengesLeaderboardDataTransactionCallback); }); return Promise.all(challengesLeaderboardDataTransactions); }) .then(() => { const challengesLeaderboardPositionTransaction = activeChallengesKeys.map((activeChallengeKey) => { const challengesLeaderboardPositionRef = firebase.database() .ref(`challengesLeaderboard/${activeChallengeKey}`); const challengesLeaderboardsDataTransactionCallback = updateLeaderboardPosition(); return challengesLeaderboardPositionRef.transaction(challengesLeaderboardsDataTransactionCallback); }); return Promise.all(challengesLeaderboardPositionTransaction); }) .then(resolve) .catch(reject); };