Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: downgrade team functionality when payment subscription has expired #2092

Merged

Conversation

ShubhamPalriwala
Copy link
Member

What does this PR do?

Downgrades the team's ability to change Link Survey Branding & In App Branding when respective paid plans are downgraded in stripe ie end of month!

How should this be tested?

  • Configure Stripe CLI to pass webhooks locally
  • Upgrade Team plan
  • Cancel it
  • Now edit product look and feel to disable branding
  • Run subscription sim clock on stripe to a month later so that the sub expires till then
  • Now visit the look and feel, it should be on & disabled (since plan expired)

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read How we Code at Formbricks
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand bits
  • Ran pnpm build
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Formbricks Docs if changes were necessary

Copy link

vercel bot commented Feb 16, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Ignored Deployments
Name Status Preview Updated (UTC)
formbricks-cloud ⬜️ Ignored (Inspect) Feb 16, 2024 0:48am
formbricks-com ⬜️ Ignored (Inspect) Feb 16, 2024 0:48am

Copy link
Contributor

Thank you for following the naming conventions for pull request titles! 🙏

Copy link
Contributor

packages/ee/billing/lib/downgradePlan.ts

Instead of calling the updateProduct function inside the loop, you can collect all the products that need to be updated and then perform a batch update. This will reduce the number of database calls and improve the performance of your code.
Create Issue
See the diff
Checkout the fix

    export const unsubscribeLinkSurveyProFeatures = async (teamId: string) => {
      const productsOfTeam = await getProducts(teamId);
      const productsToUpdate = productsOfTeam.filter(product => !product.linkSurveyBranding);
      await Promise.all(productsToUpdate.map(product => updateProduct(product.id, { linkSurveyBranding: true })));
    };

    export const unsubscribeCoreAndAppSurveyFeatures = async (teamId: string) => {
      const productsOfTeam = await getProducts(teamId);
      const productsToUpdate = productsOfTeam.filter(product => !product.inAppSurveyBranding);
      await Promise.all(productsToUpdate.map(product => updateProduct(product.id, { inAppSurveyBranding: true })));
    };
git fetch origin && git checkout -b ReviewBot/Impro-29ptpsy origin/ReviewBot/Impro-29ptpsy

packages/ee/billing/handlers/subscriptionDeleted.ts

There is a lot of repeated code in the handleSubscriptionDeleted function. You can create a helper function to handle the updating of the features and the calling of the unsubscribe functions. This will make your code more DRY (Don't Repeat Yourself) and easier to read.
Create Issue
See the diff
Checkout the fix

    const updateFeaturesAndUnsubscribe = async (teamId: string, featureKey: keyof typeof team.billing.features, unsubscribeFunction: Function) => {
      updatedFeatures[featureKey].status = "inactive";
      updatedFeatures[featureKey].unlimited = false;
      await unsubscribeFunction(teamId);
    }

    // Then in your switch statement
    switch (product.name) {
      case StripeProductNames.inAppSurvey:
        await updateFeaturesAndUnsubscribe(teamId, ProductFeatureKeys.inAppSurvey, unsubscribeCoreAndAppSurveyFeatures);
        break;
      case StripeProductNames.linkSurvey:
        await updateFeaturesAndUnsubscribe(teamId, ProductFeatureKeys.linkSurvey, unsubscribeLinkSurveyProFeatures);
        break;
      case StripeProductNames.userTargeting:
        await updateFeaturesAndUnsubscribe(teamId, ProductFeatureKeys.userTargeting);
        break;
    }
git fetch origin && git checkout -b ReviewBot/Impro-t8dztob origin/ReviewBot/Impro-t8dztob

Comment on lines +3 to +22
export const unsubscribeLinkSurveyProFeatures = async (teamId: string) => {
const productsOfTeam = await getProducts(teamId);
for (const product of productsOfTeam) {
if (!product.linkSurveyBranding) {
await updateProduct(product.id, {
linkSurveyBranding: true,
});
}
}
};

export const unsubscribeCoreAndAppSurveyFeatures = async (teamId: string) => {
const productsOfTeam = await getProducts(teamId);
for (const product of productsOfTeam) {
if (!product.inAppSurveyBranding) {
await updateProduct(product.id, {
inAppSurveyBranding: true,
});
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code has been modified to collect all the products that need to be updated and then perform a batch update. This reduces the number of database calls and improves the performance of the code.

Suggested change
export const unsubscribeLinkSurveyProFeatures = async (teamId: string) => {
const productsOfTeam = await getProducts(teamId);
for (const product of productsOfTeam) {
if (!product.linkSurveyBranding) {
await updateProduct(product.id, {
linkSurveyBranding: true,
});
}
}
};
export const unsubscribeCoreAndAppSurveyFeatures = async (teamId: string) => {
const productsOfTeam = await getProducts(teamId);
for (const product of productsOfTeam) {
if (!product.inAppSurveyBranding) {
await updateProduct(product.id, {
inAppSurveyBranding: true,
});
}
}
export const unsubscribeLinkSurveyProFeatures = async (teamId: string) => {
const productsOfTeam = await getProducts(teamId);
const productsToUpdate = productsOfTeam.filter(product => !product.linkSurveyBranding);
await Promise.all(productsToUpdate.map(product => updateProduct(product.id, { linkSurveyBranding: true })));
};
export const unsubscribeCoreAndAppSurveyFeatures = async (teamId: string) => {
const productsOfTeam = await getProducts(teamId);
const productsToUpdate = productsOfTeam.filter(product => !product.inAppSurveyBranding);
await Promise.all(productsToUpdate.map(product => updateProduct(product.id, { inAppSurveyBranding: true })));
};

Copy link
Member

@mattinannt mattinannt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ShubhamPalriwala thanks for adding the unsubscribe functionality 😊

@mattinannt mattinannt added this pull request to the merge queue Feb 19, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 19, 2024
@mattinannt mattinannt added this pull request to the merge queue Feb 19, 2024
Merged via the queue into main with commit 6ae782b Feb 19, 2024
15 checks passed
@mattinannt mattinannt deleted the shubham/for-1882-switch-branding-on-after-unsubscribe branch February 19, 2024 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants