package models import ( "fmt" "git.dynamicdiscord.de/kalipso/zineshop/utils" "gorm.io/gorm" "math" "os/exec" "strings" ) type PrintOption string const ( CoverPage PrintOption = "-o FrontCoverPage=Printed -o FrontCoverTray=BypassTray" Colored PrintOption = "-o SelectColor=Color" Grayscale PrintOption = "-o SelectColor=Grayscale" LongEdge PrintOption = "" ShortEdge PrintOption = "-o Binding=TopBinding" CreateBooklet PrintOption = "-o Combination=Booklet -o PageSize=A5" TriFold PrintOption = "-o Fold=TriFold -o Binding=TopBinding" ) type OldPrintJob struct { Pdf string Amount uint Options []PrintOption } type Invoice struct { gorm.Model PrintJobs []PrintJob PricePerClick float64 PartCosts float64 PriceTotal float64 } type PrintJob struct { gorm.Model ShopItemID uint ShopItem ShopItem VariantID uint Variant ItemVariant PaperTypeId uint PaperType Paper `gorm:"foreignKey:PaperTypeId"` CoverPaperTypeId *uint CoverPaperType *Paper `gorm:"foreignKey:CoverPaperTypeId"` Amount uint PricePerPiece float64 PriceTotal float64 InvoiceID uint } func GetPrintMode(mode string) PrintOption { if mode == "LongEdge" { return LongEdge } if mode == "ShortEdge" { return ShortEdge } if mode == "TriFold" { return TriFold } return CreateBooklet } func NewPrintJob(shopItem ShopItem, variant ItemVariant, paperType Paper, coverPaperType *Paper, amount uint) (PrintJob, error) { if shopItem.Pdf == "" { return PrintJob{}, fmt.Errorf("ShopItem has no PDF assigned") } if amount > 100 { return PrintJob{}, fmt.Errorf("Amount to big. This is denied for security reasons") } result := PrintJob{ ShopItem: shopItem, Variant: variant, PaperType: paperType, CoverPaperType: coverPaperType, Amount: amount, } return result, nil } func (p *PrintJob) IsColored() bool { return p.Variant.Name == "Colored" } func (p *PrintJob) GeneratePrintOptions() []PrintOption { var result []PrintOption if p.Variant.Name == "Colored" { result = append(result, Colored) } if p.CoverPaperType != nil { result = append(result, CoverPage) } result = append(result, GetPrintMode(p.ShopItem.PrintMode)) return result } func (p *PrintJob) Execute() error { baseCommand := "lp -d KonicaBooklet" baseCommand += fmt.Sprintf(" -n %v ", p.Amount) for _, option := range p.GeneratePrintOptions() { baseCommand += fmt.Sprintf(" %v ", option) } baseCommand += fmt.Sprintf(" -- %s", p.ShopItem.Pdf) parts := strings.Fields(baseCommand) // The first part is the command, the rest are the arguments fmt.Println(parts) cmd := exec.Command(parts[0], parts[1:]...) output, err := cmd.CombinedOutput() if err != nil { fmt.Printf("Error: %s\n", err) return err } fmt.Printf("Output:\n%s\n", output) return nil } func (p *PrintJob) CalculatePrintCosts() (float64, error) { pageCount := utils.CountPagesAtPath(p.ShopItem.Pdf) if pageCount == 0 { fmt.Println("Pagecount of 0 - something is wrong here.") return 0, fmt.Errorf("Cant calculate price, pdf seems to be empty") } printMode := GetPrintMode(p.ShopItem.PrintMode) //Get actual pagecount depending on printmode actualPageCount := pageCount fmt.Println("PagCount: ", actualPageCount) if printMode == CreateBooklet { dividedCount := float64(pageCount) / 4.0 actualPageCount = int(math.Ceil(dividedCount)) } if printMode == LongEdge || printMode == ShortEdge { dividedCount := float64(pageCount) / 2.0 actualPageCount = int(math.Ceil(dividedCount)) } PPC := 0.002604 partCost := 0.0067 if p.IsColored() { partCost = 0.0478 } printingCosts := float64(actualPageCount-1) * p.PaperType.Price if p.CoverPaperType != nil { printingCosts += p.CoverPaperType.Price } else { printingCosts += p.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(p.Amount)) p.PricePerPiece = printingCosts p.PriceTotal = printingCosts * float64(p.Amount) return printingCosts, nil }