Skip to content

Instantly share code, notes, and snippets.

@nicksherron
Created June 29, 2021 10:11
Show Gist options
  • Select an option

  • Save nicksherron/39d9163646775397e200ba67c3d3586b to your computer and use it in GitHub Desktop.

Select an option

Save nicksherron/39d9163646775397e200ba67c3d3586b to your computer and use it in GitHub Desktop.
package inventory_svc
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strconv"
"time"
"github.com/acenda/astur_golang_common/khor"
"github.com/acenda/astur_golang_common/khor/cache"
"github.com/acenda/astur_golang_common/sql/queryparser"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/render"
"github.com/go-playground/validator/v10"
"github.com/mitchellh/mapstructure"
"gorm.io/gorm"
)
var validate *validator.Validate
func CacheContext(cbCache *cache.CbCache) gin.HandlerFunc {
return func(c *gin.Context) {
c.Set("ca", cbCache)
c.Next()
}
}
func init() {
validate = validator.New()
}
// InventoryRead godoc
// @Summary Show a Inventory
// @Produce json
// @Param id path int true "Inventory ID"
// @Success 200 {array} Inventory
// @Router /inventory/{id} [get]
func (srv *InventoryController) InventoryRead(c *gin.Context) {
if c.IsAborted() {
return
}
var (
inventory []map[string]interface{}
// inventory []*Inventory
count int64
)
inventory = make([]map[string]interface{}, 100)
ctx := c.Request.Context()
ca := c.MustGet("ca").(*cache.CbCache)
cacheKey := cache.CreateGinKey(c)
//if b, err := ca.Get(ctx, cacheKey); err == nil {
// writeJsonType(c.Writer)
// c.Writer.Write(b)
// c.Writer.Flush()
// return
//}
_db := khor.GetDB(c)
db, err := queryparser.QueryToSQL(_db, c.Request.RequestURI)
if errorHandler(c, err) {
return
}
//stmt := db.Session(&gorm.Session{DryRun: true}).Debug().Joins("StockCommitment").Find(&inventory).Statement
//.Error; errorHandler(c, err) {
// return
//}
//
//fmt.Println(stmt.SQL.String())
//if err := db.Debug().Raw(stmt.SQL.String()).Scan(&inventory).Error; errorHandler(c, err) {
// panic(err)
//}
var inv []*Inventory
if err := db.Debug().Model(&inv).Joins("StockCommitments").Find(&inventory).Error; errorHandler(c, err) {
panic(err)
}
out := []Inventory{}
recs := make(map[int][]map[string]interface{}, len(inventory))
for _, v := range inventory {
if v == nil {
continue
}
id := v["id"].(int64)
recs[int(id)] = append(recs[int(id)], v)
//if id, ok := v["id"].(int64); ok {
// recs[int(id)] = append(recs[int(id)], v)
//} else {
// fmt.Println(v)
// continue
//}
}
for k := range recs {
o := Inventory{}
fmt.Printf("%#v\n", recs[k])
config := &mapstructure.DecoderConfig{
WeaklyTypedInput: false,
Result: &o,
}
decoder, err := mapstructure.NewDecoder(config)
if err != nil {
panic(err)
}
if err := decoder.Decode(recs[k][0]); errorHandler(c, err) {
panic(err)
}
fmt.Println("\n\n\n\n", o, "\n\n\n\n")
created_at := recs[k][0]["created_at"].(*time.Time)
updated_at := recs[k][0]["updated_at"].(*time.Time)
o.CreatedAt = created_at
o.UpdatedAt = updated_at
o.StockCommitments = []*StockCommitments{}
for _, vv := range recs[k] {
if vv == nil {
continue
}
//
//for kk, vvv := range vv {
// vv[strings.ReplaceAll(kk, "StockCommitments__", "")] = vvv
// delete(vv, kk)
//}
//
//ss := StockCommitments{}
//fmt.Printf("StockCommitments --- \n%#v\n---\n", vv)
//if err := mapstructure.Decode(vv, &ss); err != nil {
// fmt.Println(err)
// // fmt.Printf("StockCommitments --- \n%#v\n---\n", vv)
// continue
//}
//
//b, err := json.Marshal(&vv)
//if err != nil {
// fmt.Println(err)
// // fmt.Printf("StockCommitments --- \n%#v\n---\n", vv)
// continue
//}
//
//if err := json.Unmarshal(b, &ss); err != nil {
// fmt.Println(err)
// // fmt.Printf("StockCommitments --- \n%#v\n---\n", vv)
// continue
//}
id, ok := vv["StockCommitments__id"].(int64)
if !ok {
fmt.Printf("StockCommitments --- \n%#v\n---\n", vv)
continue
}
created_at := vv["StockCommitments__created_at"].(time.Time)
updated_at := vv["StockCommitments__updated_at"].(time.Time)
s := StockCommitments{
BaseModel: BaseModel{
ID: id,
CreatedAt: &created_at,
// CreatedBy: vv["StockCommitments__created_by"].(string),
UpdatedAt: &updated_at,
// UpdatedBy: vv["StockCommitments__updated_by"].(string),
},
}
if InventoryID, ok := vv["StockCommitments__inventory_id"].(int64); ok {
s.InventoryID = InventoryID
}
if Active, ok := vv["StockCommitments__active"].(bool); ok {
s.Active = Active
}
if Expiration, ok := vv["StockCommitments__expiration"].(time.Time); ok {
s.Expiration = Expiration
}
if LotId, ok := vv["StockCommitments__lot_id"].(string); ok {
s.LotId = LotId
}
if Policy, ok := vv["StockCommitments__policy"].(string); ok {
s.Policy = Policy
}
if Replenish, ok := vv["StockCommitments__replenish"].(bool); ok {
s.Replenish = Replenish
}
if TotalQuantity, ok := vv["StockCommitments__total_quantity"].(int64); ok {
s.TotalQuantity = TotalQuantity
}
if WarehouseId, ok := vv["StockCommitments__warehouse_id "].(int64); ok {
s.WarehouseId = WarehouseId
}
o.StockCommitments = append(o.StockCommitments, &s)
b, err := json.MarshalIndent(&s, ``, ` `)
if err != nil {
panic(err)
}
fmt.Println(string(b))
//}
}
out = append(out, o)
}
if err := mapstructure.Decode(inventory, &inv); errorHandler(c, err) {
panic(err)
}
fmt.Println(inv)
result := khor.APIResponse{
http.StatusOK,
nil,
int(count),
out,
}
writeJsonType(c.Writer)
b, err := json.Marshal(&result)
if errorHandler(c, err) {
return
}
c.Writer.Write(b)
err = ca.Add(ctx, cacheKey, b)
if err != nil {
fmt.Println(err)
}
}
// InventoryReadOne godoc
// @Summary Show a Inventory
// @Produce json
// @Param id path int true "Inventory ID"
// @Success 200 {object} Inventory
// @Router /inventory/{id} [get]
func (srv *InventoryController) InventoryReadOne(c *gin.Context) {
if c.IsAborted() {
return
}
var (
inventory Inventory
count int64
)
ctx := c.Request.Context()
ca := c.MustGet("ca").(*cache.CbCache)
cacheKey := cache.CreateGinKey(c)
if b, err := ca.Get(ctx, cacheKey); err == nil {
writeJsonType(c.Writer)
c.Writer.Write(b)
c.Writer.Flush()
return
}
db := khor.GetDB(c)
if err := c.ShouldBindUri(&inventory); errorHandler(c, err) {
return
}
if err := db.Joins("StockCommitments on StockCommitments.InventoryID = inventory.id").Find(&inventory).Error; errorHandler(c, err) {
return
}
if inventory.CreatedAt.IsZero() {
c.AbortWithStatus(http.StatusNotFound)
return
}
result := khor.APIResponse{
http.StatusOK,
nil,
int(count),
inventory,
}
writeJsonType(c.Writer)
b, err := json.Marshal(&result)
if errorHandler(c, err) {
return
}
c.Writer.Write(b)
err = ca.Add(ctx, cacheKey, b)
if err != nil {
fmt.Println(err)
}
}
// InventoryCreate godoc
// @Summary Create a Inventory
// @Accept json
// @Produce json
// @Param Inventory body Inventory true "Create Inventory"
// @Success 201 {object} Inventory
// @Router /inventory/ [post]
func (srv *InventoryController) InventoryCreate(c *gin.Context) {
db := khor.GetDB(c)
var inventory Inventory
if err := c.ShouldBindJSON(&inventory); errorHandler(c, err) {
return
}
if validationErrors := validate.Struct(inventory); errorHandler(c, validationErrors) {
return
}
if err := db.Save(&inventory).Error; errorHandler(c, err) {
return
}
result := khor.APIResponse{
http.StatusCreated,
nil,
1,
inventory,
}
c.JSON(http.StatusCreated, result)
}
// InventoryBulkCreate godoc
// @Summary Bulk create Inventories
// @Accept json
// @Produce json
// @Param Inventory body []Inventory true "Bulk create Inventories"
// @Success 201 {array} Inventory
// @Router /inventory/bulk [post]
func (srv *InventoryController) InventoryBulkCreate(c *gin.Context) {
ctx := c.Request.Context()
ca := c.MustGet("ca").(*cache.CbCache)
cacheKey := cache.CreateGinKey(c)
db := khor.GetDB(c)
var inventory []Inventory
if err := c.ShouldBindJSON(&inventory); errorHandler(c, err) {
return
}
for _, v := range inventory {
if validationErrors := validate.Struct(v); errorHandler(c, validationErrors) {
return
}
}
if err := db.Save(&inventory).Error; errorHandler(c, err) {
return
}
result := khor.APIResponse{
http.StatusCreated,
nil,
1,
inventory,
}
c.JSON(http.StatusCreated, result)
ca.Del(ctx, cacheKey)
}
// InventoryUpdate godoc
// @Summary Update a Inventory
// @Accept json
// @Produce json
// @Param id path int true "Inventory ID"
// @Param Inventory body Inventory true "Update Inventory"
// @Success 202 {object} Inventory
// @Router /inventory/{id} [put]
func (srv *InventoryController) InventoryUpdate(c *gin.Context) {
ctx := c.Request.Context()
ca := c.MustGet("ca").(*cache.CbCache)
cacheKey := cache.CreateGinKey(c)
db := khor.GetDB(c)
var inventory Inventory
if err := c.ShouldBindJSON(&inventory); errorHandler(c, err) {
return
}
// get id from path
paramId := c.Param("id")
if id, err := strconv.ParseUint(paramId, 10, 64); err != nil {
errorHandler(c, fmt.Errorf("invalid id of %v", paramId))
return
} else {
idPtr := int64(id)
inventory.ID = idPtr
}
if err := validate.Struct(inventory); err != nil {
// Iterate through validation errors and exclude and that are of type required
// since we allow empty fields in updates.
for _, er := range err.(validator.ValidationErrors) {
if er.Tag() == "required" {
continue
}
errorHandler(c, err)
return
}
}
rows := db.Model(&inventory).Updates(&inventory)
if errorHandler(c, rows.Error) {
return
}
if err := db.Find(&inventory).Error; errorHandler(c, err) {
return
}
result := khor.APIResponse{
http.StatusAccepted,
nil,
int(rows.RowsAffected),
inventory,
}
c.JSON(http.StatusAccepted, result)
ca.Del(ctx, cacheKey)
}
// InventoryDelete godoc
// @Summary Delete a Inventory
// @Param id path int true "Inventory ID"
// @Success 200
// @Router /inventory/{id} [delete]
func (srv *InventoryController) InventoryDelete(c *gin.Context) {
ctx := c.Request.Context()
ca := c.MustGet("ca").(*cache.CbCache)
cacheKey := cache.CreateGinKey(c)
db := khor.GetDB(c)
var modelID Inventory
if err := c.ShouldBindUri(&modelID); errorHandler(c, err) {
return
}
changed := db.Delete(&modelID).RowsAffected
result := khor.APIResponse{
http.StatusOK,
nil,
int(changed),
nil,
}
if changed == 0 {
result.Status = http.StatusNotFound
c.JSON(http.StatusNotFound, result)
return
}
c.JSON(http.StatusOK, result)
ca.Del(ctx, cacheKey)
}
func errorHandler(c *gin.Context, err error) bool {
if err != nil {
fmt.Println(err)
response := khor.APIResponse{}
response.Errors = make(map[string]interface{}, 1)
if errors.Is(err, gorm.ErrRecordNotFound) {
response.Status, response.Errors["error"] = http.StatusNotFound, err.Error()
c.JSON(http.StatusNotFound, response)
return true
}
response.Status, response.Errors["error"] = http.StatusBadRequest, err.Error()
c.IndentedJSON(http.StatusBadRequest, response)
return true
}
return false
}
type InventoryController struct {
Db *gorm.DB
Api *khor.KeycloakClient
khor.GenericCRUDController
}
func (ctrl *InventoryController) Setup(Db *gorm.DB, Api *khor.KeycloakClient) {
ctrl.Db = Db
ctrl.Api = Api
ctrl.GenericCRUDController.Setup(Db, Api)
ctrl.GenericCRUDController.Model = Inventory{}
}
func writeJsonType(w http.ResponseWriter) {
render.JSON{}.WriteContentType(w)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment