Files
MyClub/internal/models/eshop.go
T
Tomas Dvorak dfc079288f hot fix #1
2026-01-26 08:13:18 +01:00

232 lines
11 KiB
Go

package models
import (
"time"
"gorm.io/gorm"
)
// EshopProductCategory represents a product category in the e-shop (e.g. dresy, čepice)
type EshopProductCategory struct {
ID uint `gorm:"primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
Slug string `gorm:"size:190;uniqueIndex;not null" json:"slug"`
Name string `gorm:"size:255;not null" json:"name"`
ParentID *uint `gorm:"index" json:"parent_id,omitempty"`
DisplayOrder int `gorm:"default:0" json:"display_order"`
Active bool `gorm:"default:true" json:"active"`
}
func (EshopProductCategory) TableName() string { return "eshop_product_categories" }
// EshopProduct represents a sellable product in the e-shop
// Prices are stored in cents for currency-safe arithmetic.
type EshopProduct struct {
ID uint `gorm:"primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
Slug string `gorm:"size:190;uniqueIndex;not null" json:"slug"`
Name string `gorm:"size:255;not null" json:"name"`
ShortDescription string `gorm:"type:text" json:"short_description"`
DescriptionHTML string `gorm:"type:text" json:"description_html"`
PriceCents int64 `json:"price_cents"`
Currency string `gorm:"size:10;default:'CZK'" json:"currency"`
VATRate float64 `json:"vat_rate"`
Active bool `gorm:"default:true;index" json:"active"`
StockMode string `gorm:"size:20;default:'finite'" json:"stock_mode"` // finite | unlimited
DefaultImageURL string `gorm:"size:500" json:"default_image_url"`
GalleryJSON string `gorm:"type:text" json:"gallery_json"` // JSON array of image URLs
Tags string `gorm:"type:text" json:"tags"` // comma-separated or JSON
MetadataJSON string `gorm:"type:text" json:"metadata_json"` // flexible metadata
CategoryID *uint `gorm:"index" json:"category_id,omitempty"`
Category *EshopProductCategory `gorm:"foreignKey:CategoryID" json:"category,omitempty"`
Variants []EshopProductVariant `gorm:"foreignKey:ProductID" json:"variants,omitempty"`
}
func (EshopProduct) TableName() string { return "eshop_products" }
// EshopProductVariant represents a concrete variant of a product (size/color)
type EshopProductVariant struct {
ID uint `gorm:"primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
ProductID uint `gorm:"index;not null" json:"product_id"`
Product EshopProduct `gorm:"foreignKey:ProductID" json:"-"`
SKU string `gorm:"size:64;index" json:"sku"`
Name string `gorm:"size:255" json:"name"`
AttributesJSON string `gorm:"type:text" json:"attributes_json"` // e.g. {"size":"M","color":"Modrá"}
StockQty int `json:"stock_qty"`
Barcode string `gorm:"size:128" json:"barcode"`
ImageURL string `gorm:"size:500" json:"image_url"`
}
func (EshopProductVariant) TableName() string { return "eshop_product_variants" }
// EshopCart represents an open shopping cart (either user-based or session-based)
type EshopCart struct {
ID uint `gorm:"primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
UserID *uint `gorm:"index" json:"user_id,omitempty"`
User *User `gorm:"foreignKey:UserID" json:"user,omitempty"`
SessionToken string `gorm:"size:64;index" json:"session_token,omitempty"`
Currency string `gorm:"size:10" json:"currency"`
Completed bool `gorm:"default:false;index" json:"completed"`
Items []EshopCartItem `gorm:"foreignKey:CartID" json:"items,omitempty"`
}
func (EshopCart) TableName() string { return "eshop_carts" }
// EshopCartItem represents a single item in the shopping cart
type EshopCartItem struct {
ID uint `gorm:"primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CartID uint `gorm:"index;not null" json:"cart_id"`
Cart EshopCart `gorm:"foreignKey:CartID" json:"-"`
ProductID uint `gorm:"index;not null" json:"product_id"`
Product EshopProduct `gorm:"foreignKey:ProductID" json:"product"`
VariantID *uint `gorm:"index" json:"variant_id,omitempty"`
Variant *EshopProductVariant `gorm:"foreignKey:VariantID" json:"variant,omitempty"`
Quantity int `gorm:"not null;default:1" json:"quantity"`
UnitPriceCents int64 `json:"unit_price_cents"`
Currency string `gorm:"size:10" json:"currency"`
}
func (EshopCartItem) TableName() string { return "eshop_cart_items" }
// EshopOrder represents a placed order
// It is intentionally denormalized a bit so changes to user profile do not affect historical orders.
type EshopOrder struct {
ID uint `gorm:"primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
OrderNumber string `gorm:"size:32;uniqueIndex" json:"order_number"`
UserID *uint `gorm:"index" json:"user_id,omitempty"`
User *User `gorm:"foreignKey:UserID" json:"user,omitempty"`
SessionToken string `gorm:"size:64;index" json:"session_token,omitempty"`
Email string `gorm:"size:255" json:"email"`
FirstName string `gorm:"size:100" json:"first_name"`
LastName string `gorm:"size:100" json:"last_name"`
BillingAddressJSON string `gorm:"type:text" json:"billing_address_json"`
ShippingAddressJSON string `gorm:"type:text" json:"shipping_address_json"`
Status string `gorm:"size:32;index" json:"status"` // new, awaiting_payment, paid, cancelled, refunded, ready_to_ship, shipped, delivered
TotalAmountCents int64 `json:"total_amount_cents"`
Currency string `gorm:"size:10" json:"currency"`
ShippingMethod string `gorm:"size:32" json:"shipping_method"`
ShippingPriceCents int64 `json:"shipping_price_cents"`
ShippingDataJSON string `gorm:"type:text" json:"shipping_data_json"`
TicketOrder *uint `gorm:"index" json:"ticket_order,omitempty"` // Flag for ticket orders
TicketCampaignID *uint `gorm:"index" json:"ticket_campaign_id,omitempty"` // Link to ticket campaign
MetadataJSON string `gorm:"type:text" json:"metadata_json"`
Items []EshopOrderItem `gorm:"foreignKey:OrderID" json:"items,omitempty"`
Payments []EshopPayment `gorm:"foreignKey:OrderID" json:"payments,omitempty"`
Labels []EshopShippingLabel `gorm:"foreignKey:OrderID" json:"labels,omitempty"`
}
func (EshopOrder) TableName() string { return "eshop_orders" }
// EshopOrderItem represents a line item within an order
type EshopOrderItem struct {
ID uint `gorm:"primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
OrderID uint `gorm:"index;not null" json:"order_id"`
Order EshopOrder `gorm:"foreignKey:OrderID" json:"-"`
ProductID uint `gorm:"index" json:"product_id"`
VariantID *uint `gorm:"index" json:"variant_id,omitempty"`
Name string `gorm:"size:255" json:"name"`
SKU string `gorm:"size:64" json:"sku"`
Quantity int `gorm:"not null;default:1" json:"quantity"`
UnitPriceCents int64 `json:"unit_price_cents"`
Currency string `gorm:"size:10" json:"currency"`
VATRate float64 `json:"vat_rate"`
TicketID *uint `gorm:"index" json:"ticket_id,omitempty"` // Link to ticket if this is a ticket item
}
func (EshopOrderItem) TableName() string { return "eshop_order_items" }
// EshopPayment tracks payments for orders (e.g. Stripe)
type EshopPayment struct {
ID uint `gorm:"primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
OrderID uint `gorm:"index;not null" json:"order_id"`
Order EshopOrder `gorm:"foreignKey:OrderID" json:"-"`
Provider string `gorm:"size:32" json:"provider"` // stripe, bank_transfer
ProviderPaymentID string `gorm:"size:128;index" json:"provider_payment_id"`
Status string `gorm:"size:32;index" json:"status"` // pending, succeeded, failed, refunded
AmountCents int64 `json:"amount_cents"`
Currency string `gorm:"size:10" json:"currency"`
RawPayloadJSON string `gorm:"type:text" json:"raw_payload_json"`
}
func (EshopPayment) TableName() string { return "eshop_payments" }
// EshopShippingLabel tracks carrier labels / Packeta packets for orders
type EshopShippingLabel struct {
ID uint `gorm:"primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
OrderID uint `gorm:"index;not null" json:"order_id"`
Order EshopOrder `gorm:"foreignKey:OrderID" json:"-"`
Carrier string `gorm:"size:32" json:"carrier"` // packeta, courier, pickup
PacketaPacketID string `gorm:"size:64;index" json:"packeta_packet_id"`
TrackingNumber string `gorm:"size:64" json:"tracking_number"`
LabelURL string `gorm:"size:500" json:"label_url"`
Status string `gorm:"size:64" json:"status"`
HistoryJSON string `gorm:"type:text" json:"history_json"`
}
func (EshopShippingLabel) TableName() string { return "eshop_shipping_labels" }
// EshopSettings stores configuration specific to the e-shop instance
type EshopSettings struct {
ID uint `gorm:"primaryKey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
DefaultCurrency string `gorm:"size:10;default:'CZK'" json:"default_currency"`
SupportedCurrencies string `gorm:"type:text" json:"supported_currencies"`
DefaultCountry string `gorm:"size:2;default:'CZ'" json:"default_country"`
ShippingOptionsJSON string `gorm:"type:text" json:"shipping_options_json"`
TermsURL string `gorm:"size:500" json:"terms_url"`
ReturnsPolicyURL string `gorm:"size:500" json:"returns_policy_url"`
SupportEmail string `gorm:"size:255" json:"support_email"`
SupportPhone string `gorm:"size:64" json:"support_phone"`
}
func (EshopSettings) TableName() string { return "eshop_settings" }