Created
June 29, 2021 10:11
-
-
Save nicksherron/39d9163646775397e200ba67c3d3586b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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