mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
FEAT[BE] :enhance UpdateOne method with validation for source and target kandang ownership and quantity checks
This commit is contained in:
@@ -444,15 +444,105 @@ func (s *transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update,
|
|||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Target project flock not found")
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Target project flock not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sourceKandangIDs := make([]uint, len(req.SourceKandangs))
|
||||||
|
for i, detail := range req.SourceKandangs {
|
||||||
|
sourceKandangIDs[i] = detail.ProjectFlockKandangId
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.validateKandangOwnership(
|
||||||
|
c.Context(),
|
||||||
|
req.SourceProjectFlockId,
|
||||||
|
sourceKandangIDs,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
targetKandangIDs := make([]uint, len(req.TargetKandangs))
|
||||||
|
for i, detail := range req.TargetKandangs {
|
||||||
|
targetKandangIDs[i] = detail.ProjectFlockKandangId
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.validateKandangOwnership(
|
||||||
|
c.Context(),
|
||||||
|
req.TargetProjectFlockId,
|
||||||
|
targetKandangIDs,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
transferDate, err := time.Parse("2006-01-02", req.TransferDate)
|
transferDate, err := time.Parse("2006-01-02", req.TransferDate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid transfer date format")
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid transfer date format")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var totalSourceQty, totalTargetQty float64
|
||||||
|
sourceWarehouseMap := make(map[uint]uint)
|
||||||
|
|
||||||
|
for _, sourceDetail := range req.SourceKandangs {
|
||||||
|
if sourceDetail.Quantity <= 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
totalSourceQty += sourceDetail.Quantity
|
||||||
|
|
||||||
|
populations, err := s.ProjectFlockPopulationRepo.GetByProjectFlockKandangID(c.Context(), sourceDetail.ProjectFlockKandangId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalPopulation float64
|
||||||
|
var productWarehouseId uint
|
||||||
|
for _, pop := range populations {
|
||||||
|
totalPopulation += pop.TotalQty
|
||||||
|
if productWarehouseId == 0 {
|
||||||
|
productWarehouseId = pop.ProductWarehouseId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if totalPopulation == 0 {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Kandang sumber %d tidak memiliki populasi untuk ditransfer", sourceDetail.ProjectFlockKandangId))
|
||||||
|
}
|
||||||
|
|
||||||
|
if totalPopulation < sourceDetail.Quantity {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Kandang sumber %d jumlah tidak mencukupi. Tersedia: %.0f, Diminta: %.0f", sourceDetail.ProjectFlockKandangId, totalPopulation, sourceDetail.Quantity))
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceWarehouseMap[sourceDetail.ProjectFlockKandangId] = productWarehouseId
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, targetDetail := range req.TargetKandangs {
|
||||||
|
if targetDetail.Quantity <= 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
totalTargetQty += targetDetail.Quantity
|
||||||
|
}
|
||||||
|
|
||||||
|
if totalSourceQty == 0 {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Minimal harus ada 1 kandang sumber dengan jumlah lebih dari 0")
|
||||||
|
}
|
||||||
|
if totalTargetQty == 0 {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Minimal harus ada 1 kandang tujuan dengan jumlah lebih dari 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
if totalSourceQty != totalTargetQty {
|
||||||
|
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Jumlah total sumber (%.0f) harus sama dengan jumlah total tujuan (%.0f)", totalSourceQty, totalTargetQty))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ambil productWarehouseId pertama dari source yang valid (quantity > 0)
|
||||||
|
var firstProductWarehouseId uint
|
||||||
|
for _, sourceDetail := range req.SourceKandangs {
|
||||||
|
if sourceDetail.Quantity > 0 {
|
||||||
|
if pwId, ok := sourceWarehouseMap[sourceDetail.ProjectFlockKandangId]; ok {
|
||||||
|
firstProductWarehouseId = pwId
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||||
repoTx := s.Repository.WithTx(dbTransaction)
|
repoTx := s.Repository.WithTx(dbTransaction)
|
||||||
sourceRepo := s.LayingTransferSourceRepo.WithTx(dbTransaction)
|
sourceRepo := s.LayingTransferSourceRepo.WithTx(dbTransaction)
|
||||||
targetRepo := s.LayingTransferTargetRepo.WithTx(dbTransaction)
|
targetRepo := s.LayingTransferTargetRepo.WithTx(dbTransaction)
|
||||||
|
pwRepo := rInventory.NewProductWarehouseRepository(dbTransaction)
|
||||||
|
|
||||||
// Hapus old sources dan targets
|
// Hapus old sources dan targets
|
||||||
for _, oldSource := range existingTransfer.Sources {
|
for _, oldSource := range existingTransfer.Sources {
|
||||||
@@ -476,26 +566,11 @@ func (s *transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update,
|
|||||||
|
|
||||||
// Create new sources dengan pending quantity
|
// Create new sources dengan pending quantity
|
||||||
for _, sourceDetail := range req.SourceKandangs {
|
for _, sourceDetail := range req.SourceKandangs {
|
||||||
populations, err := s.ProjectFlockPopulationRepo.GetByProjectFlockKandangID(c.Context(), sourceDetail.ProjectFlockKandangId)
|
if sourceDetail.Quantity == 0 {
|
||||||
if err != nil {
|
continue
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get populations")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(populations) == 0 {
|
productWarehouseId := sourceWarehouseMap[sourceDetail.ProjectFlockKandangId]
|
||||||
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Source kandang %d has no population available", sourceDetail.ProjectFlockKandangId))
|
|
||||||
}
|
|
||||||
|
|
||||||
var productWarehouseId uint
|
|
||||||
for _, pop := range populations {
|
|
||||||
if pop.ProductWarehouseId > 0 {
|
|
||||||
productWarehouseId = pop.ProductWarehouseId
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if productWarehouseId == 0 {
|
|
||||||
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Source kandang %d has no product warehouse", sourceDetail.ProjectFlockKandangId))
|
|
||||||
}
|
|
||||||
|
|
||||||
source := entity.LayingTransferSource{
|
source := entity.LayingTransferSource{
|
||||||
LayingTransferId: id,
|
LayingTransferId: id,
|
||||||
@@ -510,7 +585,18 @@ func (s *transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pwRepo := rInventory.NewProductWarehouseRepository(dbTransaction)
|
// Ambil product ID dari source warehouse pertama yang valid
|
||||||
|
var sourceProductID uint
|
||||||
|
if firstProductWarehouseId > 0 {
|
||||||
|
sourcePW, err := pwRepo.GetByID(c.Context(), firstProductWarehouseId, nil)
|
||||||
|
if err == nil {
|
||||||
|
sourceProductID = sourcePW.ProductId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if sourceProductID == 0 {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get product from source warehouse")
|
||||||
|
}
|
||||||
|
|
||||||
for _, targetDetail := range req.TargetKandangs {
|
for _, targetDetail := range req.TargetKandangs {
|
||||||
targetprojectFlockKandang, err := s.ProjectFlockKandangRepo.GetByID(c.Context(), targetDetail.ProjectFlockKandangId)
|
targetprojectFlockKandang, err := s.ProjectFlockKandangRepo.GetByID(c.Context(), targetDetail.ProjectFlockKandangId)
|
||||||
@@ -526,23 +612,6 @@ func (s *transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update,
|
|||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get target warehouse")
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get target warehouse")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ambil product ID dari source yang pertama (semua sources seharusnya product-nya sama)
|
|
||||||
var sourceProductID uint
|
|
||||||
if len(req.SourceKandangs) > 0 {
|
|
||||||
firstSourceKandangID := req.SourceKandangs[0].ProjectFlockKandangId
|
|
||||||
populations, err := s.ProjectFlockPopulationRepo.GetByProjectFlockKandangID(c.Context(), firstSourceKandangID)
|
|
||||||
if err == nil && len(populations) > 0 && populations[0].ProductWarehouseId > 0 {
|
|
||||||
sourcePW, err := pwRepo.GetByID(c.Context(), populations[0].ProductWarehouseId, nil)
|
|
||||||
if err == nil {
|
|
||||||
sourceProductID = sourcePW.ProductId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if sourceProductID == 0 {
|
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get product from source warehouse")
|
|
||||||
}
|
|
||||||
|
|
||||||
targetPW, err := pwRepo.FindByProductWarehouseAndPfk(c.Context(), sourceProductID, targetWarehouse.Id, &targetDetail.ProjectFlockKandangId)
|
targetPW, err := pwRepo.FindByProductWarehouseAndPfk(c.Context(), sourceProductID, targetWarehouse.Id, &targetDetail.ProjectFlockKandangId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
|||||||
Reference in New Issue
Block a user