[MM-50534] - Renew email adds portal link when not eligible for self-serve renewal (#22350)
* [MM-50534] - Renew email adds portal link when not eligible for self-serve renewal * fix translations * make more checks * improve endpoint to make checks * use new checks * fix translations * fix lint * add meaningful names * rename struct * rename endpoint
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
9c7aab24f5
Коммит
1f5a6e439e
@@ -41,7 +41,7 @@ func (api *API) InitCloud() {
|
||||
api.BaseRoutes.Cloud.Handle("/subscription", api.APISessionRequired(getSubscription)).Methods("GET")
|
||||
api.BaseRoutes.Cloud.Handle("/subscription/invoices", api.APISessionRequired(getInvoicesForSubscription)).Methods("GET")
|
||||
api.BaseRoutes.Cloud.Handle("/subscription/invoices/{invoice_id:[_A-Za-z0-9]+}/pdf", api.APISessionRequired(getSubscriptionInvoicePDF)).Methods("GET")
|
||||
api.BaseRoutes.Cloud.Handle("/subscription/expand", api.APISessionRequired(GetLicenseExpandStatus)).Methods("GET")
|
||||
api.BaseRoutes.Cloud.Handle("/subscription/self-serve-status", api.APISessionRequired(getLicenseSelfServeStatus)).Methods("GET")
|
||||
api.BaseRoutes.Cloud.Handle("/subscription", api.APISessionRequired(changeSubscription)).Methods("PUT")
|
||||
|
||||
// GET /api/v4/cloud/request-trial
|
||||
@@ -430,7 +430,8 @@ func getCloudCustomer(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
w.Write(json)
|
||||
}
|
||||
|
||||
func GetLicenseExpandStatus(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
// getLicenseSelfServeStatus makes check for the license in the CWS self-serve portal and establishes if the license is renewable, expandable etc.
|
||||
func getLicenseSelfServeStatus(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageLicenseInformation) {
|
||||
c.SetPermissionError(model.PermissionManageLicenseInformation)
|
||||
return
|
||||
@@ -443,15 +444,15 @@ func GetLicenseExpandStatus(c *Context, w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
res, cloudErr := c.App.Cloud().GetLicenseExpandStatus(c.AppContext.Session().UserId, token)
|
||||
status, cloudErr := c.App.Cloud().GetLicenseSelfServeStatus(c.AppContext.Session().UserId, token)
|
||||
if cloudErr != nil {
|
||||
c.Err = model.NewAppError("Api4.GetLicenseExpandStatusForSubscription", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(cloudErr)
|
||||
c.Err = model.NewAppError("Api4.getLicenseSelfServeStatus", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(cloudErr)
|
||||
return
|
||||
}
|
||||
|
||||
json, jsonErr := json.Marshal(res)
|
||||
json, jsonErr := json.Marshal(status)
|
||||
if jsonErr != nil {
|
||||
c.Err = model.NewAppError("Api4.GetLicenseExpandStatusForSubscription", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr)
|
||||
c.Err = model.NewAppError("Api4.getLicenseSelfServeStatus", "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -650,7 +650,7 @@ func TestGetCloudProducts(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_GetExpandStatsForSubscription(t *testing.T) {
|
||||
isExpandable := &model.SubscriptionExpandStatus{
|
||||
status := &model.SubscriptionLicenseSelfServeStatusResponse{
|
||||
IsExpandable: true,
|
||||
}
|
||||
|
||||
@@ -664,7 +664,7 @@ func Test_GetExpandStatsForSubscription(t *testing.T) {
|
||||
|
||||
cloud := mocks.CloudInterface{}
|
||||
|
||||
cloud.Mock.On("GetLicenseExpandStatus", mock.Anything).Return(isExpandable, nil)
|
||||
cloud.Mock.On("GetLicenseSelfServeStatus", mock.Anything).Return(status, nil)
|
||||
|
||||
cloudImpl := th.App.Srv().Cloud
|
||||
defer func() {
|
||||
@@ -672,9 +672,9 @@ func Test_GetExpandStatsForSubscription(t *testing.T) {
|
||||
}()
|
||||
th.App.Srv().Cloud = &cloud
|
||||
|
||||
subscriptionExpandable, r, err := th.Client.GetExpandStats(licenseId)
|
||||
checksMade, r, err := th.Client.GetSubscriptionStatus(licenseId)
|
||||
require.Error(t, err)
|
||||
require.Nil(t, subscriptionExpandable)
|
||||
require.Nil(t, checksMade)
|
||||
require.Equal(t, http.StatusForbidden, r.StatusCode, "403 Forbidden")
|
||||
})
|
||||
|
||||
@@ -686,7 +686,7 @@ func Test_GetExpandStatsForSubscription(t *testing.T) {
|
||||
|
||||
cloud := mocks.CloudInterface{}
|
||||
|
||||
cloud.Mock.On("GetLicenseExpandStatus", mock.Anything).Return(isExpandable, nil)
|
||||
cloud.Mock.On("GetLicenseSelfServeStatus", mock.Anything).Return(status, nil)
|
||||
|
||||
cloudImpl := th.App.Srv().Cloud
|
||||
defer func() {
|
||||
@@ -694,9 +694,9 @@ func Test_GetExpandStatsForSubscription(t *testing.T) {
|
||||
}()
|
||||
th.App.Srv().Cloud = &cloud
|
||||
|
||||
subscriptionExpandable, r, err := th.Client.GetExpandStats("")
|
||||
checks, r, err := th.Client.GetSubscriptionStatus("")
|
||||
require.Error(t, err)
|
||||
require.Nil(t, subscriptionExpandable)
|
||||
require.Nil(t, checks)
|
||||
require.Equal(t, http.StatusBadRequest, r.StatusCode, "400 Bad Request")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -261,9 +261,14 @@ func requestRenewalLink(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// check if it is possible to renew license on the portal with generated token
|
||||
e := c.App.Cloud().GetLicenseRenewalStatus(c.AppContext.Session().UserId, token)
|
||||
status, e := c.App.Cloud().GetLicenseSelfServeStatus(c.AppContext.Session().UserId, token)
|
||||
if e != nil {
|
||||
c.Err = model.NewAppError("requestRenewalLink", "api.license.request_renewal_link.cannot_renew_on_cws", nil, e.Error(), http.StatusBadRequest)
|
||||
c.Err = model.NewAppError("requestRenewalLink", "api.license.request_renewal_link.cannot_renew_on_cws", nil, e.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if !status.IsRenewable {
|
||||
c.Err = model.NewAppError("requestRenewalLink", "api.license.request_renewal_link.cannot_renew_on_cws", nil, "License is not self-serve renewable", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -989,7 +989,7 @@ func (es *Service) SendLicenseInactivityEmail(email, name, locale, siteURL strin
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *Service) SendLicenseUpForRenewalEmail(email, name, locale, siteURL, renewalLink string, daysToExpiration int) error {
|
||||
func (es *Service) SendLicenseUpForRenewalEmail(email, name, locale, siteURL, ctaTitle, ctaLink, ctaText string, daysToExpiration int) error {
|
||||
T := i18n.GetUserTranslations(locale)
|
||||
subject := T("api.templates.license_up_for_renewal_subject")
|
||||
|
||||
@@ -997,10 +997,10 @@ func (es *Service) SendLicenseUpForRenewalEmail(email, name, locale, siteURL, re
|
||||
data.Props["SiteURL"] = siteURL
|
||||
data.Props["Title"] = T("api.templates.license_up_for_renewal_title")
|
||||
data.Props["SubTitle"] = T("api.templates.license_up_for_renewal_subtitle", map[string]any{"UserName": name, "Days": daysToExpiration})
|
||||
data.Props["SubTitleTwo"] = T("api.templates.license_up_for_renewal_subtitle_two")
|
||||
data.Props["SubTitleTwo"] = ctaTitle
|
||||
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
|
||||
data.Props["Button"] = T("api.templates.license_up_for_renewal_renew_now")
|
||||
data.Props["ButtonURL"] = renewalLink
|
||||
data.Props["Button"] = ctaText
|
||||
data.Props["ButtonURL"] = ctaLink
|
||||
data.Props["QuestionTitle"] = T("api.templates.questions_footer.title")
|
||||
data.Props["SupportEmail"] = "feedback@mattermost.com"
|
||||
data.Props["QuestionInfo"] = T("api.templates.questions_footer.info")
|
||||
@@ -1298,7 +1298,7 @@ func (es *Service) SendDelinquencyEmail90(email, locale, siteURL string) error {
|
||||
|
||||
// SendRemoveExpiredLicenseEmail formats an email and uses the email service to send the email to user with link pointing to CWS
|
||||
// to renew the user license
|
||||
func (es *Service) SendRemoveExpiredLicenseEmail(renewalLink, email string, locale, siteURL string) error {
|
||||
func (es *Service) SendRemoveExpiredLicenseEmail(ctaText, ctaLink, email, locale, siteURL string) error {
|
||||
T := i18n.GetUserTranslations(locale)
|
||||
subject := T("api.templates.remove_expired_license.subject",
|
||||
map[string]any{"SiteName": es.config().TeamSettings.SiteName})
|
||||
@@ -1306,8 +1306,8 @@ func (es *Service) SendRemoveExpiredLicenseEmail(renewalLink, email string, loca
|
||||
data := es.NewEmailTemplateData(locale)
|
||||
data.Props["SiteURL"] = siteURL
|
||||
data.Props["Title"] = T("api.templates.remove_expired_license.body.title")
|
||||
data.Props["Link"] = renewalLink
|
||||
data.Props["LinkButton"] = T("api.templates.remove_expired_license.body.renew_button")
|
||||
data.Props["Link"] = ctaLink
|
||||
data.Props["LinkButton"] = ctaText
|
||||
|
||||
body, err := es.templatesContainer.RenderToString("remove_expired_license", data)
|
||||
if err != nil {
|
||||
|
||||
@@ -358,13 +358,13 @@ func (_m *ServiceInterface) SendLicenseInactivityEmail(_a0 string, name string,
|
||||
return r0
|
||||
}
|
||||
|
||||
// SendLicenseUpForRenewalEmail provides a mock function with given fields: _a0, name, locale, siteURL, renewalLink, daysToExpiration
|
||||
func (_m *ServiceInterface) SendLicenseUpForRenewalEmail(_a0 string, name string, locale string, siteURL string, renewalLink string, daysToExpiration int) error {
|
||||
ret := _m.Called(_a0, name, locale, siteURL, renewalLink, daysToExpiration)
|
||||
// SendLicenseUpForRenewalEmail provides a mock function with given fields: _a0, name, locale, siteURL, ctaTitle, ctaLink, ctaText, daysToExpiration
|
||||
func (_m *ServiceInterface) SendLicenseUpForRenewalEmail(_a0 string, name string, locale string, siteURL string, ctaTitle string, ctaLink string, ctaText string, daysToExpiration int) error {
|
||||
ret := _m.Called(_a0, name, locale, siteURL, ctaTitle, ctaLink, ctaText, daysToExpiration)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, string, string, string, int) error); ok {
|
||||
r0 = rf(_a0, name, locale, siteURL, renewalLink, daysToExpiration)
|
||||
if rf, ok := ret.Get(0).(func(string, string, string, string, string, string, string, int) error); ok {
|
||||
r0 = rf(_a0, name, locale, siteURL, ctaTitle, ctaLink, ctaText, daysToExpiration)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
@@ -484,13 +484,13 @@ func (_m *ServiceInterface) SendPaymentFailedEmail(_a0 string, locale string, fa
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SendRemoveExpiredLicenseEmail provides a mock function with given fields: renewalLink, _a1, locale, siteURL
|
||||
func (_m *ServiceInterface) SendRemoveExpiredLicenseEmail(renewalLink string, _a1 string, locale string, siteURL string) error {
|
||||
ret := _m.Called(renewalLink, _a1, locale, siteURL)
|
||||
// SendRemoveExpiredLicenseEmail provides a mock function with given fields: ctaText, ctaLink, _a2, locale, siteURL
|
||||
func (_m *ServiceInterface) SendRemoveExpiredLicenseEmail(ctaText string, ctaLink string, _a2 string, locale string, siteURL string) error {
|
||||
ret := _m.Called(ctaText, ctaLink, _a2, locale, siteURL)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, string, string) error); ok {
|
||||
r0 = rf(renewalLink, _a1, locale, siteURL)
|
||||
if rf, ok := ret.Get(0).(func(string, string, string, string, string) error); ok {
|
||||
r0 = rf(ctaText, ctaLink, _a2, locale, siteURL)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ type ServiceInterface interface {
|
||||
SendDeactivateAccountEmail(email string, locale, siteURL string) error
|
||||
SendNotificationMail(to, subject, htmlBody string) error
|
||||
SendMailWithEmbeddedFiles(to, subject, htmlBody string, embeddedFiles map[string]io.Reader, messageID string, inReplyTo string, references string, category string) error
|
||||
SendLicenseUpForRenewalEmail(email, name, locale, siteURL, renewalLink string, daysToExpiration int) error
|
||||
SendLicenseUpForRenewalEmail(email, name, locale, siteURL, ctaTitle, ctaLink, ctaText string, daysToExpiration int) error
|
||||
SendPaymentFailedEmail(email string, locale string, failedPayment *model.FailedPayment, planName, siteURL string) (bool, error)
|
||||
// Cloud delinquency email sequence
|
||||
SendDelinquencyEmail7(email, locale, siteURL, planName string) error
|
||||
@@ -152,7 +152,7 @@ type ServiceInterface interface {
|
||||
SendDelinquencyEmail75(email, locale, siteURL, planName, delinquencyDate string) error
|
||||
SendDelinquencyEmail90(email, locale, siteURL string) error
|
||||
SendNoCardPaymentFailedEmail(email string, locale string, siteURL string) error
|
||||
SendRemoveExpiredLicenseEmail(renewalLink, email string, locale, siteURL string) error
|
||||
SendRemoveExpiredLicenseEmail(ctaText, ctaLink, email, locale, siteURL string) error
|
||||
AddNotificationEmailToBatch(user *model.User, post *model.Post, team *model.Team) *model.AppError
|
||||
GetMessageForNotification(post *model.Post, translateFunc i18n.TranslateFunc) string
|
||||
InitEmailBatching()
|
||||
|
||||
@@ -1288,11 +1288,16 @@ func (s *Server) sendLicenseUpForRenewalEmail(users map[string]*model.User, lice
|
||||
|
||||
daysToExpiration := license.DaysToExpiration()
|
||||
|
||||
renewalLink, _, appErr := s.GenerateLicenseRenewalLink()
|
||||
ctaLink, tokenToBeUsedForRenew, appErr := s.GenerateLicenseRenewalLink()
|
||||
if appErr != nil {
|
||||
return model.NewAppError("s.sendLicenseUpForRenewalEmail", "api.server.license_up_for_renewal.error_generating_link", nil, "", http.StatusInternalServerError).Wrap(appErr)
|
||||
}
|
||||
|
||||
status, err := s.Cloud.GetLicenseSelfServeStatus("", tokenToBeUsedForRenew)
|
||||
if err != nil {
|
||||
return model.NewAppError("s.sendLicenseUpForRenewalEmail", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
|
||||
// we want to at least have one email sent out to an admin
|
||||
countNotOks := 0
|
||||
|
||||
@@ -1301,7 +1306,16 @@ func (s *Server) sendLicenseUpForRenewalEmail(users map[string]*model.User, lice
|
||||
if name == "" {
|
||||
name = user.Username
|
||||
}
|
||||
if err := s.EmailService.SendLicenseUpForRenewalEmail(user.Email, name, user.Locale, *s.platform.Config().ServiceSettings.SiteURL, renewalLink, daysToExpiration); err != nil {
|
||||
T := i18n.GetUserTranslations(user.Locale)
|
||||
ctaTitle := T("api.templates.license_up_for_renewal_subtitle_two")
|
||||
ctaText := T("api.templates.license_up_for_renewal_renew_now")
|
||||
if !status.IsRenewable {
|
||||
ctaTitle = ""
|
||||
ctaText = T("api.templates.license_up_for_renewal_contact_sales")
|
||||
ctaLink = "https://mattermost.com/contact-sales/"
|
||||
}
|
||||
|
||||
if err := s.EmailService.SendLicenseUpForRenewalEmail(user.Email, name, user.Locale, *s.platform.Config().ServiceSettings.SiteURL, ctaTitle, ctaLink, ctaText, daysToExpiration); err != nil {
|
||||
mlog.Error("Error sending license up for renewal email to", mlog.String("user_email", user.Email), mlog.Err(err))
|
||||
countNotOks++
|
||||
}
|
||||
@@ -1366,9 +1380,15 @@ func (s *Server) doLicenseExpirationCheck() {
|
||||
return
|
||||
}
|
||||
|
||||
renewalLink, _, appErr := s.GenerateLicenseRenewalLink()
|
||||
ctaLink, tokenToBeUsedForRenew, appErr := s.GenerateLicenseRenewalLink()
|
||||
if appErr != nil {
|
||||
mlog.Error("Error while sending the license expired email.", mlog.Err(appErr))
|
||||
mlog.Debug(model.NewAppError("s.sendLicenseUpForRenewalEmail", "api.server.license_up_for_renewal.error_generating_link", nil, "", http.StatusInternalServerError).Wrap(appErr).Error())
|
||||
return
|
||||
}
|
||||
|
||||
status, err := s.Cloud.GetLicenseSelfServeStatus("", tokenToBeUsedForRenew)
|
||||
if err != nil {
|
||||
mlog.Debug(model.NewAppError("s.sendLicenseUpForRenewalEmail", "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(err).Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1380,9 +1400,16 @@ func (s *Server) doLicenseExpirationCheck() {
|
||||
continue
|
||||
}
|
||||
|
||||
T := i18n.GetUserTranslations(user.Locale)
|
||||
ctaText := T("api.templates.remove_expired_license.body.renew_button")
|
||||
if !status.IsRenewable {
|
||||
ctaText = T("api.templates.license_up_for_renewal_contact_sales")
|
||||
ctaLink = "https://mattermost.com/contact-sales/"
|
||||
}
|
||||
|
||||
mlog.Debug("Sending license expired email.", mlog.String("user_email", user.Email))
|
||||
s.Go(func() {
|
||||
if err := s.SendRemoveExpiredLicenseEmail(user.Email, renewalLink, user.Locale, *s.platform.Config().ServiceSettings.SiteURL); err != nil {
|
||||
if err := s.SendRemoveExpiredLicenseEmail(user.Email, ctaText, ctaLink, user.Locale, *s.platform.Config().ServiceSettings.SiteURL); err != nil {
|
||||
mlog.Error("Error while sending the license expired email.", mlog.String("user_email", user.Email), mlog.Err(err))
|
||||
}
|
||||
})
|
||||
@@ -1394,9 +1421,9 @@ func (s *Server) doLicenseExpirationCheck() {
|
||||
|
||||
// SendRemoveExpiredLicenseEmail formats an email and uses the email service to send the email to user with link pointing to CWS
|
||||
// to renew the user license
|
||||
func (s *Server) SendRemoveExpiredLicenseEmail(email string, renewalLink, locale, siteURL string) *model.AppError {
|
||||
func (s *Server) SendRemoveExpiredLicenseEmail(email, ctaText, ctaLink, locale, siteURL string) *model.AppError {
|
||||
|
||||
if err := s.EmailService.SendRemoveExpiredLicenseEmail(renewalLink, email, locale, siteURL); err != nil {
|
||||
if err := s.EmailService.SendRemoveExpiredLicenseEmail(ctaText, ctaLink, email, locale, siteURL); err != nil {
|
||||
return model.NewAppError("SendRemoveExpiredLicenseEmail", "api.license.remove_expired_license.failed.error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ type CloudInterface interface {
|
||||
ConfirmCustomerPayment(userID string, confirmRequest *model.ConfirmPaymentMethodRequest) error
|
||||
|
||||
GetCloudCustomer(userID string) (*model.CloudCustomer, error)
|
||||
GetLicenseExpandStatus(userID string, token string) (*model.SubscriptionExpandStatus, error)
|
||||
GetLicenseSelfServeStatus(userID string, token string) (*model.SubscriptionLicenseSelfServeStatusResponse, error)
|
||||
UpdateCloudCustomer(userID string, customerInfo *model.CloudCustomerInfo) (*model.CloudCustomer, error)
|
||||
UpdateCloudCustomerAddress(userID string, address *model.Address) (*model.CloudCustomer, error)
|
||||
|
||||
@@ -30,8 +30,6 @@ type CloudInterface interface {
|
||||
RequestCloudTrial(userID, subscriptionID, newValidBusinessEmail string) (*model.Subscription, error)
|
||||
ValidateBusinessEmail(userID, email string) error
|
||||
|
||||
// GetLicenseRenewalStatus checks on the portal whether it is possible to use token to renew a license
|
||||
GetLicenseRenewalStatus(userID, token string) error
|
||||
InvalidateCaches() error
|
||||
|
||||
// hosted customer methods
|
||||
|
||||
@@ -339,16 +339,16 @@ func (_m *CloudInterface) GetInvoicesForSubscription(userID string) ([]*model.In
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetLicenseExpandStatus provides a mock function with given fields: userID, token
|
||||
func (_m *CloudInterface) GetLicenseExpandStatus(userID string, token string) (*model.SubscriptionExpandStatus, error) {
|
||||
// GetLicenseSelfServeStatus provides a mock function with given fields: userID, token
|
||||
func (_m *CloudInterface) GetLicenseSelfServeStatus(userID string, token string) (*model.SubscriptionLicenseSelfServeStatusResponse, error) {
|
||||
ret := _m.Called(userID, token)
|
||||
|
||||
var r0 *model.SubscriptionExpandStatus
|
||||
if rf, ok := ret.Get(0).(func(string, string) *model.SubscriptionExpandStatus); ok {
|
||||
var r0 *model.SubscriptionLicenseSelfServeStatusResponse
|
||||
if rf, ok := ret.Get(0).(func(string, string) *model.SubscriptionLicenseSelfServeStatusResponse); ok {
|
||||
r0 = rf(userID, token)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.SubscriptionExpandStatus)
|
||||
r0 = ret.Get(0).(*model.SubscriptionLicenseSelfServeStatusResponse)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,20 +362,6 @@ func (_m *CloudInterface) GetLicenseExpandStatus(userID string, token string) (*
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetLicenseRenewalStatus provides a mock function with given fields: userID, token
|
||||
func (_m *CloudInterface) GetLicenseRenewalStatus(userID string, token string) error {
|
||||
ret := _m.Called(userID, token)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||
r0 = rf(userID, token)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetSelfHostedInvoicePDF provides a mock function with given fields: invoiceID
|
||||
func (_m *CloudInterface) GetSelfHostedInvoicePDF(invoiceID string) ([]byte, string, error) {
|
||||
ret := _m.Called(invoiceID)
|
||||
|
||||
@@ -3623,6 +3623,10 @@
|
||||
"id": "api.templates.invite_team_and_channels_subject",
|
||||
"translation": "[{{ .SiteName }}] {{ .SenderName }} invited you to join {{ .ChannelsLen }} channels on the {{ .TeamDisplayName }} Team"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.license_up_for_renewal_contact_sales",
|
||||
"translation": "Contact sales"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.license_up_for_renewal_renew_now",
|
||||
"translation": "Renew now"
|
||||
|
||||
@@ -8235,17 +8235,17 @@ func (c *Client4) GetCloudCustomer() (*CloudCustomer, *Response, error) {
|
||||
return cloudCustomer, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) GetExpandStats(licenseId string) (*SubscriptionExpandStatus, *Response, error) {
|
||||
r, err := c.DoAPIGet(fmt.Sprintf("%s%s?licenseID=%s", c.cloudRoute(), "/subscription/expand", licenseId), "")
|
||||
func (c *Client4) GetSubscriptionStatus(licenseId string) (*SubscriptionLicenseSelfServeStatusResponse, *Response, error) {
|
||||
r, err := c.DoAPIGet(fmt.Sprintf("%s%s?licenseID=%s", c.cloudRoute(), "/subscription/self-serve-status", licenseId), "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
|
||||
var subscriptionExpandable *SubscriptionExpandStatus
|
||||
json.NewDecoder(r.Body).Decode(&subscriptionExpandable)
|
||||
var status *SubscriptionLicenseSelfServeStatusResponse
|
||||
json.NewDecoder(r.Body).Decode(&status)
|
||||
|
||||
return subscriptionExpandable, BuildResponse(r), nil
|
||||
return status, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) GetSubscription() (*Subscription, *Response, error) {
|
||||
|
||||
@@ -125,8 +125,9 @@ type ValidateBusinessEmailResponse struct {
|
||||
IsValid bool `json:"is_valid"`
|
||||
}
|
||||
|
||||
type SubscriptionExpandStatus struct {
|
||||
type SubscriptionLicenseSelfServeStatusResponse struct {
|
||||
IsExpandable bool `json:"is_expandable"`
|
||||
IsRenewable bool `json:"is_renewable"`
|
||||
}
|
||||
|
||||
// CloudCustomerInfo represents editable info of a customer.
|
||||
|
||||
Ссылка в новой задаче
Block a user