From 8e1df934b3f69074020e1667da1c24b99dad5aaa Mon Sep 17 00:00:00 2001 From: kalipso Date: Sun, 29 Jun 2025 16:57:51 +0200 Subject: [PATCH] WIP cost calculation --- controllers/printController.go | 74 ++++++++++++++++++++++++++++++++-- utils/utils.go | 41 +++++++++++++++++++ 2 files changed, 111 insertions(+), 4 deletions(-) diff --git a/controllers/printController.go b/controllers/printController.go index f917cd2..9fa5bda 100644 --- a/controllers/printController.go +++ b/controllers/printController.go @@ -2,11 +2,13 @@ package controllers import ( "fmt" + "math" "net/http" "strconv" "git.dynamicdiscord.de/kalipso/zineshop/models" "git.dynamicdiscord.de/kalipso/zineshop/repositories" + "git.dynamicdiscord.de/kalipso/zineshop/utils" "github.com/gin-gonic/gin" ) @@ -63,7 +65,14 @@ func (rc *printController) PrintCartView(c *gin.Context) { return } + paper, err := repositories.Papers.GetAll() + if err != nil { + c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}}) + return + } + data := CreateSessionData(c, gin.H{ + "paper": paper, "cartItems": cartItems, }) @@ -78,9 +87,16 @@ func (rc *printController) PrintOrderView(c *gin.Context) { return } + paper, err := repositories.Papers.GetAll() + if err != nil { + c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}}) + return + } + cartItems := order.CartItems data := CreateSessionData(c, gin.H{ + "paper": paper, "cartItems": cartItems, }) @@ -90,6 +106,7 @@ func (rc *printController) PrintOrderView(c *gin.Context) { func (rc *printController) PrintHandler(c *gin.Context) { variantIds := c.PostFormArray("variant-id[]") variantAmounts := c.PostFormArray("variant-amount[]") + variantPapertypes := c.PostFormArray("variant-papertype[]") variantCoverPages := c.PostFormArray("variant-coverpage[]") if len(variantIds) != len(variantAmounts) || len(variantIds) != len(variantCoverPages) { @@ -113,9 +130,53 @@ func (rc *printController) PrintHandler(c *gin.Context) { return } - coverPage := false - if variantCoverPages[idx] == "1" { - coverPage = true + paperType, err := repositories.Papers.GetById(fmt.Sprintf("%v", variantPapertypes[idx])) + if err != nil { + c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}}) + return + } + + var coverPage models.Paper + doPrintCoverpage := false + if variantCoverPages[idx] != "0" { + coverPage, err = repositories.Papers.GetById(fmt.Sprintf("%v", variantCoverPages[idx])) + if err != nil { + c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}}) + return + } + + doPrintCoverpage = true + } + + calculatePrintCosts := func(shopItem models.ShopItem, paperType models.Paper, coverPagePaperType models.Paper, colored bool, amount int) (float64, error) { + pageCount := utils.CountPagesAtPath(shopItem.Pdf) + printMode := models.GetPrintMode(shopItem.PrintMode) + + //Get actual pagecount depending on printmode + actualPageCount := pageCount + + if printMode == models.CreateBooklet { + dividedCount := float64(pageCount) / 4.0 + actualPageCount = int(math.Ceil(dividedCount)) + } + + if printMode == models.LongEdge || printMode == models.ShortEdge { + dividedCount := float64(pageCount) / 2.0 + actualPageCount = int(math.Ceil(dividedCount)) + } + + PPC := 0.002604 + partCost := 0.0067 + if colored { + partCost = 0.0478 + } + printingCosts := float64(actualPageCount) * paperType.Price + printingCosts += float64(actualPageCount/2) * PPC + printingCosts += partCost * float64(actualPageCount) + + fmt.Printf("Printing Costs per Zine: %v\n", printingCosts) + fmt.Printf("Printing Costs Total: %v\n", printingCosts*float64(amount)) + return printingCosts, nil } variantAmount, err := strconv.Atoi(variantAmounts[idx]) @@ -124,7 +185,12 @@ func (rc *printController) PrintHandler(c *gin.Context) { return } - printJob, err := models.NewPrintJob(shopItem, variant, coverPage, uint(variantAmount)) + fmt.Println("Printing Costs:") + + colored := variant.Name == "Colored" + calculatePrintCosts(shopItem, paperType, coverPage, colored, int(variantAmount)) + + printJob, err := models.NewPrintJob(shopItem, variant, doPrintCoverpage, uint(variantAmount)) if err != nil { c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}}) diff --git a/utils/utils.go b/utils/utils.go index 66c4d20..107aaac 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,8 +1,11 @@ package utils import ( + "bufio" "crypto/rand" "encoding/hex" + "io" + "os" ) func GenerateSessionId(length int) string { @@ -17,3 +20,41 @@ func GenerateSessionId(length int) string { func GenerateToken() string { return GenerateSessionId(16) } + +const match = "/Page\x00" + +// Pages reads the given io.ByteReader until EOF is reached, returning the +// number of pages encountered. +func Pages(reader io.ByteReader) (pages int) { + i := 0 + for { + b, err := reader.ReadByte() + if err != nil { + return + } + check: + switch match[i] { + case 0: + if !(b >= 'A' && b <= 'Z' || b >= 'a' && b <= 'z') { + pages++ + } + i = 0 + goto check + case b: + i++ + default: + i = 0 + } + } +} + +// PagesAtPath opens a PDF file at the given file path, returning the number +// of pages found. +func CountPagesAtPath(path string) (pages int) { + if reader, err := os.Open(path); err == nil { + reader.Chdir() + pages = Pages(bufio.NewReader(reader)) + reader.Close() + } + return +}