Skip to content
Snippets Groups Projects
price.go 4.97 KiB
Newer Older
  • Learn to ignore specific revisions
  • package models
    
    import (
    	"encoding/json"
    	"log"
    	"net/http"
    	"time"
    
    
    	"forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-server/internal/common"
    
    	"gorm.io/gorm"
    )
    
    type Price struct {
    
    	FluidType int     `json:"fluidType"`
    	Price     float32 `json:"price"`
    	StartDate string  `json:"startDate"`
    	EndDate   string  `json:"endDate"`
    
    	gorm.Model
    }
    
    // GetPrices godoc
    
    //	@Summary		Get all prices
    //	@Description	Get all prices
    //	@Tags			prices
    //	@Produce		json
    //	@Success		200	{object}	object
    //	@Failure		404	{string}	string	"Not found"
    //	@Router			/api/common/prices [get]
    
    func (dh *DataHandler) GetAllPrices(w http.ResponseWriter, r *http.Request) {
    	var prices []Price
    
    	dh.sqlClient.Find(&prices)
    
    
    	w.Header().Set("Content-Type", "application/json")
    	json.NewEncoder(w).Encode(prices)
    	log.Printf("| Get all prices | %v", r.RemoteAddr)
    }
    
    // GetPricesByFluid godoc
    
    //	@Summary		Get all prices for a given fluid
    //	@Description	Get all prices for a given fluid
    //	@Tags			prices
    //	@Produce		json
    //	@Success		200			{object}	object
    //	@Failure		404			{string}	string	"Not found"
    //	@Param			fluidtype	path		int		true	"FluidType requested"
    //	@Router			/api/common/prices/fluidType [get]
    
    func (dh *DataHandler) GetPricesByFluid(w http.ResponseWriter, r *http.Request) {
    	fluidtype, err := common.FluidTypeFromRequest(r)
    	if err != nil {
    		http.Error(w, err.Error(), http.StatusBadRequest)
    		return
    	}
    	var price []Price
    	w.Header().Set("Content-Type", "application/json")
    
    	err = dh.sqlClient.Where("fluid_type = ? ", fluidtype).Order("start_date desc").Find(&price).Error
    
    
    	if err != nil {
    		http.Error(w, err.Error(), http.StatusBadRequest)
    		return
    	}
    	json.NewEncoder(w).Encode(price)
    
    	log.Printf("| Get prices by fluid : %v | %v", fluidtype, r.RemoteAddr)
    
    //	@Summary		Add a new price entry
    //	@Description	Add a new price entry
    //	@Tags			prices
    //	@Accept			json
    //	@Produce		json
    //	@Success		200		{object}	object	"Updated successfully"
    //	@Failure		400		{string}	string	"Bad Request"
    //	@Failure		500		{string}	string	"Internal server error"
    //	@Param			price	body		object	true	"Price to create/update with new content"
    
    //	@Router			/api/animator/price [put]
    
    func (dh *DataHandler) SavePrice(w http.ResponseWriter, r *http.Request) {
    	if r.Body == http.NoBody {
    		http.Error(w, "request body price is empty", http.StatusBadRequest)
    		return
    	}
    
    	decoder := json.NewDecoder(r.Body)
    	var price Price
    	err := decoder.Decode(&price)
    	if err != nil {
    		println("JSON decoding error")
    		w.WriteHeader(http.StatusInternalServerError)
    		return
    	}
    
    	// Check if this price exists
    
    	err = dh.sqlClient.Where("fluid_type = ? AND start_date = ?", price.FluidType, price.StartDate).First(&Price{}).Error
    
    
    	if err != nil {
    		println("Price does not exist in database")
    		//Gets the last price for this fluid
    		var lastPrice Price
    
    		err = dh.sqlClient.Where("fluid_type = ?", price.FluidType).Order("start_date desc").Limit(1).Find(&lastPrice).Error
    
    		if err != nil {
    			println("Failed to get last price for this fluid")
    			w.WriteHeader(http.StatusInternalServerError)
    			return
    		}
    		// Replace previous endDate from null to startDate - 1 minute
    		t, _ := time.Parse(time.RFC3339, price.StartDate)
    		updatedEndDate := t.Add(-1 * time.Minute).Format(time.RFC3339)
    		lastPrice.EndDate = updatedEndDate
    
    
    		dh.sqlClient.Save(&lastPrice)
    
    		log.Printf("updated last price")
    
    		// Create a new price
    
    		err = dh.sqlClient.Create(&Price{
    			FluidType: price.FluidType,
    			Price:     price.Price,
    			StartDate: price.StartDate,
    			EndDate:   "",
    
    		}).Error
    		if err != nil {
    			println("Failed to create price")
    			w.WriteHeader(http.StatusInternalServerError)
    			return
    		}
    		w.WriteHeader(http.StatusCreated)
    		json.NewEncoder(w).Encode(price)
    		log.Printf("| new price | fluidType : %d price : %v | %v", price.FluidType, price.Price, r.RemoteAddr)
    		return
    
    	} else {
    		var editablePrices []Price
    		priceToUpdate := price
    		isEditable := false
    		// If price is not included in the last 3 editable prices, throw error
    
    		err = dh.sqlClient.Where("fluid_type = ? ", price.FluidType).Order("start_date desc").Limit(3).Find(&editablePrices).Error
    
    		if err != nil {
    			w.WriteHeader(http.StatusInternalServerError)
    			return
    		}
    
    		for _, p := range editablePrices {
    			if p.StartDate == price.StartDate {
    				isEditable = true
    			}
    		}
    
    		if isEditable == false {
    			w.WriteHeader(http.StatusForbidden)
    			log.Printf("Unallowed to edit price because is not included in the the last 3 editable prices")
    			return
    		}
    		// Update existing price
    
    		err = dh.sqlClient.Model(&Price{}).Where("start_date = ? AND fluid_type = ?", priceToUpdate.StartDate, priceToUpdate.FluidType).Update("price", priceToUpdate.Price).Error
    
    		if err != nil {
    			w.WriteHeader(http.StatusInternalServerError)
    			return
    		}
    
    		w.Header().Set("Content-Type", "application/json")
    		json.NewEncoder(w).Encode(priceToUpdate)
    		log.Printf("| Updated price | fluidType : %d price : %v | startDate : %v | %v", priceToUpdate.FluidType, priceToUpdate.Price, priceToUpdate.StartDate, r.RemoteAddr)
    	}
    }