mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 14:17:22 +01:00
Group plans subs to all (#8394)
* Added subscriptions to all members when group subs * Added unsub when group cancels * Give user a subscription when they join a subbed group * Removed subscription when user leaves or is removed from group * Fixed linting issues: * Added tests for users with a subscription being upgraded to group plan * Added tests for checking if existing recurring user sub gets updated during group plan. Added better merging for plans * Added test for existing gift subscriptions * Added additional months to user when they have an existing recurring subscription and get upgraded to group sub * Adds test for user who has cancelled with date termined in the future * Added test to ensure date termined is reset * Added tests for extra months carrying over * Added test for gems bought field * Add tests to for fields that should remain when upgrading * Added test for all payment methods * Added prevention for when a user joins a second group plan * Fixed subscribing tests * Separated group plan payment tests * Added prevention of editing a user with a unlimited sub * Add tests to ensure group keeps plan if they are in two and leave one * Ensured users with two group plans do not get cancelled when on group plan is cancelled * Ensured users without group sub are untouched when group cancels * Fixed lint issues * Added new emails * Added fix for cron tests * Add restore to stubbed methods * Ensured cancelled group subscriptions are updated * Changed group plan exist check to check for date terminated * Updated you cannont delete active group message * Removed description requirement * Added upgrade group plan for Amazon payments * Fixed lint issues * Fixed broken tests * Fixed user delete tests * Fixed function calls * Hid cancel button if user has group plan * Hide difficulty from rewards * Prevented add user functions to be called when group plan is cancelled * Fixed merge issue * Correctly displayed group price * Added message when you are about to join canclled group plan * Fixed linting issues * Updated tests to have no redirect to homes * Allowed leaving a group with a canceld subscription * Fixed spelling issues * Prevented user from changing leader with active sub * Added payment details title to replace subscription title * Ensured we do not count leader when displaying upcoming cost * Prevented party tasks from being displayed twice * Prevented cancelling and already cancelled sub * Fixed styles of subscriptions * Added more specific mystery item tests * Fixed test to refer to leader * Extended test range to account for short months * Fixed merge conflicts * Updated yarn file * Added missing locales * Trigger notification * Removed yarn * Fixed locales * Fixed scope mispelling * Fixed line endings * Removed extra advanced options from rewards * Prevent group leader from leaving an active group plan * Fixed issue with extra months applied to cancelled group plan * Ensured member count is calculated when updatedGroupPlan * Updated amazon payment method constant name * Added comment to cancel sub user method * Fixed smantic issues * Added unite test for user isSubscribed and hasNotCancelled * Add tests for isSubscribed and hasNotCanceled * Changed default days remaining to 2 days for group plans * Fixed logic with adding canceled notice to group invite
This commit is contained in:
@@ -387,10 +387,13 @@ api.updateGroup = {
|
||||
|
||||
if (group.leader !== user._id) throw new NotAuthorized(res.t('messageGroupOnlyLeaderCanUpdate'));
|
||||
|
||||
if (req.body.leader !== user._id && group.hasNotCancelled()) throw new NotAuthorized(res.t('cannotChangeLeaderWithActiveGroupPlan'));
|
||||
|
||||
_.assign(group, _.merge(group.toObject(), Group.sanitizeUpdate(req.body)));
|
||||
|
||||
let savedGroup = await group.save();
|
||||
let response = Group.toJSONCleanChat(savedGroup, user);
|
||||
|
||||
// If the leader changed fetch new data, otherwise use authenticated user
|
||||
if (response.leader !== user._id) {
|
||||
let rawLeader = await User.findById(response.leader).select(nameFields).exec();
|
||||
@@ -493,7 +496,10 @@ api.joinGroup = {
|
||||
|
||||
group.memberCount += 1;
|
||||
|
||||
if (group.purchased.plan.customerId) await payments.updateStripeGroupPlan(group);
|
||||
if (group.hasNotCancelled()) {
|
||||
await payments.addSubToGroupUser(user, group);
|
||||
await group.updateGroupPlan();
|
||||
}
|
||||
|
||||
let promises = [group.save(), user.save()];
|
||||
|
||||
@@ -676,7 +682,7 @@ api.leaveGroup = {
|
||||
|
||||
await group.leave(user, req.query.keep, req.body.keepChallenges);
|
||||
|
||||
if (group.purchased.plan && group.purchased.plan.customerId) await payments.updateStripeGroupPlan(group);
|
||||
if (group.hasNotCancelled()) await group.updateGroupPlan(true);
|
||||
|
||||
_removeMessagesFromMember(user, group._id);
|
||||
|
||||
@@ -763,7 +769,10 @@ api.removeGroupMember = {
|
||||
|
||||
if (isInGroup) {
|
||||
group.memberCount -= 1;
|
||||
if (group.purchased.plan.customerId) await payments.updateStripeGroupPlan(group);
|
||||
if (group.hasNotCancelled()) {
|
||||
await group.updateGroupPlan(true);
|
||||
await payments.cancelGroupSubscriptionForUser(member, group);
|
||||
}
|
||||
|
||||
if (group.quest && group.quest.leader === member._id) {
|
||||
group.quest.key = undefined;
|
||||
@@ -831,7 +840,10 @@ async function _inviteByUUID (uuid, group, inviter, req, res) {
|
||||
if (_.find(userToInvite.invitations.guilds, {id: group._id})) {
|
||||
throw new NotAuthorized(res.t('userAlreadyInvitedToGroup'));
|
||||
}
|
||||
userToInvite.invitations.guilds.push({id: group._id, name: group.name, inviter: inviter._id});
|
||||
|
||||
let guildInvite = {id: group._id, name: group.name, inviter: inviter._id};
|
||||
if (group.isSubscribed() && !group.hasNotCancelled()) guildInvite.cancelledPlan = true;
|
||||
userToInvite.invitations.guilds.push(guildInvite);
|
||||
} else if (group.type === 'party') {
|
||||
if (userToInvite.invitations.party.id) {
|
||||
throw new NotAuthorized(res.t('userAlreadyPendingInvitation'));
|
||||
@@ -844,7 +856,9 @@ async function _inviteByUUID (uuid, group, inviter, req, res) {
|
||||
if (userParty && userParty.memberCount !== 1) throw new NotAuthorized(res.t('userAlreadyInAParty'));
|
||||
}
|
||||
|
||||
userToInvite.invitations.party = {id: group._id, name: group.name, inviter: inviter._id};
|
||||
let partyInvite = {id: group._id, name: group.name, inviter: inviter._id};
|
||||
if (group.isSubscribed() && !group.hasNotCancelled()) partyInvite.cancelledPlan = true;
|
||||
userToInvite.invitations.party = partyInvite;
|
||||
}
|
||||
|
||||
let groupLabel = group.type === 'guild' ? 'Guild' : 'Party';
|
||||
@@ -907,10 +921,15 @@ async function _inviteByEmail (invite, group, inviter, req, res) {
|
||||
userReturnInfo = await _inviteByUUID(userToContact._id, group, inviter, req, res);
|
||||
} else {
|
||||
userReturnInfo = invite.email;
|
||||
|
||||
let cancelledPlan = false;
|
||||
if (group.isSubscribed() && !group.hasNotCancelled()) cancelledPlan = true;
|
||||
|
||||
const groupQueryString = JSON.stringify({
|
||||
id: group._id,
|
||||
inviter: inviter._id,
|
||||
sentAt: Date.now(), // so we can let it expire
|
||||
cancelledPlan,
|
||||
});
|
||||
let link = `/static/front?groupInvite=${encrypt(groupQueryString)}`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user