Dev / models /models.go
Mhamdans17
feat: single session enforcement + UI improvements
c6e89e6
Raw
History Blame Contribute Delete
16 kB
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"`
}