package entities import ( "time" "github.com/google/uuid" ) // Voucher is what EnakPoint is redeemed for (docs/rfc-enakgame.md ยง5.7). type Voucher struct { ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"` OrganizationID uuid.UUID `gorm:"type:uuid;not null" json:"organization_id"` Name string `gorm:"size:255;not null" json:"name"` Description *string `gorm:"type:text" json:"description"` ImageURL *string `gorm:"column:image_url;size:500" json:"image_url"` VoucherType string `gorm:"size:30;not null" json:"voucher_type"` // Rupiah: the basis of realized cost. FaceValue int64 `gorm:"not null" json:"face_value"` PointCost int64 `gorm:"not null" json:"point_cost"` // Reporting only. BusinessCost *int64 `json:"business_cost"` StockMode string `gorm:"size:20;not null" json:"stock_mode"` // STATIC only. Stock *int64 `json:"stock"` // EXTERNAL only. Provider *string `gorm:"size:50" json:"provider"` ProviderRef *string `gorm:"size:255" json:"provider_ref"` MaxPerCustomer *int `json:"max_per_customer"` ValidFrom *time.Time `json:"valid_from"` ValidUntil *time.Time `json:"valid_until"` Terms JSONDocument `gorm:"type:jsonb;not null;default:'{}'" json:"terms"` Status string `gorm:"size:20;not null" json:"status"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } func (Voucher) TableName() string { return "vouchers" } // VoucherCode is one code of a CODE_POOL voucher. type VoucherCode struct { ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"` VoucherID uuid.UUID `gorm:"type:uuid;not null" json:"voucher_id"` Code string `gorm:"size:255;not null" json:"code"` Status string `gorm:"size:20;not null" json:"status"` RedemptionID *uuid.UUID `gorm:"type:uuid" json:"redemption_id"` ExpiresAt *time.Time `json:"expires_at"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } func (VoucherCode) TableName() string { return "voucher_codes" } // VoucherRedemption is one redemption, with the voucher's numbers frozen (P3). type VoucherRedemption struct { ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"` OrganizationID uuid.UUID `gorm:"type:uuid;not null" json:"organization_id"` CustomerID uuid.UUID `gorm:"type:uuid;not null" json:"customer_id"` VoucherID uuid.UUID `gorm:"type:uuid;not null" json:"voucher_id"` IdempotencyKey string `gorm:"size:100;not null" json:"idempotency_key"` Status string `gorm:"size:20;not null" json:"status"` FaceValue int64 `gorm:"not null" json:"face_value"` PointCost int64 `gorm:"not null" json:"point_cost"` VoucherCodeID *uuid.UUID `gorm:"type:uuid" json:"voucher_code_id"` ExternalCode *string `gorm:"size:255" json:"external_code"` ExternalRef *string `gorm:"size:255" json:"external_ref"` DebitTransactionID uuid.UUID `gorm:"type:uuid;not null" json:"debit_transaction_id"` RefundTransactionID *uuid.UUID `gorm:"type:uuid" json:"refund_transaction_id"` FailureReason *string `gorm:"size:255" json:"failure_reason"` Attempts int `gorm:"not null;default:0" json:"attempts"` CompletedAt *time.Time `json:"completed_at"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } func (VoucherRedemption) TableName() string { return "voucher_redemptions" } // VoucherRedemptionCost is the part of a redemption's face value one source of its // EnakPoint accounts for (D5). BudgetID is nil for EnakPoint not from EnakGame. type VoucherRedemptionCost struct { RedemptionID uuid.UUID `gorm:"type:uuid;not null" json:"redemption_id"` BudgetID *uuid.UUID `gorm:"type:uuid" json:"budget_id"` SourceType string `gorm:"size:30;not null" json:"source_type"` Points int64 `gorm:"not null" json:"points"` Cost int64 `gorm:"not null" json:"cost"` RecognizedAt time.Time `gorm:"not null" json:"recognized_at"` } func (VoucherRedemptionCost) TableName() string { return "voucher_redemption_costs" }