wip itemvariant
This commit is contained in:
@@ -137,7 +137,7 @@ func (rc *cartItemController) CartItemView(c *gin.Context) {
|
|||||||
|
|
||||||
priceTotal := 0.0
|
priceTotal := 0.0
|
||||||
for _, cartItem := range cartItems {
|
for _, cartItem := range cartItems {
|
||||||
priceTotal += (float64(cartItem.Quantity) * cartItem.ShopItem.Price)
|
priceTotal += (float64(cartItem.Quantity) * cartItem.ShopItem.BasePrice)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("PRICE TOTAL", priceTotal)
|
fmt.Println("PRICE TOTAL", priceTotal)
|
||||||
|
|||||||
@@ -69,7 +69,8 @@ func (rc *shopItemController) NewShopItemFromForm(ctx *gin.Context) (models.Shop
|
|||||||
name := ctx.PostForm("name")
|
name := ctx.PostForm("name")
|
||||||
abstract := ctx.PostForm("abstract")
|
abstract := ctx.PostForm("abstract")
|
||||||
description := ctx.PostForm("description")
|
description := ctx.PostForm("description")
|
||||||
priceStr := ctx.PostForm("price")
|
variantNames := ctx.PostFormArray("variant-name[]")
|
||||||
|
variantValues := ctx.PostFormArray("variant-value[]")
|
||||||
tagIds := ctx.PostFormArray("tags[]")
|
tagIds := ctx.PostFormArray("tags[]")
|
||||||
image, err := ctx.FormFile("image")
|
image, err := ctx.FormFile("image")
|
||||||
dst := "static/img/zine.jpg"
|
dst := "static/img/zine.jpg"
|
||||||
@@ -85,19 +86,37 @@ func (rc *shopItemController) NewShopItemFromForm(ctx *gin.Context) (models.Shop
|
|||||||
return models.ShopItem{}, fmt.Errorf("Name or description empty")
|
return models.ShopItem{}, fmt.Errorf("Name or description empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var variants []models.ItemVariant
|
||||||
|
|
||||||
|
if len(variantNames) != len(variantValues) {
|
||||||
|
return models.ShopItem{}, fmt.Errorf("Different number of variant names and values")
|
||||||
|
}
|
||||||
|
|
||||||
|
for idx := range variantNames {
|
||||||
|
if variantValues[idx] == "" || variantNames[idx] == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
price, err := strconv.ParseFloat(variantValues[idx], 64)
|
||||||
|
if err != nil {
|
||||||
|
return models.ShopItem{}, fmt.Errorf("Could not variant parse price")
|
||||||
|
}
|
||||||
|
|
||||||
|
variants = append(variants, models.ItemVariant{
|
||||||
|
Name: variantNames[idx],
|
||||||
|
Price: price,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Convert the price string to float64
|
// Convert the price string to float64
|
||||||
price, err := strconv.ParseFloat(priceStr, 64)
|
|
||||||
if err != nil {
|
|
||||||
return models.ShopItem{}, fmt.Errorf("Could not parse price")
|
|
||||||
}
|
|
||||||
|
|
||||||
shopItem := models.ShopItem{
|
shopItem := models.ShopItem{
|
||||||
Name: name,
|
Name: name,
|
||||||
Abstract: abstract,
|
Abstract: abstract,
|
||||||
Description: description,
|
Description: description,
|
||||||
Price: price,
|
|
||||||
IsPublic: true,
|
IsPublic: true,
|
||||||
Image: dst,
|
Image: dst,
|
||||||
|
Variants: variants,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tagId := range tagIds {
|
for _, tagId := range tagIds {
|
||||||
@@ -293,9 +312,10 @@ func (rc *shopItemController) EditItemHandler(c *gin.Context) {
|
|||||||
newShopItem.Name = shopItem.Name
|
newShopItem.Name = shopItem.Name
|
||||||
newShopItem.Abstract = shopItem.Abstract
|
newShopItem.Abstract = shopItem.Abstract
|
||||||
newShopItem.Description = shopItem.Description
|
newShopItem.Description = shopItem.Description
|
||||||
newShopItem.Price = shopItem.Price
|
newShopItem.BasePrice = shopItem.BasePrice
|
||||||
newShopItem.IsPublic = shopItem.IsPublic
|
newShopItem.IsPublic = shopItem.IsPublic
|
||||||
newShopItem.Tags = shopItem.Tags
|
newShopItem.Tags = shopItem.Tags
|
||||||
|
newShopItem.Variants = shopItem.Variants
|
||||||
|
|
||||||
tags, err := repositories.Tags.GetAll()
|
tags, err := repositories.Tags.GetAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -4,14 +4,34 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sticker
|
||||||
|
- name, abstr, descr, price, tag
|
||||||
|
Poster
|
||||||
|
- name, abstr, descr, price bw/colored, tag
|
||||||
|
Zines
|
||||||
|
- name, abstr, descr, price bw/colored/coloredcoveronly, tag
|
||||||
|
Books
|
||||||
|
- name, abstr, descr, price, tag
|
||||||
|
*/
|
||||||
|
|
||||||
|
type ItemVariant struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string `json:"name" gorm:"not null"`
|
||||||
|
Price float64 `json:"price" gorm:"not null"`
|
||||||
|
InStock bool `json:"inStock" gorm:"default:true"`
|
||||||
|
ShopItemID uint
|
||||||
|
}
|
||||||
|
|
||||||
type ShopItem struct {
|
type ShopItem struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
Name string `json:"name" binding:"required" gorm:"unique;not null"`
|
Name string `json:"name" binding:"required" gorm:"unique;not null"`
|
||||||
Abstract string `json:"Abstract" binding:"required"`
|
Abstract string `json:"Abstract" binding:"required"`
|
||||||
Description string `json:"description" binding:"required"`
|
Description string `json:"description" binding:"required"`
|
||||||
Price float64 `json:"price" binding:"required"`
|
Category string `json:"category"`
|
||||||
|
Variants []ItemVariant `json:"variant"`
|
||||||
|
BasePrice float64 `json:"basePrice"`
|
||||||
IsPublic bool `json:"isPublic" gorm:"default:true"`
|
IsPublic bool `json:"isPublic" gorm:"default:true"`
|
||||||
Tags []Tag `gorm:"many2many:item_tags;"`
|
Tags []Tag `gorm:"many2many:item_tags;"`
|
||||||
Image string
|
Image string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func InitRepositories() {
|
|||||||
panic("failed to connect to database")
|
panic("failed to connect to database")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db.AutoMigrate(&models.ShopItem{}, &models.User{}, &models.Tag{}, &models.CartItem{})
|
err = db.AutoMigrate(&models.ShopItem{}, &models.ItemVariant{}, &models.User{}, &models.Tag{}, &models.CartItem{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("failed to migrate database")
|
panic("failed to migrate database")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,14 +38,14 @@ func (r *GORMShopItemRepository) Create(shopItem models.ShopItem) (models.ShopIt
|
|||||||
|
|
||||||
func (r *GORMShopItemRepository) GetAll() ([]models.ShopItem, error) {
|
func (r *GORMShopItemRepository) GetAll() ([]models.ShopItem, error) {
|
||||||
var shopItems []models.ShopItem
|
var shopItems []models.ShopItem
|
||||||
result := r.DB.Preload("Tags").Find(&shopItems)
|
result := r.DB.Preload("Tags").Preload("Variants").Find(&shopItems)
|
||||||
|
|
||||||
return shopItems, result.Error
|
return shopItems, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *GORMShopItemRepository) GetAllPublic() ([]models.ShopItem, error) {
|
func (r *GORMShopItemRepository) GetAllPublic() ([]models.ShopItem, error) {
|
||||||
var shopItems []models.ShopItem
|
var shopItems []models.ShopItem
|
||||||
result := r.DB.Preload("Tags").Where("is_public = 1").Find(&shopItems)
|
result := r.DB.Preload("Tags").Preload("Variants").Where("is_public = 1").Find(&shopItems)
|
||||||
|
|
||||||
return shopItems, result.Error
|
return shopItems, result.Error
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ func (r *GORMShopItemRepository) GetById(id string) (models.ShopItem, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var shopItem models.ShopItem
|
var shopItem models.ShopItem
|
||||||
result := r.DB.Preload("Tags").First(&shopItem, uint(shopItemId))
|
result := r.DB.Preload("Tags").Preload("Variants").First(&shopItem, uint(shopItemId))
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return models.ShopItem{}, result.Error
|
return models.ShopItem{}, result.Error
|
||||||
@@ -74,6 +74,11 @@ func (r *GORMShopItemRepository) Update(shopItem models.ShopItem) (models.ShopIt
|
|||||||
return models.ShopItem{}, err
|
return models.ShopItem{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = r.DB.Model(&shopItem).Association("Variants").Replace(shopItem.Variants)
|
||||||
|
if err != nil {
|
||||||
|
return models.ShopItem{}, err
|
||||||
|
}
|
||||||
|
|
||||||
result := r.DB.Save(&shopItem)
|
result := r.DB.Save(&shopItem)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return models.ShopItem{}, result.Error
|
return models.ShopItem{}, result.Error
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ func (u *ShopItemService) NewShopItem(name string, abstract string, description
|
|||||||
Name: name,
|
Name: name,
|
||||||
Abstract: abstract,
|
Abstract: abstract,
|
||||||
Description: description,
|
Description: description,
|
||||||
Price: price,
|
BasePrice: price,
|
||||||
IsPublic: true,
|
IsPublic: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,14 +55,28 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
<input type="hidden" id="variant-name1" name="varian-name[]" value="B/W" required>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<label for="price" class="block text-sm/6 font-medium text-gray-900">Price</label>
|
<label for="variant-value1" class="block text-sm/6 font-medium text-gray-900">Price B/W</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<input type="number" name="price" id="price" step="0.01" min="0.00" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
|
<input type="number" name="variant-value[]" id="variant-value1" step="0.01" min="0.00" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<input type="hidden" id="variant-name2" name="varian-name[]" value="Colored" required>
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<label for="variant-value2" class="block text-sm/6 font-medium text-gray-900">Price Colored</label>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2">
|
||||||
|
<input type="number" name="variant-value[]" id="variant-value2" step="0.01" min="0.00" class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-sm font-medium text-gray-900">
|
<label class="block text-sm font-medium text-gray-900">
|
||||||
Image
|
Image
|
||||||
@@ -101,5 +115,40 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<form action="/submit-product" method="POST">
|
||||||
|
<label for="product-name">Product Name:</label>
|
||||||
|
<input type="text" id="product-name" name="product-name" required><br><br>
|
||||||
|
|
||||||
|
<label for="product-type">Product Type:</label>
|
||||||
|
<select id="product-type" name="product-type" required>
|
||||||
|
<option value="magazine">Magazine</option>
|
||||||
|
<option value="t-shirt">T-Shirt</option>
|
||||||
|
</select><br><br>
|
||||||
|
|
||||||
|
<h3>Options</h3>
|
||||||
|
<div class="option-group">
|
||||||
|
<label for="option-name-1">Option Name:</label>
|
||||||
|
<input type="text" id="option-name-1" name="option-name[]" required>
|
||||||
|
<label for="option-price-1">Price:</label>
|
||||||
|
<input type="number" id="option-price-1" name="option-price[]" required><br><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option-group">
|
||||||
|
<label for="option-name-2">Option Name:</label>
|
||||||
|
<input type="text" id="option-name-2" name="option-name[]" required>
|
||||||
|
<label for="option-price-2">Price:</label>
|
||||||
|
<input type="number" id="option-price-2" name="option-price[]" required><br><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option-group">
|
||||||
|
<label for="option-name-3">Option Name:</label>
|
||||||
|
<input type="text" id="option-name-3" name="option-name[]" required>
|
||||||
|
<label for="option-price-3">Price:</label>
|
||||||
|
<input type="number" id="option-price-3" name="option-price[]" required><br><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" value="Add Product">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
{{ template "footer.html" . }}
|
{{ template "footer.html" . }}
|
||||||
|
|||||||
@@ -32,10 +32,12 @@
|
|||||||
{{ .data.shopItem.Abstract }}
|
{{ .data.shopItem.Abstract }}
|
||||||
</p>
|
</p>
|
||||||
<div class="flex mb-4">
|
<div class="flex mb-4">
|
||||||
|
{{ range .data.shopItem.Variants }}
|
||||||
<div class="mr-4">
|
<div class="mr-4">
|
||||||
<span class="font-bold text-gray-700 dark:text-gray-300">Price:</span>
|
<span class="font-bold text-gray-700 dark:text-gray-300">{{ .Name }}:</span>
|
||||||
<span class="text-gray-600 dark:text-gray-300">{{ .data.shopItem.Price }}€</span>
|
<span class="text-gray-600 dark:text-gray-300">{{ .Price }}€</span>
|
||||||
</div>
|
</div>
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex mb-4">
|
<div class="flex mb-4">
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<!--<p class="mt-1 text-sm text-gray-500">{{ .Abstract }}</p>-->
|
<!--<p class="mt-1 text-sm text-gray-500">{{ .Abstract }}</p>-->
|
||||||
</div>
|
</div>
|
||||||
<p class="text-sm font-medium text-gray-900">{{ .Price }}€</p>
|
<p class="text-sm font-medium text-gray-900">{{ .BasePrice }}€</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user