package models import ( "fmt" "gorm.io/gorm" ) type OrderStatus string const ( AwaitingConfirmation OrderStatus = "AwaitingConfirmation" Received OrderStatus = "Received" AwaitingPayment OrderStatus = "AwaitingPayment" Payed OrderStatus = "Payed" ReadyForPickup OrderStatus = "ReadyForPickup" Shipped OrderStatus = "Shipped" Cancelled OrderStatus = "Cancelled" ) type AddressInfo struct { FirstName string `json:"firstname"` LastName string `json:"lastname"` Address string `json:"address"` PostalCode string `json:"postalcode"` City string `json:"city"` Country string `json:"country"` } type Shipping struct { Id string `json:"id"` Name string `json:"name"` Price float64 `json:"price"` } func GetShippingMethods() []Shipping { return []Shipping{ {Id: "germany", Name: "Germany (DHL)", Price: 3.99}, {Id: "international", Name: "International (DHL)", Price: 5.99}, {Id: "pickup", Name: "Pickup", Price: 0.00}, } } func GetShippingMethod(id string) (Shipping, error) { var shipping Shipping found := false for _, shippingMethod := range GetShippingMethods() { if shippingMethod.Id == id { shipping = shippingMethod found = true } } if !found { return Shipping{}, fmt.Errorf("Shipping method does not exist.") } return shipping, nil } type Order struct { gorm.Model SessionId string `json:"sessionid" binding:"required" gorm:"not null"` Status OrderStatus `json:"status"` Token string `json:"token" binding:"required" gorm:"not null"` Email string `json:"email"` Comment string `json:"comment"` FirstName string `json:"firstname"` LastName string `json:"lastname"` Address string `json:"address"` PostalCode string `json:"postalcode"` City string `json:"city"` Country string `json:"country"` Shipping string `json:"shipping"` CartItems []CartItem `json:"cartitems" gorm:"foreignKey:OrderID"` } func (o *Order) Validate() error { //TODO: validate sessionId if o.SessionId == "" { return fmt.Errorf("Invalid SessionId") } //TODO: validate token if o.Token == "" { return fmt.Errorf("Invalid Token") } if o.Status == AwaitingConfirmation { return fmt.Errorf("Order still awaiting confirmation.") } if len(o.CartItems) == 0 { return fmt.Errorf("Order is empty.") } shipping, err := GetShippingMethod(o.Shipping) if err != nil { return err } //for pickup no address validation is necessary if shipping.Id == "pickup" { return nil } return o.ValidateAddress() } func (o *Order) ValidateAddress() error { if o.FirstName == "" { return fmt.Errorf("Firstname missing") } if o.LastName == "" { return fmt.Errorf("Lastname missing") } if o.Address == "" { return fmt.Errorf("Address missing") } if o.PostalCode == "" { return fmt.Errorf("Postalcode missing") } if o.City == "" { return fmt.Errorf("City missing") } if o.Country == "" { return fmt.Errorf("Country missing") } return nil } func (o *Order) CalculatePrices() (float64, float64, error) { shipping, err := GetShippingMethod(o.Shipping) if err != nil { return 0, 0, err } priceProducts := 0.0 for _, cartItem := range o.CartItems { priceProducts += (float64(cartItem.Quantity) * cartItem.ItemVariant.Price) } priceTotal := priceProducts + shipping.Price return priceProducts, priceTotal, nil } type CartItem struct { gorm.Model SessionId string `json:"sessionid" binding:"required" gorm:"not null"` ShopItemId uint ShopItem ShopItem `json:"shopitem" gorm:"foreignKey:ShopItemId"` //gorm one2one ItemVariantId uint ItemVariant ItemVariant `json:"itemvariant" gorm:"foreignKey:ItemVariantId"` //gorm one2one Quantity int `json:"quantity" binding:"required"` OrderID uint }