package main import ( "bytes" "fmt" "html/template" "log" "net/http" "path" "time" "github.com/gin-gonic/gin" "gopkg.in/gomail.v2" ) const SHIPPING = 250 func sendMail(preOrder PreOrder, config Config) { tpl, err := template.ParseFiles(path.Join(ROOT_DIR, "templates/preorder.email")) if err != nil { panic(err) } m := gomail.NewMessage() var w bytes.Buffer data := map[string]interface{}{ "preOrder": preOrder, } tpl.Execute(&w, data) m.SetHeader("From", config.FromAddr) m.SetHeader("To", preOrder.Email) m.SetAddressHeader("Bcc", config.BCC, "admin") m.SetHeader("Subject", "Flip Noorman bestelling | Flip speelt cohen") m.SetBody("text/html", w.String()) d := gomail.NewDialer(config.MailServer, config.MailPort, config.MailUser, config.MailPass) // Send the email to Bob, Cora and Dan. if err := d.DialAndSend(m); err != nil { panic(err) } } func preorderIndex(c *gin.Context) { db := getDB(c) products := []Product{} db.Where("id = 2").Find(&products) c.HTML(http.StatusOK, "preorder_index.html", map[string]interface{}{ "products": products, "nowYear": time.Now().Format("2006"), }) } func postGetOrderInfo(c *gin.Context) { db := getDB(c) var order struct { CD int `form:"product[2]"` } c.Bind(&order) product := Product{} db.Where("id = 2").Find(&product) subtotal := product.Price * order.CD shipping := SHIPPING total := subtotal + shipping c.HTML(http.StatusOK, "preorder_info.html", map[string]interface{}{ "orderCount": order.CD, "product": product, "subtotal": subtotal, "shipping": shipping, "total": total, "error_": "", }) } func renderGetOrderInfoError(error_ string, count int, c *gin.Context) { db := getDB(c) product := Product{} db.Where("id = 2").Find(&product) subtotal := product.Price * count shipping := SHIPPING total := subtotal + shipping c.HTML(http.StatusOK, "preorder_info.html", map[string]interface{}{ "orderCount": count, "product": product, "subtotal": subtotal, "shipping": shipping, "total": total, "error_": error_, }) } func postCreateOrder(c *gin.Context) { db := getDB(c) products := []Product{} db.Find(&products) var order struct { DVD int `form:"product_count"` Name string `form:"name"` Email string `form:"email"` Address string `form:"address"` Postcode string `form:"postcode"` City string `form:"city"` } c.Bind(&order) if order.Name == "" || order.Email == "" || order.Address == "" || order.Postcode == "" || order.City == "" || order.DVD < 0 { renderGetOrderInfoError("Alle velden zijn verplicht", order.DVD, c) return } preOrder := PreOrder{ Name: order.Name, Email: order.Email, Address: order.Address, Postcode: order.Postcode, City: order.City, Status: PRE_ORDER_STATE_CREATED, } db.Create(&preOrder) for i := 0; i < order.DVD; i++ { db.Create(&Item{ ProductID: 2, PreOrderID: preOrder.ID, }) } db.Preload("Items").Preload("Items.Product").Find(&preOrder) payment, err := createMolliePayment(preOrder) if err != nil { log.Printf("[err] createMolliePayment: %v", err) c.AbortWithError(500, fmt.Errorf("Er is iets fout gegaan...")) return } molliePayment := MolliePayment{ MolliePaymentID: payment.ID, Amount: preOrder.CalcTotal() + SHIPPING, Status: payment.Status, PreOrderID: preOrder.ID, } db.Create(&molliePayment) c.Redirect(http.StatusFound, payment.Links.Checkout.Href) } func postMollieWebhook(c *gin.Context) { db := getDB(c) paymentID := c.Request.FormValue("id") payment, err := mollieClient.Payments.Get(paymentID, nil) if err != nil { log.Printf("Error get payment from mollie; %v; %s", err, paymentID) c.AbortWithError(500, fmt.Errorf("Deze bestelling is onbekend")) return } molliePayment := &MolliePayment{} if err := db.Preload("PreOrder").Where("mollie_payment_id = ?", paymentID).Find(&molliePayment).Error; err != nil { log.Printf("Error get payment from db; %v; %s", err, paymentID) c.AbortWithError(500, fmt.Errorf("Deze bestelling is onbekend")) return } if payment.Status != molliePayment.Status { molliePayment.Status = payment.Status db.Save(&molliePayment) if molliePayment.Status == "paid" { sendMail(molliePayment.PreOrder, config) } } c.Status(200) } func postOrderRetry(c *gin.Context) { orderID := c.Param("orderid") db := getDB(c) preOrder := &PreOrder{} if err := db.Preload("Items").Preload("Items.Product").Where("id = ?", orderID).Find(&preOrder).Error; err != nil { c.AbortWithError(500, fmt.Errorf("Deze bestelling is onbekend")) return } db.Find(&preOrder) payment, err := createMolliePayment(*preOrder) if err != nil { c.AbortWithError(500, fmt.Errorf("Er is iets fout gegaan...")) return } molliePayment := MolliePayment{ MolliePaymentID: payment.ID, Amount: preOrder.CalcTotal() + SHIPPING, Status: payment.Status, PreOrderID: preOrder.ID, } db.Create(&molliePayment) c.Redirect(http.StatusFound, payment.Links.Checkout.Href) } func getPendingOrder(c *gin.Context) { orderID := c.Param("orderid") db := getDB(c) payments := []*MolliePayment{} if err := db.Where("pre_order_id = ?", orderID).Order("created_at desc").Find(&payments).Error; err != nil { c.AbortWithError(500, fmt.Errorf("Deze bestelling is onbekend")) return } payment := payments[0] if payment.Status == "paid" { c.Redirect(http.StatusFound, "/preorder/bedankt") return } c.HTML(http.StatusOK, "preorder_pending.html", map[string]interface{}{"payment": payment, "orderID": orderID}) } func getPreOrderThankYou(c *gin.Context) { c.HTML(http.StatusOK, "preorder_thankyou.html", nil) }