package models import ( "time" ) type Company struct { ID uint `gorm:"primaryKey" json:"id"` Name string `gorm:"type:varchar(100);not null" json:"name"` BankAccountNumber string `gorm:"type:varchar(50)" json:"bank_account_number"` BankName string `gorm:"type:varchar(100)" json:"bank_name"` Address string `gorm:"type:varchar(255)" json:"address"` NPWP string `gorm:"type:varchar(50)" json:"npwp"` Email string `gorm:"type:varchar(100)" json:"email"` Phone string `gorm:"type:varchar(20)" json:"phone"` LogoURL string `gorm:"type:varchar(255)" json:"logo_url"` IsActive bool `json:"is_active"` FeePercentage float64 `gorm:"type:float;default:0.0;not null" json:"fee_percentage"` ApprovedAt *time.Time `json:"approved_at"` TripayMerchantCode string `gorm:"type:varchar(100)" json:"tripay_merchant_code"` TripayAPIKey string `gorm:"type:text" json:"tripay_api_key"` TripayPrivateKey string `gorm:"type:text" json:"tripay_private_key"` TripayProxyURL string `gorm:"type:text" json:"tripay_proxy_url"` CashFeeRules string `gorm:"type:text;default:'[]'" json:"cash_fee_rules"` QrisFeeRules string `gorm:"type:text;default:'[]'" json:"qris_fee_rules"` QrisFeePercentage float64 `gorm:"type:float;default:1.7" json:"qris_fee_percentage"` QrisFeeFixed int `gorm:"default:500" json:"qris_fee_fixed"` QrisFeeMin int `gorm:"default:850" json:"qris_fee_min"` QrisMinTransaction int `gorm:"default:10000" json:"qris_min_transaction"` AllowQrisBelowMin bool `gorm:"default:false" json:"allow_qris_below_min"` ChargeFeeBeforeDiscount bool `gorm:"default:false" json:"charge_fee_before_discount"` WalletBalance float64 `gorm:"type:float;default:0.0" json:"wallet_balance"` WalletLimit float64 `gorm:"type:float;default:-50000.0" json:"wallet_limit"` EnableMember bool `gorm:"default:true" json:"enable_member"` EnableVoucher bool `gorm:"default:true" json:"enable_voucher"` EnableMultiBranch bool `gorm:"default:false" json:"enable_multi_branch"` MaxBranches int `gorm:"default:0" json:"max_branches"` EnableMultiKasir bool `gorm:"default:false" json:"enable_multi_kasir"` MaxCashiers int `gorm:"default:0" json:"max_cashiers"` EnforceSingleSession bool `gorm:"default:false" json:"enforce_single_session"` PointRules []PointRule `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"point_rules"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` Branches []Branch `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"` Users []User `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"` Categories []Category `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"` Products []Product `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"` Orders []Order `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"` Members []Member `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"` PointHistories []PointHistory `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"` WalletTransactions []WalletTransaction `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"` TopupRequests []TopupRequest `gorm:"foreignKey:CompanyID;constraint:OnDelete:CASCADE" json:"-"` } type PointRule struct { ID uint `gorm:"primaryKey" json:"id"` CompanyID uint `gorm:"not null;index" json:"company_id"` MinAmount int `gorm:"not null" json:"min_amount"` PointReward int `gorm:"not null" json:"point_reward"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } type Member struct { ID uint `gorm:"primaryKey" json:"id"` CompanyID uint `gorm:"not null;index" json:"company_id"` MemberCode string `gorm:"column:member_id;type:varchar(50);not null;uniqueIndex:uq_company_member" json:"member_id"` Name string `gorm:"type:varchar(100);not null" json:"name"` Phone string `gorm:"type:varchar(20)" json:"phone"` Points int `gorm:"default:0" json:"points"` BranchID *uint `gorm:"index" json:"branch_id"` CreatedByID *uint `gorm:"index" json:"created_by_id"` CreatedByName string `gorm:"type:varchar(100)" json:"created_by_name"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` Company *Company `gorm:"foreignKey:CompanyID" json:"company,omitempty"` Branch *Branch `gorm:"foreignKey:BranchID;constraint:OnDelete:SET NULL;" json:"branch,omitempty"` CreatedBy *User `gorm:"foreignKey:CreatedByID;constraint:OnDelete:SET NULL;" json:"created_by,omitempty"` PointHistories []PointHistory `gorm:"foreignKey:MemberID;constraint:OnDelete:CASCADE" json:"PointHistories"` } type PointHistory struct { ID uint `gorm:"primaryKey" json:"id"` CompanyID uint `gorm:"not null;index" json:"company_id"` MemberID uint `gorm:"not null;index" json:"member_id"` PointsDelta int `gorm:"not null" json:"points_delta"` // e.g. +5 or -2 Reason string `gorm:"type:varchar(255)" json:"reason"` // e.g., "Transaksi WP-123", "Penyesuaian Manual oleh Budi" CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` Company *Company `gorm:"foreignKey:CompanyID" json:"-"` } type Branch struct { ID uint `gorm:"primaryKey" json:"id"` CompanyID uint `gorm:"not null;index" json:"company_id"` Name string `gorm:"type:varchar(100);not null" json:"name"` Address string `gorm:"type:varchar(255)" json:"address"` Phone string `gorm:"type:varchar(20)" json:"phone"` IsActive bool `json:"is_active"` IsPointEnabled bool `gorm:"default:true" json:"is_point_enabled"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` Company *Company `gorm:"foreignKey:CompanyID" json:"company,omitempty"` Users []User `gorm:"foreignKey:BranchID;constraint:OnDelete:SET NULL" json:"-"` Orders []Order `gorm:"foreignKey:BranchID;constraint:OnDelete:SET NULL" json:"-"` BranchProducts []BranchProduct `gorm:"foreignKey:BranchID;constraint:OnDelete:CASCADE" json:"-"` } type User struct { ID uint `gorm:"primaryKey" json:"id"` Name string `gorm:"type:varchar(100);not null" json:"name"` Email string `gorm:"type:varchar(100);uniqueIndex;not null" json:"email"` Password string `gorm:"type:varchar(255);not null" json:"-"` Phone string `gorm:"type:varchar(20)" json:"phone"` Role string `gorm:"type:varchar(20);default:'kasir'" json:"role"` // "super_admin", "owner", "kasir" CompanyID *uint `gorm:"index" json:"company_id"` BranchID *uint `gorm:"index" json:"branch_id"` IsActive bool `json:"is_active"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` Company *Company `gorm:"foreignKey:CompanyID" json:"company,omitempty"` Branch *Branch `gorm:"foreignKey:BranchID;constraint:OnDelete:SET NULL;" json:"branch,omitempty"` } type Category struct { ID uint `gorm:"primaryKey" json:"id"` CompanyID uint `gorm:"not null;index" json:"company_id"` Name string `gorm:"type:varchar(100);not null" json:"name"` Description string `gorm:"type:varchar(255)" json:"description"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` Company *Company `gorm:"foreignKey:CompanyID" json:"company,omitempty"` Products []Product `gorm:"foreignKey:CategoryID" json:"products,omitempty"` } type Product struct { ID uint `gorm:"primaryKey" json:"id"` CompanyID uint `gorm:"not null;index" json:"company_id"` Name string `gorm:"type:varchar(200);not null" json:"name"` SKU *string `gorm:"type:varchar(50);uniqueIndex" json:"sku"` Price int `gorm:"not null" json:"price"` Stock int `gorm:"not null;default:0" json:"stock"` IsUnlimitedStock bool `gorm:"default:false" json:"is_unlimited_stock"` CategoryID *uint `gorm:"index" json:"category_id"` ImageURL string `gorm:"type:text" json:"image_url"` IsActive bool `gorm:"default:true" json:"is_active"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` Company *Company `gorm:"foreignKey:CompanyID" json:"company,omitempty"` Category *Category `gorm:"foreignKey:CategoryID" json:"category,omitempty"` BranchProducts []BranchProduct `gorm:"foreignKey:ProductID;constraint:OnDelete:CASCADE" json:"-"` } type BranchProduct struct { ID uint `gorm:"primaryKey" json:"id"` BranchID uint `gorm:"uniqueIndex:uq_branch_product;not null" json:"branch_id"` ProductID uint `gorm:"uniqueIndex:uq_branch_product;not null" json:"product_id"` IsAvailable bool `gorm:"default:true" json:"is_available"` Branch *Branch `gorm:"foreignKey:BranchID" json:"branch,omitempty"` Product *Product `gorm:"foreignKey:ProductID" json:"product,omitempty"` } type Order struct { ID uint `gorm:"primaryKey" json:"id"` CompanyID uint `gorm:"not null;index" json:"company_id"` BranchID *uint `gorm:"index" json:"branch_id"` OrderNumber string `gorm:"type:varchar(50);not null;index" json:"order_number"` SubtotalAmount int `gorm:"not null;default:0" json:"subtotal_amount"` TotalAmount int `gorm:"not null;default:0" json:"total_amount"` PaidAmount int `gorm:"not null;default:0" json:"paid_amount"` ChangeAmount int `gorm:"not null;default:0" json:"change_amount"` PaymentMethod string `gorm:"type:varchar(20)" json:"payment_method"` PaymentStatus string `gorm:"type:varchar(20);default:'pending'" json:"payment_status"` // pending, paid, failed, expired, refunded, cancelled MidtransOrderID string `gorm:"type:varchar(100)" json:"midtrans_order_id"` MidtransToken string `gorm:"type:varchar(255)" json:"midtrans_token"` PlatformFee int `gorm:"not null;default:0" json:"platform_fee"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` Company *Company `gorm:"foreignKey:CompanyID" json:"company,omitempty"` Branch *Branch `gorm:"foreignKey:BranchID;constraint:OnDelete:SET NULL;" json:"branch,omitempty"` MemberID *uint `gorm:"index" json:"member_id"` Member *Member `gorm:"constraint:-" json:"member,omitempty"` ServedBy string `gorm:"type:varchar(100)" json:"served_by"` CustomerName string `gorm:"type:varchar(100)" json:"customer_name"` CustomerPhone string `gorm:"type:varchar(50)" json:"customer_phone"` PointsEarned int `gorm:"default:0" json:"points_earned"` Items []OrderItem `gorm:"foreignKey:OrderID;constraint:OnDelete:CASCADE" json:"items"` VoucherID *uint `gorm:"index" json:"voucher_id"` Voucher *Voucher `gorm:"constraint:-" json:"voucher,omitempty"` DiscountAmount int `gorm:"default:0" json:"discount_amount"` PointsUsed int `gorm:"default:0" json:"points_used"` } type Voucher struct { ID uint `gorm:"primaryKey" json:"id"` CompanyID uint `gorm:"not null;index" json:"company_id"` BranchID *uint `gorm:"index" json:"branch_id"` Name string `gorm:"type:varchar(100);not null" json:"name"` DiscountValue int `gorm:"not null;default:0" json:"discount_value"` PointCost int `gorm:"not null;default:0" json:"point_cost"` MinPurchase int `gorm:"not null;default:0" json:"min_purchase"` IsActive bool `gorm:"default:true" json:"is_active"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } type OrderItem struct { ID uint `gorm:"primaryKey" json:"id"` OrderID uint `gorm:"not null;index" json:"order_id"` ProductID uint `gorm:"not null;index" json:"product_id"` Quantity int `gorm:"not null;default:1" json:"quantity"` UnitPrice int `gorm:"not null" json:"unit_price"` Subtotal int `gorm:"not null" json:"subtotal"` Product *Product `gorm:"foreignKey:ProductID" json:"product,omitempty"` } type OTP struct { ID uint `gorm:"primaryKey" json:"id"` PhoneNumber string `gorm:"type:varchar(20);not null;index" json:"phone_number"` OTPCode string `gorm:"type:varchar(10);not null" json:"otp_code"` IsVerified bool `gorm:"default:false" json:"is_verified"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` ExpiresAt time.Time `gorm:"not null" json:"expires_at"` } type Setting struct { ID uint `gorm:"primaryKey" json:"id"` TripayMerchantCode string `gorm:"type:varchar(100)" json:"tripay_merchant_code"` TripayAPIKey string `gorm:"type:text" json:"tripay_api_key"` TripayPrivateKey string `gorm:"type:text" json:"tripay_private_key"` TripayProxyURL string `gorm:"type:text" json:"tripay_proxy_url"` TripayPaymentMethod string `gorm:"type:varchar(50);default:'QRIS'" json:"tripay_payment_method"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } type WalletTransaction struct { ID uint `gorm:"primaryKey" json:"id"` CompanyID uint `gorm:"not null;index" json:"company_id"` Amount float64 `gorm:"not null" json:"amount"` Type string `gorm:"type:varchar(50);not null" json:"type"` // "cash_fee", "topup_qris", "topup_manual", "admin_adjustment" RefID string `gorm:"type:varchar(100)" json:"ref_id"` Desc string `gorm:"type:varchar(255)" json:"desc"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` Company *Company `gorm:"foreignKey:CompanyID" json:"company,omitempty"` } // UserSession tracks active login sessions for single-session enforcement type UserSession struct { ID uint `gorm:"primaryKey" json:"id"` UserID uint `gorm:"not null;index" json:"user_id"` SessionToken string `gorm:"type:varchar(64);not null;uniqueIndex" json:"session_token"` UserAgent string `gorm:"type:varchar(255)" json:"user_agent"` IPAddress string `gorm:"type:varchar(45)" json:"ip_address"` ExpiresAt time.Time `gorm:"not null" json:"expires_at"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` User *User `gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE" json:"-"` } type TopupRequest struct { ID uint `gorm:"primaryKey" json:"id"` CompanyID uint `gorm:"not null;index" json:"company_id"` Amount float64 `gorm:"not null" json:"amount"` ProofURL string `gorm:"type:varchar(255);not null" json:"proof_url"` Status string `gorm:"type:varchar(20);default:'pending'" json:"status"` // pending, approved, rejected CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` Company *Company `gorm:"foreignKey:CompanyID" json:"company,omitempty"` }