[MM-52158] - Don't show deprecation/move to annual banners to some clients (#22963)

* [MM-52158] - Don't show deprecation/move to annual banners to some clients

* create const

* feedback impl

* update test names

* update banner text

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Allan Guwatudde 2023-04-20 17:04:41 +03:00 committed by GitHub
parent 89f2ebc836
commit 87555aa242
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 119 additions and 4 deletions

View File

@ -103,6 +103,7 @@ func getSubscription(c *Context, w http.ResponseWriter, r *http.Request) {
DNS: "",
LastInvoice: &model.Invoice{},
DelinquentSince: subscription.DelinquentSince,
BillingType: "",
}
}

View File

@ -179,6 +179,7 @@ type Subscription struct {
DelinquentSince *int64 `json:"delinquent_since"`
OriginallyLicensedSeats int `json:"originally_licensed_seats"`
ComplianceBlocked string `json:"compliance_blocked"`
BillingType string `json:"billing_type"`
}
// Subscription History model represents true up event in a yearly subscription

View File

@ -197,6 +197,58 @@ describe('ToYearlyNudgeBannerDismissable', () => {
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-announcement-bar')).toThrow();
});
test('should NOT show when subscription has billing type of internal', () => {
const state = JSON.parse(JSON.stringify(initialState));
state.entities.users.profiles = {
current_user_id: {roles: 'system_admin'},
};
state.entities.cloud = {
subscription: {
product_id: 'prod_professional',
is_free_trial: 'false',
trial_end_at: 1,
billing_type: 'internal',
},
products: {
prod_professional: {
id: 'prod_professional',
sku: CloudProducts.PROFESSIONAL,
recurring_interval: RecurringIntervals.MONTH,
},
},
};
renderWithIntlAndStore(<ToYearlyNudgeBannerDismissable/>, state);
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-announcement-bar')).toThrow();
});
test('should NOT show when subscription has billing type of licensed', () => {
const state = JSON.parse(JSON.stringify(initialState));
state.entities.users.profiles = {
current_user_id: {roles: 'system_admin'},
};
state.entities.cloud = {
subscription: {
product_id: 'prod_professional',
is_free_trial: 'false',
trial_end_at: 1,
billing_type: 'licensed',
},
products: {
prod_professional: {
id: 'prod_professional',
sku: CloudProducts.PROFESSIONAL,
recurring_interval: RecurringIntervals.MONTH,
},
},
};
renderWithIntlAndStore(<ToYearlyNudgeBannerDismissable/>, state);
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-announcement-bar')).toThrow();
});
});
describe('ToYearlyNudgeBanner', () => {
@ -241,6 +293,51 @@ describe('ToYearlyNudgeBanner', () => {
renderWithIntlAndStore(<ToYearlyNudgeBanner/>, state);
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-alert-banner')).toThrow();
});
test('should NOT show when subscription has billing type of internal', () => {
const state = JSON.parse(JSON.stringify(initialState));
state.entities.cloud = {
subscription: {
product_id: 'prod_professional',
is_free_trial: 'false',
trial_end_at: 1,
billing_type: 'internal',
},
products: {
prod_professional: {
id: 'prod_professional',
sku: CloudProducts.PROFESSIONAL,
recurring_interval: RecurringIntervals.MONTH,
},
},
};
renderWithIntlAndStore(<ToYearlyNudgeBanner/>, state);
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-alert-banner')).toThrow();
});
test('should NOT show when subscription has billing type of licensed', () => {
const state = JSON.parse(JSON.stringify(initialState));
state.entities.cloud = {
subscription: {
product_id: 'prod_professional',
is_free_trial: 'false',
trial_end_at: 1,
billing_type: 'licensed',
},
products: {
prod_professional: {
id: 'prod_professional',
sku: CloudProducts.PROFESSIONAL,
recurring_interval: RecurringIntervals.MONTH,
},
},
};
renderWithIntlAndStore(<ToYearlyNudgeBanner/>, state);
expect(() => screen.getByTestId('cloud-pro-monthly-deprecation-alert-banner')).toThrow();
});
});

View File

@ -11,12 +11,12 @@ import useOpenCloudPurchaseModal from 'components/common/hooks/useOpenCloudPurch
import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink';
import AnnouncementBar from 'components/announcement_bar/default_announcement_bar';
import {getSubscriptionProduct as selectSubscriptionProduct} from 'mattermost-redux/selectors/entities/cloud';
import {getSubscriptionProduct as selectSubscriptionProduct, getCloudSubscription as selectCloudSubscription} from 'mattermost-redux/selectors/entities/cloud';
import {getCurrentUser, isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
import {savePreferences} from 'mattermost-redux/actions/preferences';
import {get as getPreference} from 'mattermost-redux/selectors/entities/preferences';
import {AnnouncementBarTypes, CloudBanners, CloudProducts, Preferences, RecurringIntervals} from 'utils/constants';
import {AnnouncementBarTypes, CloudBanners, CloudProducts, Preferences, RecurringIntervals, CloudBillingTypes} from 'utils/constants';
import {t} from 'utils/i18n';
import {GlobalState} from '@mattermost/types/store';
@ -53,6 +53,7 @@ const ToYearlyNudgeBannerDismissable = () => {
const show = snoozeInfo.show;
const currentUser = useSelector(getCurrentUser);
const subscription = useSelector(selectCloudSubscription);
const isAdmin = useSelector(isCurrentUserSystemAdmin);
const product = useSelector(selectSubscriptionProduct);
const currentProductProfessional = product?.sku === CloudProducts.PROFESSIONAL;
@ -139,6 +140,10 @@ const ToYearlyNudgeBannerDismissable = () => {
return null;
}
if (subscription?.billing_type === CloudBillingTypes.INTERNAL || subscription?.billing_type === CloudBillingTypes.LICENSED) {
return null;
}
const message = (
<FormattedMessage
id='cloud_billing.nudge_to_yearly.announcement_bar'
@ -159,7 +164,7 @@ const ToYearlyNudgeBannerDismissable = () => {
showCloseButton={daysToProMonthlyEnd > 10}
onButtonClick={() => openPurchaseModal({trackingLocation: 'to_yearly_nudge_annoucement_bar'})}
modalButtonText={t('cloud_billing.nudge_to_yearly.learn_more')}
modalButtonDefaultText='Learn more'
modalButtonDefaultText='Update billing'
message={message}
showLinkAsButton={true}
handleClose={showBanner}
@ -173,6 +178,7 @@ const ToYearlyNudgeBanner = () => {
const [openSalesLink] = useOpenSalesLink();
const openPurchaseModal = useOpenCloudPurchaseModal({});
const subscription = useSelector(selectCloudSubscription);
const product = useSelector(selectSubscriptionProduct);
const currentProductProfessional = product?.sku === CloudProducts.PROFESSIONAL;
const currentProductIsMonthly = product?.recurring_interval === RecurringIntervals.MONTH;
@ -182,6 +188,10 @@ const ToYearlyNudgeBanner = () => {
return null;
}
if (subscription?.billing_type === CloudBillingTypes.INTERNAL || subscription?.billing_type === CloudBillingTypes.LICENSED) {
return null;
}
const now = moment(Date.now());
const proMonthlyEndDate = moment(cloudProMonthlyCloseMoment, 'YYYYMMDD');
const daysToProMonthlyEnd = proMonthlyEndDate.diff(now, 'days');

View File

@ -3056,7 +3056,7 @@
"cloud_billing.nudge_to_yearly.announcement_bar": "Monthly billing will be discontinued in {days} days . Switch to annual billing",
"cloud_billing.nudge_to_yearly.contact_sales": "Contact sales",
"cloud_billing.nudge_to_yearly.description": "Monthly billing will be discontinued on {date}. To keep your workspace, switch to annual billing.",
"cloud_billing.nudge_to_yearly.learn_more": "Learn more",
"cloud_billing.nudge_to_yearly.learn_more": "Update billing",
"cloud_billing.nudge_to_yearly.title": "Action required: Switch to annual billing to keep your workspace.",
"cloud_delinquency.banner.buttonText": "Update billing now",
"cloud_delinquency.banner.end_user_notify_admin_button": "Notify admin",

View File

@ -504,6 +504,11 @@ export const CloudProducts = {
LEGACY: 'cloud-legacy',
};
export const CloudBillingTypes = {
INTERNAL: 'internal',
LICENSED: 'licensed',
};
export const SelfHostedProducts = {
STARTER: 'starter',
PROFESSIONAL: 'professional',

View File

@ -41,6 +41,7 @@ export type Subscription = {
is_free_trial: string;
delinquent_since?: number;
compliance_blocked?: string;
billing_type?: string;
}
export type Product = {