Yimaru-BackEnd/internal/domain/subscriptions.go

153 lines
3.9 KiB
Go

package domain
import (
"time"
)
type DurationUnit string
const (
DurationUnitDay DurationUnit = "DAY"
DurationUnitWeek DurationUnit = "WEEK"
DurationUnitMonth DurationUnit = "MONTH"
DurationUnitYear DurationUnit = "YEAR"
)
type SubscriptionStatus string
const (
SubscriptionStatusPending SubscriptionStatus = "PENDING"
SubscriptionStatusActive SubscriptionStatus = "ACTIVE"
SubscriptionStatusExpired SubscriptionStatus = "EXPIRED"
SubscriptionStatusCancelled SubscriptionStatus = "CANCELLED"
)
type SubscriptionPlan struct {
ID int64
Name string
Description *string
DurationValue int32
DurationUnit string
Price float64
Currency string
IsActive bool
CreatedAt time.Time
UpdatedAt *time.Time
}
type UserSubscription struct {
ID int64
UserID int64
PlanID int64
StartsAt time.Time
ExpiresAt time.Time
Status string
PaymentReference *string
PaymentMethod *string
AutoRenew bool
CancelledAt *time.Time
CreatedAt time.Time
UpdatedAt *time.Time
// Joined fields from plan
PlanName *string
DurationValue *int32
DurationUnit *string
Price *float64
Currency *string
}
// UserSubscriptionSummary is the active subscription attached to admin user list responses (GET /users).
type UserSubscriptionSummary struct {
ID int64 `json:"id"`
PlanID int64 `json:"plan_id"`
PlanName string `json:"plan_name"`
Status string `json:"status"`
StartsAt time.Time `json:"starts_at"`
ExpiresAt time.Time `json:"expires_at"`
AutoRenew bool `json:"auto_renew"`
PaymentMethod *string `json:"payment_method,omitempty"`
DurationValue int32 `json:"duration_value"`
DurationUnit string `json:"duration_unit"`
Price float64 `json:"price"`
Currency string `json:"currency"`
}
// Summary returns a copy safe for JSON embedding; nil if receiver is nil.
func (us *UserSubscription) Summary() *UserSubscriptionSummary {
if us == nil {
return nil
}
s := &UserSubscriptionSummary{
ID: us.ID,
PlanID: us.PlanID,
Status: us.Status,
StartsAt: us.StartsAt,
ExpiresAt: us.ExpiresAt,
AutoRenew: us.AutoRenew,
PaymentMethod: us.PaymentMethod,
}
if us.PlanName != nil {
s.PlanName = *us.PlanName
}
if us.DurationValue != nil {
s.DurationValue = *us.DurationValue
}
if us.DurationUnit != nil {
s.DurationUnit = *us.DurationUnit
}
if us.Price != nil {
s.Price = *us.Price
}
if us.Currency != nil {
s.Currency = *us.Currency
}
return s
}
type CreateSubscriptionPlanInput struct {
Name string
Description *string
DurationValue int32
DurationUnit string
Price float64
Currency string
IsActive *bool
}
type UpdateSubscriptionPlanInput struct {
Name *string
Description *string
DurationValue *int32
DurationUnit *string
Price *float64
Currency *string
IsActive *bool
}
type CreateUserSubscriptionInput struct {
UserID int64
PlanID int64
StartsAt *time.Time
ExpiresAt time.Time
Status *string
PaymentReference *string
PaymentMethod *string
AutoRenew *bool
}
// CalculateExpiryDate calculates the expiry date based on plan duration
func CalculateExpiryDate(startTime time.Time, durationValue int32, durationUnit string) time.Time {
switch durationUnit {
case string(DurationUnitDay):
return startTime.AddDate(0, 0, int(durationValue))
case string(DurationUnitWeek):
return startTime.AddDate(0, 0, int(durationValue)*7)
case string(DurationUnitMonth):
return startTime.AddDate(0, int(durationValue), 0)
case string(DurationUnitYear):
return startTime.AddDate(int(durationValue), 0, 0)
default:
return startTime.AddDate(0, int(durationValue), 0) // Default to months
}
}