FEAT[BE] :add type filtering and validation to product warehouse services

This commit is contained in:
aguhh18
2026-02-04 09:59:15 +07:00
parent f59cdd821a
commit 90de167fcd
8 changed files with 70 additions and 36 deletions
@@ -289,13 +289,7 @@ func (s *deliveryOrdersService) CreateOne(c *fiber.Ctx, req *validation.Delivery
itemDeliveryDate = &parsedDate
}
totalWeight := requestedProduct.Qty * requestedProduct.AvgWeight
var totalPrice float64
if marketing.MarketingType == string(utils.MarketingTypeTrading) {
totalPrice = requestedProduct.Qty * requestedProduct.UnitPrice
} else {
totalPrice = totalWeight * requestedProduct.UnitPrice
}
totalWeight, totalPrice := s.calculatePriceByMarketingType(marketing.MarketingType, requestedProduct.Qty, requestedProduct.AvgWeight, requestedProduct.UnitPrice, foundMarketingProduct.Week)
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
@@ -421,13 +415,7 @@ func (s deliveryOrdersService) UpdateOne(c *fiber.Ctx, req *validation.DeliveryO
itemDeliveryDate = deliveryProduct.DeliveryDate
}
totalWeight := requestedProduct.Qty * requestedProduct.AvgWeight
var totalPrice float64
if marketing.MarketingType == string(utils.MarketingTypeTrading) {
totalPrice = requestedProduct.Qty * requestedProduct.UnitPrice
} else {
totalPrice = totalWeight * requestedProduct.UnitPrice
}
totalWeight, totalPrice := s.calculatePriceByMarketingType(marketing.MarketingType, requestedProduct.Qty, requestedProduct.AvgWeight, requestedProduct.UnitPrice, foundMarketingProduct.Week)
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
@@ -471,6 +459,20 @@ func (s deliveryOrdersService) UpdateOne(c *fiber.Ctx, req *validation.DeliveryO
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 {
if marketingProduct == nil || marketingProduct.ProductWarehouseId == 0 {
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) {
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)
@@ -119,6 +119,9 @@ func (s *salesOrdersService) CreateOne(c *fiber.Ctx, req *validation.Create) (*e
}
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) {
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) {
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 {
@@ -245,6 +248,9 @@ func (s salesOrdersService) UpdateOne(c *fiber.Ctx, req *validation.Update, id u
if len(req.MarketingProducts) > 0 {
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) {
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 {
if old, ok := oldByPW[rp.ProductWarehouseId]; ok {
totalWeight := rp.Qty * rp.AvgWeight
var totalPrice float64
if marketing.MarketingType == string(utils.MarketingTypeTrading) {
totalPrice = rp.Qty * rp.UnitPrice
} else {
totalPrice = totalWeight * rp.UnitPrice
}
totalWeight, totalPrice := s.calculatePriceByMarketingType(marketing.MarketingType, rp.Qty, rp.AvgWeight, rp.UnitPrice, rp.Week)
deliveryProduct, err := invDeliveryRepoTx.GetByMarketingProductID(c.Context(), old.Id)
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 {
totalWeight := rp.Qty * rp.AvgWeight
var totalPrice float64
if marketingType == string(utils.MarketingTypeTrading) {
totalPrice = rp.Qty * rp.UnitPrice
} else {
totalPrice = totalWeight * rp.UnitPrice
}
totalWeight, totalPrice := s.calculatePriceByMarketingType(marketingType, rp.Qty, rp.AvgWeight, rp.UnitPrice, rp.Week)
marketingProduct := &entity.MarketingProduct{
MarketingId: marketingId,
@@ -730,3 +724,17 @@ func (s *salesOrdersService) createMarketingProductWithDelivery(ctx context.Cont
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
}