package service import ( "context" "errors" "fmt" productWarehouseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories" warehouseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories" projectFlockKandangRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" "github.com/gofiber/fiber/v2" "gorm.io/gorm" ) // Dipakai untuk semua module yang butuh cek: // "PW ini → warehouse → kandang → project_flock_kandang sudah closing atau belum" func EnsureProjectFlockNotClosedForProductWarehouses( ctx context.Context, db *gorm.DB, productWarehouseIDs []uint, ) error { if len(productWarehouseIDs) == 0 { return nil } pwRepo := productWarehouseRepo.NewProductWarehouseRepository(db) wRepo := warehouseRepo.NewWarehouseRepository(db) pfkRepo := projectFlockKandangRepo.NewProjectFlockKandangRepository(db) seenPW := make(map[uint]struct{}) seenKandang := make(map[uint]struct{}) for _, pwID := range productWarehouseIDs { if pwID == 0 { continue } if _, ok := seenPW[pwID]; ok { continue } seenPW[pwID] = struct{}{} pw, err := pwRepo.GetByID(ctx, pwID, nil) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Product warehouse %d tidak ditemukan", pwID)) } return fiber.NewError(fiber.StatusInternalServerError, "Failed to validate product warehouse") } wh, err := wRepo.GetByID(ctx, uint(pw.WarehouseId), nil) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Warehouse %d tidak ditemukan", pw.WarehouseId)) } return fiber.NewError(fiber.StatusInternalServerError, "Failed to validate warehouse") } // Warehouse tanpa kandang → bukan kandang produksi → skip if wh.KandangId == nil || *wh.KandangId == 0 { continue } kandangID := uint(*wh.KandangId) if _, ok := seenKandang[kandangID]; ok { continue } seenKandang[kandangID] = struct{}{} pfk, err := pfkRepo.GetActiveByKandangID(ctx, kandangID) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { // nggak ada project aktif untuk kandang ini → aman continue } return fiber.NewError(fiber.StatusInternalServerError, "Failed to validate project flock") } // INTI RULE: kalau aktif tapi sudah punya ClosedAt → anggap "project sudah closing" if pfk != nil && pfk.ClosedAt != nil { return fiber.NewError(fiber.StatusBadRequest, "Project sudah closing") } } return nil } func EnsureProjectFlockNotClosedByProjectFlockKandangID( ctx context.Context, db *gorm.DB, pfkIDs []uint, ) error { pfkRepo := projectFlockKandangRepo.NewProjectFlockKandangRepository(db) seen := make(map[uint]struct{}) for _, id := range pfkIDs { if id == 0 { continue } if _, ok := seen[id]; ok { continue } seen[id] = struct{}{} pfk, err := pfkRepo.GetByID(ctx, id) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Project flock kandang %d tidak ditemukan", id)) } return fiber.NewError(fiber.StatusInternalServerError, "Failed to validate project flock") } if pfk.ClosedAt != nil { return fiber.NewError(fiber.StatusBadRequest, "Project sudah closing") } } return nil }