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 | Love it!")
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)
}