@@ -22,8 +22,9 @@ var CostCenterNotFound = errors.New("CostCenter not found")
22
22
type BillingStrategy string
23
23
24
24
const (
25
- CostCenter_Stripe BillingStrategy = "stripe"
26
- CostCenter_Other BillingStrategy = "other"
25
+ CostCenter_Stripe BillingStrategy = "stripe"
26
+ CostCenter_Other BillingStrategy = "other"
27
+ CostCenter_ChargebeeCancelled BillingStrategy = "chargebee-cancelled"
27
28
)
28
29
29
30
type CostCenter struct {
@@ -103,7 +104,7 @@ func (c *CostCenterManager) GetOrCreateCostCenter(ctx context.Context, attributi
103
104
// we want to reset it immediately.
104
105
// This can happen in the following scenario:
105
106
// * User accesses gitpod just after their CostCenter expired, but just before our periodic CostCenter reset kicks in.
106
- if result .BillingStrategy == CostCenter_Other && result .IsExpired () {
107
+ if result .BillingStrategy != CostCenter_Stripe && result .IsExpired () {
107
108
cc , err := c .ResetUsage (ctx , result .ID )
108
109
if err != nil {
109
110
logger .WithError (err ).Error ("Failed to reset expired usage." )
@@ -237,7 +238,7 @@ func (c *CostCenterManager) newInvoiceUsageRecord(ctx context.Context, attributi
237
238
}, nil
238
239
}
239
240
240
- func (c * CostCenterManager ) ListLatestCostCentersWithBillingTimeBefore (ctx context.Context , strategy BillingStrategy , billingTimeBefore time.Time ) ([]CostCenter , error ) {
241
+ func (c * CostCenterManager ) ListManagedCostCentersWithBillingTimeBefore (ctx context.Context , billingTimeBefore time.Time ) ([]CostCenter , error ) {
241
242
db := c .conn .WithContext (ctx )
242
243
243
244
var results []CostCenter
@@ -250,7 +251,7 @@ func (c *CostCenterManager) ListLatestCostCentersWithBillingTimeBefore(ctx conte
250
251
tx := db .Table (fmt .Sprintf ("%s as cc" , (& CostCenter {}).TableName ())).
251
252
// Join on our set of latest CostCenter records
252
253
Joins ("INNER JOIN (?) AS expiredCC on cc.id = expiredCC.id AND cc.creationTime = expiredCC.creationTime" , subquery ).
253
- Where ("cc.billingStrategy = ?" , strategy ).
254
+ Where ("cc.billingStrategy ! = ?" , CostCenter_Stripe ). // Stripe is managed externally
254
255
Where ("nextBillingTime != ?" , "" ).
255
256
Where ("nextBillingTime < ?" , TimeToISO8601 (billingTimeBefore )).
256
257
FindInBatches (& batch , 1000 , func (tx * gorm.DB , iteration int ) error {
@@ -273,7 +274,7 @@ func (c *CostCenterManager) ResetUsage(ctx context.Context, id AttributionID) (C
273
274
return cc , err
274
275
}
275
276
logger = logger .WithField ("cost_center" , cc )
276
- if cc .BillingStrategy != CostCenter_Other {
277
+ if cc .BillingStrategy == CostCenter_Stripe {
277
278
return CostCenter {}, fmt .Errorf ("cannot reset usage for Billing Strategy %s for Cost Center ID: %s" , cc .BillingStrategy , cc .ID )
278
279
}
279
280
if ! cc .IsExpired () {
@@ -290,11 +291,19 @@ func (c *CostCenterManager) ResetUsage(ctx context.Context, id AttributionID) (C
290
291
nextBillingTime = cc .NextBillingTime .Time ().AddDate (0 , 1 , 0 )
291
292
}
292
293
294
+ futureSpendingLimit := cc .SpendingLimit
295
+ futurebillingStrategy := cc .BillingStrategy
296
+ // chargebee cancellations will be switched to free plan (strategy: other)
297
+ if cc .BillingStrategy == CostCenter_ChargebeeCancelled {
298
+ futureSpendingLimit = c .cfg .ForTeams
299
+ futurebillingStrategy = CostCenter_Other
300
+ }
301
+
293
302
// All fields on the new cost center remain the same, except for BillingCycleStart, NextBillingTime, and CreationTime
294
303
newCostCenter := CostCenter {
295
304
ID : cc .ID ,
296
- SpendingLimit : cc . SpendingLimit ,
297
- BillingStrategy : cc . BillingStrategy ,
305
+ SpendingLimit : futureSpendingLimit ,
306
+ BillingStrategy : futurebillingStrategy ,
298
307
BillingCycleStart : NewVarCharTime (billingCycleStart ),
299
308
NextBillingTime : NewVarCharTime (nextBillingTime ),
300
309
CreationTime : NewVarCharTime (now ),
0 commit comments