Skip to content
Snippets Groups Projects
purchase.go 2.73 KiB
Newer Older
  • Learn to ignore specific revisions
  • meskio's avatar
    meskio committed
    package api
    
    import (
    	"encoding/json"
    	"log"
    	"net/http"
    	"time"
    
    	"gorm.io/gorm"
    )
    
    type Purchase struct {
    
    meskio's avatar
    meskio committed
    	gorm.Model    `json:"-"`
    	TransactionID int     `json:"-" gorm:"column:transaction"`
    
    	ProductCode   int     `json:"code" gorm:"column:product"`
    	Product       Product `json:"product" gorm:"foreignKey:ProductCode;references:Code"`
    
    meskio's avatar
    meskio committed
    	Price         int     `json:"price"`
    	Ammount       int     `json:"ammount"`
    
    meskio's avatar
    meskio committed
    }
    
    func (a *api) AddPurchase(num int, w http.ResponseWriter, req *http.Request) {
    
    meskio's avatar
    meskio committed
    	var purchase []Purchase
    	err := json.NewDecoder(req.Body).Decode(&purchase)
    
    meskio's avatar
    meskio committed
    	if err != nil {
    		log.Printf("Can't create purchase: %v", err)
    		w.WriteHeader(http.StatusInternalServerError)
    		return
    	}
    	total := 0
    
    meskio's avatar
    meskio committed
    	for i, p := range purchase {
    
    meskio's avatar
    meskio committed
    		var product Product
    
    		err = a.db.Where("code = ?", p.ProductCode).First(&product).Error
    
    meskio's avatar
    meskio committed
    		if err != nil {
    			log.Printf("Can't get product %d: %v", p.ProductCode, err)
    
    			w.WriteHeader(http.StatusNotAcceptable)
    
    meskio's avatar
    meskio committed
    			return
    		}
    
    		total += product.Price * p.Ammount
    
    meskio's avatar
    meskio committed
    		purchase[i].Price = product.Price
    
    meskio's avatar
    meskio committed
    	}
    
    meskio's avatar
    meskio committed
    	if total == 0 {
    		log.Printf("Empty purchase (%d)", num)
    		w.WriteHeader(http.StatusNotAcceptable)
    		return
    	}
    
    meskio's avatar
    meskio committed
    
    
    	httpStatus := a.substractMemberBalance(num, total)
    	if httpStatus != http.StatusOK {
    		w.WriteHeader(httpStatus)
    
    meskio's avatar
    meskio committed
    	transaction := Transaction{
    
    meskio's avatar
    meskio committed
    		MemberNum: num,
    		Date:      time.Now(),
    
    meskio's avatar
    meskio committed
    		Purchase:  purchase,
    		Type:      "purchase",
    
    meskio's avatar
    meskio committed
    		Total:     total,
    
    meskio's avatar
    meskio committed
    	}
    
    meskio's avatar
    meskio committed
    	err = a.db.Create(&transaction).Error
    
    meskio's avatar
    meskio committed
    	if err != nil {
    		log.Printf("Can't create purchase: %v\n%v", err, purchase)
    		w.WriteHeader(http.StatusInternalServerError)
    		return
    	}
    
    
    meskio's avatar
    meskio committed
    	for _, p := range purchase {
    
    meskio's avatar
    meskio committed
    		err := a.db.Model(&Product{}).
    			Where("code = ?", p.ProductCode).
    			Update("stock", gorm.Expr("stock - ?", p.Ammount)).Error
    		if err != nil {
    
    			log.Printf("Can't update product stock %d-%d: %v", p.ProductCode, p.Ammount, err)
    
    meskio's avatar
    meskio committed
    		}
    	}
    
    	w.Header().Set("Content-Type", "application/json")
    	w.WriteHeader(http.StatusCreated)
    
    meskio's avatar
    meskio committed
    	err = json.NewEncoder(w).Encode(transaction)
    
    meskio's avatar
    meskio committed
    	if err != nil {
    		log.Printf("Can't encode added purchase: %v", err)
    		w.WriteHeader(http.StatusInternalServerError)
    	}
    
    }
    
    
    func (a *api) substractMemberBalance(num int, total int) int {
    	var member Member
    	err := a.db.Where("num = ?", num).Find(&member).Error
    	if err != nil {
    		log.Printf("Can't find member %d: %v", num, err)
    		return http.StatusNotAcceptable
    	}
    	if member.Balance < total {
    		log.Printf("Member %d don't have enough money (%d-%d)", num, member.Balance, total)
    		return http.StatusBadRequest
    	}
    	err = a.db.Model(&Member{}).
    		Where("num = ?", num).
    		Update("balance", gorm.Expr("balance - ?", total)).Error
    	if err != nil {
    		log.Printf("Can't update update member balance %d-%d: %v", num, total, err)
    		return http.StatusNotAcceptable
    	}
    	return http.StatusOK
    }