mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
FEAT[BE] :add type filtering and validation to product warehouse services
This commit is contained in:
+1
@@ -32,6 +32,7 @@ func (u *ProductWarehouseController) GetAll(c *fiber.Ctx) error {
|
|||||||
Flags: c.Query("flags", ""),
|
Flags: c.Query("flags", ""),
|
||||||
KandangId: uint(c.QueryInt("kandang_id", 0)),
|
KandangId: uint(c.QueryInt("kandang_id", 0)),
|
||||||
TransferContext: c.Query(utils.TransferContextKey, ""),
|
TransferContext: c.Query(utils.TransferContextKey, ""),
|
||||||
|
Type: c.Query("type", ""),
|
||||||
}
|
}
|
||||||
|
|
||||||
if query.Page < 1 || query.Limit < 1 {
|
if query.Page < 1 || query.Limit < 1 {
|
||||||
|
|||||||
+4
-3
@@ -168,9 +168,10 @@ func (r *ProductWarehouseRepositoryImpl) ApplyFlagsFilter(db *gorm.DB, flags []s
|
|||||||
}
|
}
|
||||||
|
|
||||||
return db.
|
return db.
|
||||||
Joins("JOIN products ON products.id = product_warehouses.product_id").
|
Joins("JOIN products p_flag ON p_flag.id = product_warehouses.product_id").
|
||||||
Joins("JOIN flags ON flags.flagable_id = products.id AND flags.flagable_type = ?", "products").
|
Joins("JOIN flags f_flag ON f_flag.flagable_id = p_flag.id AND f_flag.flagable_type = ?", "products").
|
||||||
Where("flags.name IN ?", flags)
|
Where("f_flag.name IN ?", flags).
|
||||||
|
Distinct()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ProductWarehouseRepositoryImpl) AdjustQuantities(ctx context.Context, deltas map[uint]float64, modifier func(*gorm.DB) *gorm.DB) error {
|
func (r *ProductWarehouseRepositoryImpl) AdjustQuantities(ctx context.Context, deltas map[uint]float64, modifier func(*gorm.DB) *gorm.DB) error {
|
||||||
|
|||||||
+22
-1
@@ -99,6 +99,12 @@ func (s productWarehouseService) GetAll(c *fiber.Ctx, params *validation.Query)
|
|||||||
|
|
||||||
offset := (params.Page - 1) * params.Limit
|
offset := (params.Page - 1) * params.Limit
|
||||||
|
|
||||||
|
if params.Type != "" {
|
||||||
|
if !utils.IsValidMarketingType(params.Type) {
|
||||||
|
return nil, 0, fiber.NewError(fiber.StatusBadRequest, "Invalid marketing type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cleanFlags := utils.ParseFlags(params.Flags)
|
cleanFlags := utils.ParseFlags(params.Flags)
|
||||||
|
|
||||||
productWarehouses, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
productWarehouses, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
||||||
@@ -128,7 +134,22 @@ func (s productWarehouseService) GetAll(c *fiber.Ctx, params *validation.Query)
|
|||||||
db = db.Where("warehouse_id = ?", params.WarehouseId)
|
db = db.Where("warehouse_id = ?", params.WarehouseId)
|
||||||
}
|
}
|
||||||
|
|
||||||
db = s.Repository.ApplyFlagsFilter(db, cleanFlags)
|
if params.Type != "" {
|
||||||
|
switch params.Type {
|
||||||
|
case string(utils.MarketingTypeAyamPullet):
|
||||||
|
db = s.Repository.ApplyFlagsFilter(db, []string{string(utils.FlagDOC), string(utils.FlagPullet), string(utils.FlagLayer)})
|
||||||
|
case string(utils.MarketingTypeAyam):
|
||||||
|
db = s.Repository.ApplyFlagsFilter(db, []string{string(utils.FlagAyamAfkir), string(utils.FlagAyamCulling), string(utils.FlagAyamMati)})
|
||||||
|
case string(utils.MarketingTypeTelur):
|
||||||
|
db = s.Repository.ApplyFlagsFilter(db, []string{string(utils.FlagTelur), string(utils.FlagTelurUtuh), string(utils.FlagTelurPecah), string(utils.FlagTelurPutih), string(utils.FlagTelurRetak)})
|
||||||
|
case string(utils.MarketingTypeTrading):
|
||||||
|
db = s.Repository.ApplyFlagsFilter(db, []string{string(utils.FlagPakan), string(utils.FlagPreStarter), string(utils.FlagStarter), string(utils.FlagFinisher), string(utils.FlagOVK), string(utils.FlagObat), string(utils.FlagVitamin), string(utils.FlagKimia), string(utils.FlagEkspedisi)})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cleanFlags) > 0 {
|
||||||
|
db = s.Repository.ApplyFlagsFilter(db, cleanFlags)
|
||||||
|
}
|
||||||
|
|
||||||
return db.Order("product_warehouses.id DESC")
|
return db.Order("product_warehouses.id DESC")
|
||||||
})
|
})
|
||||||
|
|||||||
+1
@@ -20,4 +20,5 @@ type Query struct {
|
|||||||
Flags string `query:"flags" validate:"omitempty"`
|
Flags string `query:"flags" validate:"omitempty"`
|
||||||
KandangId uint `query:"kandang_id" validate:"omitempty,number,min=1"`
|
KandangId uint `query:"kandang_id" validate:"omitempty,number,min=1"`
|
||||||
TransferContext string `query:"transfer_context" validate:"omitempty,oneof=inventory_transfer"`
|
TransferContext string `query:"transfer_context" validate:"omitempty,oneof=inventory_transfer"`
|
||||||
|
Type string `query:"type" validate:"omitempty,oneof=AYAM TELUR TRADING AYAM_PULLET"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,13 +289,7 @@ func (s *deliveryOrdersService) CreateOne(c *fiber.Ctx, req *validation.Delivery
|
|||||||
itemDeliveryDate = &parsedDate
|
itemDeliveryDate = &parsedDate
|
||||||
}
|
}
|
||||||
|
|
||||||
totalWeight := requestedProduct.Qty * requestedProduct.AvgWeight
|
totalWeight, totalPrice := s.calculatePriceByMarketingType(marketing.MarketingType, requestedProduct.Qty, requestedProduct.AvgWeight, requestedProduct.UnitPrice, foundMarketingProduct.Week)
|
||||||
var totalPrice float64
|
|
||||||
if marketing.MarketingType == string(utils.MarketingTypeTrading) {
|
|
||||||
totalPrice = requestedProduct.Qty * requestedProduct.UnitPrice
|
|
||||||
} else {
|
|
||||||
totalPrice = totalWeight * requestedProduct.UnitPrice
|
|
||||||
}
|
|
||||||
|
|
||||||
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
|
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
|
||||||
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
|
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
|
||||||
@@ -421,13 +415,7 @@ func (s deliveryOrdersService) UpdateOne(c *fiber.Ctx, req *validation.DeliveryO
|
|||||||
itemDeliveryDate = deliveryProduct.DeliveryDate
|
itemDeliveryDate = deliveryProduct.DeliveryDate
|
||||||
}
|
}
|
||||||
|
|
||||||
totalWeight := requestedProduct.Qty * requestedProduct.AvgWeight
|
totalWeight, totalPrice := s.calculatePriceByMarketingType(marketing.MarketingType, requestedProduct.Qty, requestedProduct.AvgWeight, requestedProduct.UnitPrice, foundMarketingProduct.Week)
|
||||||
var totalPrice float64
|
|
||||||
if marketing.MarketingType == string(utils.MarketingTypeTrading) {
|
|
||||||
totalPrice = requestedProduct.Qty * requestedProduct.UnitPrice
|
|
||||||
} else {
|
|
||||||
totalPrice = totalWeight * requestedProduct.UnitPrice
|
|
||||||
}
|
|
||||||
|
|
||||||
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
|
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
|
||||||
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
|
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
|
||||||
@@ -471,6 +459,20 @@ func (s deliveryOrdersService) UpdateOne(c *fiber.Ctx, req *validation.DeliveryO
|
|||||||
return s.getMarketingWithDeliveries(c, id)
|
return s.getMarketingWithDeliveries(c, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *deliveryOrdersService) calculatePriceByMarketingType(marketingType string, qty, avgWeight, unitPrice float64, week *int) (totalWeight, totalPrice float64) {
|
||||||
|
if marketingType == string(utils.MarketingTypeTrading) {
|
||||||
|
totalWeight = 0
|
||||||
|
totalPrice = qty * unitPrice
|
||||||
|
} else if marketingType == string(utils.MarketingTypeAyamPullet) && week != nil && *week > 0 {
|
||||||
|
totalWeight = qty * avgWeight
|
||||||
|
totalPrice = unitPrice * float64(*week) * qty
|
||||||
|
} else {
|
||||||
|
totalWeight = qty * avgWeight
|
||||||
|
totalPrice = totalWeight * unitPrice
|
||||||
|
}
|
||||||
|
return totalWeight, totalPrice
|
||||||
|
}
|
||||||
|
|
||||||
func (s deliveryOrdersService) consumeDeliveryStock(ctx context.Context, tx *gorm.DB, deliveryProduct *entity.MarketingDeliveryProduct, marketingProduct *entity.MarketingProduct, requestedQty float64, actorID uint) error {
|
func (s deliveryOrdersService) consumeDeliveryStock(ctx context.Context, tx *gorm.DB, deliveryProduct *entity.MarketingDeliveryProduct, marketingProduct *entity.MarketingProduct, requestedQty float64, actorID uint) error {
|
||||||
if marketingProduct == nil || marketingProduct.ProductWarehouseId == 0 {
|
if marketingProduct == nil || marketingProduct.ProductWarehouseId == 0 {
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "Product warehouse not found")
|
return fiber.NewError(fiber.StatusInternalServerError, "Product warehouse not found")
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ func (s *salesOrdersService) CreateOne(c *fiber.Ctx, req *validation.Create) (*e
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !utils.IsValidMarketingType(req.MarketingType) {
|
if !utils.IsValidMarketingType(req.MarketingType) {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid marketing_type. Must be one of: AYAM, TELUR, TRADING, AYAM PULLET")
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid marketing_type. Must be one of: AYAM, TELUR, TRADING, AYAM_PULLET")
|
||||||
}
|
}
|
||||||
|
|
||||||
actorID, err := m.ActorIDFromContext(c)
|
actorID, err := m.ActorIDFromContext(c)
|
||||||
@@ -119,6 +119,9 @@ func (s *salesOrdersService) CreateOne(c *fiber.Ctx, req *validation.Create) (*e
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range req.MarketingProducts {
|
for _, item := range req.MarketingProducts {
|
||||||
|
if req.MarketingType != string(utils.MarketingTypeTrading) && item.AvgWeight == 0 {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, "avg_weight is required for non-TRADING marketing type")
|
||||||
|
}
|
||||||
if item.ConvertionUnit != nil && !utils.IsValidConvertionUnit(*item.ConvertionUnit) {
|
if item.ConvertionUnit != nil && !utils.IsValidConvertionUnit(*item.ConvertionUnit) {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid convertion_unit. Must be one of: PETI, KG")
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid convertion_unit. Must be one of: PETI, KG")
|
||||||
}
|
}
|
||||||
@@ -215,7 +218,7 @@ func (s salesOrdersService) UpdateOne(c *fiber.Ctx, req *validation.Update, id u
|
|||||||
}
|
}
|
||||||
|
|
||||||
if req.MarketingType != "" && !utils.IsValidMarketingType(req.MarketingType) {
|
if req.MarketingType != "" && !utils.IsValidMarketingType(req.MarketingType) {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid marketing_type. Must be one of: AYAM, TELUR, TRADING, AYAM PULLET")
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid marketing_type. Must be one of: AYAM, TELUR, TRADING, AYAM_PULLET")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := m.EnsureMarketingAccess(c, s.MarketingRepo.DB(), id); err != nil {
|
if err := m.EnsureMarketingAccess(c, s.MarketingRepo.DB(), id); err != nil {
|
||||||
@@ -245,6 +248,9 @@ func (s salesOrdersService) UpdateOne(c *fiber.Ctx, req *validation.Update, id u
|
|||||||
|
|
||||||
if len(req.MarketingProducts) > 0 {
|
if len(req.MarketingProducts) > 0 {
|
||||||
for _, item := range req.MarketingProducts {
|
for _, item := range req.MarketingProducts {
|
||||||
|
if req.MarketingType != "" && req.MarketingType != string(utils.MarketingTypeTrading) && item.AvgWeight == 0 {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, "avg_weight is required for non-TRADING marketing type")
|
||||||
|
}
|
||||||
if item.ConvertionUnit != nil && !utils.IsValidConvertionUnit(*item.ConvertionUnit) {
|
if item.ConvertionUnit != nil && !utils.IsValidConvertionUnit(*item.ConvertionUnit) {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid convertion_unit. Must be one of: PETI, KG")
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid convertion_unit. Must be one of: PETI, KG")
|
||||||
}
|
}
|
||||||
@@ -331,13 +337,7 @@ func (s salesOrdersService) UpdateOne(c *fiber.Ctx, req *validation.Update, id u
|
|||||||
for _, rp := range req.MarketingProducts {
|
for _, rp := range req.MarketingProducts {
|
||||||
if old, ok := oldByPW[rp.ProductWarehouseId]; ok {
|
if old, ok := oldByPW[rp.ProductWarehouseId]; ok {
|
||||||
|
|
||||||
totalWeight := rp.Qty * rp.AvgWeight
|
totalWeight, totalPrice := s.calculatePriceByMarketingType(marketing.MarketingType, rp.Qty, rp.AvgWeight, rp.UnitPrice, rp.Week)
|
||||||
var totalPrice float64
|
|
||||||
if marketing.MarketingType == string(utils.MarketingTypeTrading) {
|
|
||||||
totalPrice = rp.Qty * rp.UnitPrice
|
|
||||||
} else {
|
|
||||||
totalPrice = totalWeight * rp.UnitPrice
|
|
||||||
}
|
|
||||||
|
|
||||||
deliveryProduct, err := invDeliveryRepoTx.GetByMarketingProductID(c.Context(), old.Id)
|
deliveryProduct, err := invDeliveryRepoTx.GetByMarketingProductID(c.Context(), old.Id)
|
||||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
@@ -688,13 +688,7 @@ func (s salesOrdersService) Approval(c *fiber.Ctx, req *validation.Approve) ([]e
|
|||||||
|
|
||||||
func (s *salesOrdersService) createMarketingProductWithDelivery(ctx context.Context, marketingId uint, marketingType string, rp validation.CreateMarketingProduct, marketingProductRepo repository.MarketingProductRepository, invDeliveryRepo repository.MarketingDeliveryProductRepository) error {
|
func (s *salesOrdersService) createMarketingProductWithDelivery(ctx context.Context, marketingId uint, marketingType string, rp validation.CreateMarketingProduct, marketingProductRepo repository.MarketingProductRepository, invDeliveryRepo repository.MarketingDeliveryProductRepository) error {
|
||||||
|
|
||||||
totalWeight := rp.Qty * rp.AvgWeight
|
totalWeight, totalPrice := s.calculatePriceByMarketingType(marketingType, rp.Qty, rp.AvgWeight, rp.UnitPrice, rp.Week)
|
||||||
var totalPrice float64
|
|
||||||
if marketingType == string(utils.MarketingTypeTrading) {
|
|
||||||
totalPrice = rp.Qty * rp.UnitPrice
|
|
||||||
} else {
|
|
||||||
totalPrice = totalWeight * rp.UnitPrice
|
|
||||||
}
|
|
||||||
|
|
||||||
marketingProduct := &entity.MarketingProduct{
|
marketingProduct := &entity.MarketingProduct{
|
||||||
MarketingId: marketingId,
|
MarketingId: marketingId,
|
||||||
@@ -730,3 +724,17 @@ func (s *salesOrdersService) createMarketingProductWithDelivery(ctx context.Cont
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *salesOrdersService) calculatePriceByMarketingType(marketingType string, qty, avgWeight, unitPrice float64, week *int) (totalWeight, totalPrice float64) {
|
||||||
|
if marketingType == string(utils.MarketingTypeTrading) {
|
||||||
|
totalWeight = 0
|
||||||
|
totalPrice = qty * unitPrice
|
||||||
|
} else if marketingType == string(utils.MarketingTypeAyamPullet) && week != nil && *week > 0 {
|
||||||
|
totalWeight = qty * avgWeight
|
||||||
|
totalPrice = unitPrice * float64(*week) * qty
|
||||||
|
} else {
|
||||||
|
totalWeight = qty * avgWeight
|
||||||
|
totalPrice = totalWeight * unitPrice
|
||||||
|
}
|
||||||
|
return totalWeight, totalPrice
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type CreateMarketingProduct struct {
|
|||||||
ProductWarehouseId uint `json:"product_warehouse_id" validate:"required,gt=0"`
|
ProductWarehouseId uint `json:"product_warehouse_id" validate:"required,gt=0"`
|
||||||
UnitPrice float64 `json:"unit_price" validate:"required,gt=0"`
|
UnitPrice float64 `json:"unit_price" validate:"required,gt=0"`
|
||||||
Qty float64 `json:"qty" validate:"required,gt=0"`
|
Qty float64 `json:"qty" validate:"required,gt=0"`
|
||||||
AvgWeight float64 `json:"avg_weight" validate:"required,gt=0"`
|
AvgWeight float64 `json:"avg_weight" validate:"omitempty,gt=0"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Update struct {
|
type Update struct {
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ const (
|
|||||||
MarketingTypeAyam MarketingType = "AYAM"
|
MarketingTypeAyam MarketingType = "AYAM"
|
||||||
MarketingTypeTelur MarketingType = "TELUR"
|
MarketingTypeTelur MarketingType = "TELUR"
|
||||||
MarketingTypeTrading MarketingType = "TRADING"
|
MarketingTypeTrading MarketingType = "TRADING"
|
||||||
MarketingTypeAyamPullet MarketingType = "AYAM PULLET"
|
MarketingTypeAyamPullet MarketingType = "AYAM_PULLET"
|
||||||
)
|
)
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user