initial refactori trasnfer to laying, and depretitation to 25 week

This commit is contained in:
giovanni
2026-05-27 15:00:13 +07:00
parent 2da476b276
commit fecbcab48d
20 changed files with 1018 additions and 223 deletions
@@ -1617,6 +1617,13 @@ func (s *transferLayingService) validateKandangOwnership(
return nil
}
// validateTargetSourceLineage memvalidasi bahwa source kandang yang sama TIDAK boleh ditransfer 2x ke
// target kandang yang sama (anti-duplicate pair). Aturan lama "satu target hanya boleh punya satu
// source" sudah dihapus — sekarang 1 target boleh menerima dari multiple source kandang via transfer
// terpisah (multi-source via N-call approach).
//
// Yang ditolak: kalau ada approved transfer lain (id != excludeTransferID) yang punya pair
// (source = sourceProjectFlockKandangID, target ∈ targetKandangIDs) yang sama.
func (s *transferLayingService) validateTargetSourceLineage(
ctx context.Context,
sourceProjectFlockKandangID uint,
@@ -1637,7 +1644,7 @@ func (s *transferLayingService) validateTargetSourceLineage(
}
seen[targetKandangID] = struct{}{}
existingTransfer, err := s.Repository.GetLatestApprovedByTargetKandang(ctx, targetKandangID)
existingTransfers, err := s.Repository.GetAllApprovedByTargetKandang(ctx, targetKandangID)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
continue
@@ -1645,47 +1652,49 @@ func (s *transferLayingService) validateTargetSourceLineage(
s.Log.Errorf("Failed to validate transfer lineage for target kandang %d: %+v", targetKandangID, err)
return fiber.NewError(fiber.StatusInternalServerError, "Gagal memvalidasi relasi sumber transfer ke laying")
}
if existingTransfer == nil {
continue
}
if excludeTransferID != 0 && existingTransfer.Id == excludeTransferID {
continue
}
existingSourceID := uint(0)
if existingTransfer.SourceProjectFlockKandangId != nil && *existingTransfer.SourceProjectFlockKandangId != 0 {
existingSourceID = *existingTransfer.SourceProjectFlockKandangId
}
if existingSourceID == 0 && s.LayingTransferSourceRepo != nil {
sources, sourceErr := s.LayingTransferSourceRepo.GetByLayingTransferId(ctx, existingTransfer.Id)
if sourceErr != nil {
s.Log.Errorf("Failed to resolve transfer sources for lineage validation transfer=%d: %+v", existingTransfer.Id, sourceErr)
return fiber.NewError(fiber.StatusInternalServerError, "Gagal memvalidasi relasi sumber transfer ke laying")
for i := range existingTransfers {
existingTransfer := &existingTransfers[i]
if excludeTransferID != 0 && existingTransfer.Id == excludeTransferID {
continue
}
for _, source := range sources {
if source.SourceProjectFlockKandangId != 0 {
existingSourceID = source.SourceProjectFlockKandangId
break
// Source di header (single source of truth per migration 20260307130342).
existingSourceID := uint(0)
if existingTransfer.SourceProjectFlockKandangId != nil && *existingTransfer.SourceProjectFlockKandangId != 0 {
existingSourceID = *existingTransfer.SourceProjectFlockKandangId
}
// Fallback ke laying_transfer_sources untuk transfer yang belum punya source di header
// (historis pre-migration 20260307130342).
if existingSourceID == 0 && s.LayingTransferSourceRepo != nil {
sources, sourceErr := s.LayingTransferSourceRepo.GetByLayingTransferId(ctx, existingTransfer.Id)
if sourceErr != nil {
s.Log.Errorf("Failed to resolve transfer sources for lineage validation transfer=%d: %+v", existingTransfer.Id, sourceErr)
return fiber.NewError(fiber.StatusInternalServerError, "Gagal memvalidasi relasi sumber transfer ke laying")
}
for _, source := range sources {
if source.SourceProjectFlockKandangId == sourceProjectFlockKandangID {
existingSourceID = source.SourceProjectFlockKandangId
break
}
}
}
}
if existingSourceID == 0 {
continue
}
if existingSourceID == sourceProjectFlockKandangID {
continue
}
return fiber.NewError(
fiber.StatusBadRequest,
fmt.Sprintf(
"Kandang tujuan %d sudah memiliki lineage sumber kandang %d dari transfer %s. Tidak boleh ganti ke sumber kandang %d.",
targetKandangID,
existingSourceID,
existingTransfer.TransferNumber,
sourceProjectFlockKandangID,
),
)
if existingSourceID != sourceProjectFlockKandangID {
continue
}
return fiber.NewError(
fiber.StatusBadRequest,
fmt.Sprintf(
"Source kandang %d sudah pernah ditransfer ke target kandang %d via transfer %s. Tidak boleh duplikat (source, target) pair yang sama.",
sourceProjectFlockKandangID,
targetKandangID,
existingTransfer.TransferNumber,
),
)
}
}
return nil