package repository import ( "context" "errors" "gitlab.com/mbugroup/lti-api.git/internal/common/repository" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" "gitlab.com/mbugroup/lti-api.git/internal/utils" "gorm.io/gorm" ) type KandangRepository interface { repository.BaseRepository[entity.Kandang] LocationExists(ctx context.Context, areaId uint) (bool, error) PicExists(ctx context.Context, areaId uint) (bool, error) NameExists(ctx context.Context, name string, excludeID *uint) (bool, error) ProjectFlockExists(ctx context.Context, projectFlockID uint) (bool, error) GetFirstByProjectFlockID(ctx context.Context, projectFlockID uint) (*entity.Kandang, error) HasActiveKandangForProjectFlock(ctx context.Context, projectFlockID uint, excludeID *uint) (bool, error) UpdateStatusByProjectFlockID(ctx context.Context, projectFlockID uint, status utils.KandangStatus) error UpsertProjectFlockKandang(ctx context.Context, projectFlockID, kandangID uint) error UpdateStatusByIDs(ctx context.Context, kandangIDs []uint, status utils.KandangStatus) error } type KandangRepositoryImpl struct { *repository.BaseRepositoryImpl[entity.Kandang] db *gorm.DB } func NewKandangRepository(db *gorm.DB) KandangRepository { return &KandangRepositoryImpl{ BaseRepositoryImpl: repository.NewBaseRepository[entity.Kandang](db), db: db, } } func (r *KandangRepositoryImpl) LocationExists(ctx context.Context, locationId uint) (bool, error) { return repository.Exists[entity.Location](ctx, r.db, locationId) } func (r *KandangRepositoryImpl) PicExists(ctx context.Context, picId uint) (bool, error) { return repository.Exists[entity.User](ctx, r.db, picId) } func (r *KandangRepositoryImpl) NameExists(ctx context.Context, name string, excludeID *uint) (bool, error) { return repository.ExistsByName[entity.Kandang](ctx, r.db, name, excludeID) } func (r *KandangRepositoryImpl) ProjectFlockExists(ctx context.Context, projectFlockID uint) (bool, error) { var count int64 if err := r.db.WithContext(ctx). Model(&entity.ProjectFlock{}). Where("id = ?", projectFlockID). Where("deleted_at IS NULL"). Count(&count).Error; err != nil { return false, err } return count > 0, nil } func (r *KandangRepositoryImpl) HasActiveKandangForProjectFlock(ctx context.Context, projectFlockID uint, excludeID *uint) (bool, error) { var count int64 q := r.db.WithContext(ctx). Table("kandangs k"). Joins("JOIN project_flock_kandangs pfk ON pfk.kandang_id = k.id"). Where("pfk.project_flock_id = ?", projectFlockID). Where("k.status = ?", utils.KandangStatusActive). Where("k.deleted_at IS NULL") if excludeID != nil { q = q.Where("k.id <> ?", *excludeID) } if err := q.Count(&count).Error; err != nil { return false, err } return count > 0, nil } func (r *KandangRepositoryImpl) GetFirstByProjectFlockID(ctx context.Context, projectFlockID uint) (*entity.Kandang, error) { kandang := new(entity.Kandang) err := r.db.WithContext(ctx). Table("kandangs k"). Joins("JOIN project_flock_kandangs pfk ON pfk.kandang_id = k.id"). Where("pfk.project_flock_id = ?", projectFlockID). Where("k.deleted_at IS NULL"). Order("k.id ASC"). Limit(1). Find(kandang).Error if err != nil { return nil, err } if kandang.Id == 0 { return nil, gorm.ErrRecordNotFound } return kandang, nil } func (r *KandangRepositoryImpl) UpdateStatusByProjectFlockID(ctx context.Context, projectFlockID uint, status utils.KandangStatus) error { sub := r.db.WithContext(ctx). Table("project_flock_kandangs"). Select("kandang_id"). Where("project_flock_id = ?", projectFlockID) return r.db.WithContext(ctx). Model(&entity.Kandang{}). Where("id IN (?)", sub). Where("deleted_at IS NULL"). Update("status", string(status)).Error } func (r *KandangRepositoryImpl) UpsertProjectFlockKandang(ctx context.Context, projectFlockID, kandangID uint) error { var link entity.ProjectFlockKandang err := r.db.WithContext(ctx). Where("project_flock_id = ? AND kandang_id = ?", projectFlockID, kandangID). First(&link).Error if errors.Is(err, gorm.ErrRecordNotFound) { link = entity.ProjectFlockKandang{ ProjectFlockId: projectFlockID, KandangId: kandangID, } return r.db.WithContext(ctx).Create(&link).Error } return err } func (r *KandangRepositoryImpl) UpdateStatusByIDs(ctx context.Context, kandangIDs []uint, status utils.KandangStatus) error { if len(kandangIDs) == 0 { return nil } return r.db.WithContext(ctx). Model(&entity.Kandang{}). Where("id IN ?", kandangIDs). Where("deleted_at IS NULL"). Update("status", string(status)).Error }