mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-24 07:15:43 +00:00
feat/BE/US-76/US-78/US-79/TASK-112,120,133,121-Recording growing/TASK-187,189,202,190-Recording Laying/TASK-191,192,194,197,203-Grading Telur
This commit is contained in:
+184
-12
@@ -3,19 +3,30 @@ package repository
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/validations"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
const baseNameExpression = "LOWER(TRIM(regexp_replace(flock_name, '\\\\s+\\\\d+(\\\\s+\\\\d+)*$', '', 'g')))"
|
||||
|
||||
type ProjectflockRepository interface {
|
||||
repository.BaseRepository[entity.ProjectFlock]
|
||||
GetAllByFlock(ctx context.Context, flockID uint) ([]entity.ProjectFlock, error)
|
||||
GetActiveByFlock(ctx context.Context, flockID uint) (*entity.ProjectFlock, error)
|
||||
GetMaxPeriodByFlock(ctx context.Context, flockID uint) (int, error)
|
||||
GetNextPeriodForFlock(ctx context.Context, flockID uint) (int, error)
|
||||
GetAllByBaseName(ctx context.Context, baseName string) ([]entity.ProjectFlock, error)
|
||||
GetActiveByBaseName(ctx context.Context, baseName string) (*entity.ProjectFlock, error)
|
||||
GetMaxPeriodByBaseName(ctx context.Context, baseName string) (int, error)
|
||||
GetNextSequenceForBase(ctx context.Context, baseName string) (int, error)
|
||||
GetAllWithFilters(ctx context.Context, offset, limit int, params *validation.Query) ([]entity.ProjectFlock, int64, error)
|
||||
WithDefaultRelations() func(*gorm.DB) *gorm.DB
|
||||
ExistsByFlockName(ctx context.Context, flockName string, excludeID *uint) (bool, error)
|
||||
AreaExists(ctx context.Context, id uint) (bool, error)
|
||||
FcrExists(ctx context.Context, id uint) (bool, error)
|
||||
LocationExists(ctx context.Context, id uint) (bool, error)
|
||||
}
|
||||
|
||||
type ProjectflockRepositoryImpl struct {
|
||||
@@ -28,11 +39,11 @@ func NewProjectflockRepository(db *gorm.DB) ProjectflockRepository {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) GetAllByFlock(ctx context.Context, flockID uint) ([]entity.ProjectFlock, error) {
|
||||
func (r *ProjectflockRepositoryImpl) GetAllByBaseName(ctx context.Context, baseName string) ([]entity.ProjectFlock, error) {
|
||||
var records []entity.ProjectFlock
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Unscoped().
|
||||
Where("flock_id = ?", flockID).
|
||||
Where(baseNameExpression+" = LOWER(?)", baseName).
|
||||
Order("period ASC").
|
||||
Find(&records).Error; err != nil {
|
||||
return nil, err
|
||||
@@ -40,10 +51,10 @@ func (r *ProjectflockRepositoryImpl) GetAllByFlock(ctx context.Context, flockID
|
||||
return records, nil
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) GetActiveByFlock(ctx context.Context, flockID uint) (*entity.ProjectFlock, error) {
|
||||
func (r *ProjectflockRepositoryImpl) GetActiveByBaseName(ctx context.Context, baseName string) (*entity.ProjectFlock, error) {
|
||||
var record entity.ProjectFlock
|
||||
err := r.DB().WithContext(ctx).
|
||||
Where("flock_id = ?", flockID).
|
||||
Where(baseNameExpression+" = LOWER(?)", baseName).
|
||||
Order("period DESC").
|
||||
First(&record).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -55,11 +66,11 @@ func (r *ProjectflockRepositoryImpl) GetActiveByFlock(ctx context.Context, flock
|
||||
return &record, nil
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) GetMaxPeriodByFlock(ctx context.Context, flockID uint) (int, error) {
|
||||
func (r *ProjectflockRepositoryImpl) GetMaxPeriodByBaseName(ctx context.Context, baseName string) (int, error) {
|
||||
var max int
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Model(&entity.ProjectFlock{}).
|
||||
Where("flock_id = ?", flockID).
|
||||
Where(baseNameExpression+" = LOWER(?)", baseName).
|
||||
Select("COALESCE(MAX(period), 0)").
|
||||
Scan(&max).Error; err != nil {
|
||||
return 0, err
|
||||
@@ -67,13 +78,13 @@ func (r *ProjectflockRepositoryImpl) GetMaxPeriodByFlock(ctx context.Context, fl
|
||||
return max, nil
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) GetNextPeriodForFlock(ctx context.Context, flockID uint) (int, error) {
|
||||
func (r *ProjectflockRepositoryImpl) GetNextSequenceForBase(ctx context.Context, baseName string) (int, error) {
|
||||
var payload struct {
|
||||
Period int
|
||||
}
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Model(&entity.ProjectFlock{}).
|
||||
Where("flock_id = ?", flockID).
|
||||
Where(baseNameExpression+" = LOWER(?)", baseName).
|
||||
Clauses(clause.Locking{Strength: "UPDATE"}).
|
||||
Order("period DESC").
|
||||
Limit(1).
|
||||
@@ -86,3 +97,164 @@ func (r *ProjectflockRepositoryImpl) GetNextPeriodForFlock(ctx context.Context,
|
||||
}
|
||||
return payload.Period + 1, nil
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) GetAllWithFilters(ctx context.Context, offset, limit int, params *validation.Query) ([]entity.ProjectFlock, int64, error) {
|
||||
return r.GetAll(ctx, offset, limit, func(db *gorm.DB) *gorm.DB {
|
||||
db = r.withDefaultRelations(db)
|
||||
return r.applyQueryFilters(db, params)
|
||||
})
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) WithDefaultRelations() func(*gorm.DB) *gorm.DB {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return r.withDefaultRelations(db)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) withDefaultRelations(db *gorm.DB) *gorm.DB {
|
||||
return db.
|
||||
Preload("CreatedUser").
|
||||
Preload("Area").
|
||||
Preload("Fcr").
|
||||
Preload("Location").
|
||||
Preload("Kandangs")
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) applyQueryFilters(db *gorm.DB, params *validation.Query) *gorm.DB {
|
||||
if params == nil {
|
||||
return db
|
||||
}
|
||||
|
||||
if params.AreaId > 0 {
|
||||
db = db.Where("project_flocks.area_id = ?", params.AreaId)
|
||||
}
|
||||
if params.LocationId > 0 {
|
||||
db = db.Where("project_flocks.location_id = ?", params.LocationId)
|
||||
}
|
||||
if params.Period > 0 {
|
||||
db = db.Where("project_flocks.period = ?", params.Period)
|
||||
}
|
||||
if len(params.KandangIds) > 0 {
|
||||
db = db.Where(`
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM project_flock_kandangs pfk
|
||||
WHERE pfk.project_flock_id = project_flocks.id
|
||||
AND pfk.kandang_id IN ?
|
||||
)`, params.KandangIds)
|
||||
}
|
||||
|
||||
db = r.applySearchFilters(db, params.Search)
|
||||
|
||||
for _, expr := range r.buildOrderExpressions(params.SortBy, params.SortOrder) {
|
||||
db = db.Order(expr)
|
||||
}
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) applySearchFilters(db *gorm.DB, rawSearch string) *gorm.DB {
|
||||
if rawSearch == "" {
|
||||
return db
|
||||
}
|
||||
|
||||
normalized := strings.ToLower(strings.TrimSpace(rawSearch))
|
||||
if normalized == "" {
|
||||
return db
|
||||
}
|
||||
|
||||
likeQuery := "%" + normalized + "%"
|
||||
return db.
|
||||
Joins("LEFT JOIN areas ON areas.id = project_flocks.area_id").
|
||||
Joins("LEFT JOIN fcrs ON fcrs.id = project_flocks.fcr_id").
|
||||
Joins("LEFT JOIN locations ON locations.id = project_flocks.location_id").
|
||||
Joins("LEFT JOIN users AS created_users ON created_users.id = project_flocks.created_by").
|
||||
Where(`
|
||||
LOWER(areas.name) LIKE ?
|
||||
OR LOWER(project_flocks.category) LIKE ?
|
||||
OR LOWER(fcrs.name) LIKE ?
|
||||
OR LOWER(locations.name) LIKE ?
|
||||
OR LOWER(locations.address) LIKE ?
|
||||
OR LOWER(created_users.name) LIKE ?
|
||||
OR LOWER(created_users.email) LIKE ?
|
||||
OR LOWER(project_flocks.flock_name) LIKE ?
|
||||
OR LOWER(TRIM(regexp_replace(project_flocks.flock_name, '\\s+\\d+(\\s+\\d+)*$', '', 'g'))) LIKE ?
|
||||
OR LOWER(CAST(project_flocks.period AS TEXT)) LIKE ?
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM kandangs
|
||||
WHERE kandangs.project_flock_id = project_flocks.id
|
||||
AND LOWER(kandangs.name) LIKE ?
|
||||
)
|
||||
`,
|
||||
likeQuery,
|
||||
likeQuery,
|
||||
likeQuery,
|
||||
likeQuery,
|
||||
likeQuery,
|
||||
likeQuery,
|
||||
likeQuery,
|
||||
likeQuery,
|
||||
likeQuery,
|
||||
likeQuery,
|
||||
likeQuery,
|
||||
)
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) AreaExists(ctx context.Context, id uint) (bool, error) {
|
||||
return repository.Exists[entity.Area](ctx, r.DB(), id)
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) FcrExists(ctx context.Context, id uint) (bool, error) {
|
||||
return repository.Exists[entity.Fcr](ctx, r.DB(), id)
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) LocationExists(ctx context.Context, id uint) (bool, error) {
|
||||
return repository.Exists[entity.Location](ctx, r.DB(), id)
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) buildOrderExpressions(sortBy, sortOrder string) []string {
|
||||
direction := "ASC"
|
||||
if strings.ToLower(sortOrder) == "desc" {
|
||||
direction = "DESC"
|
||||
}
|
||||
|
||||
switch sortBy {
|
||||
case "area":
|
||||
return []string{
|
||||
fmt.Sprintf("(SELECT name FROM areas WHERE areas.id = project_flocks.area_id) %s", direction),
|
||||
fmt.Sprintf("project_flocks.id %s", direction),
|
||||
}
|
||||
case "location":
|
||||
return []string{
|
||||
fmt.Sprintf("(SELECT name FROM locations WHERE locations.id = project_flocks.location_id) %s", direction),
|
||||
fmt.Sprintf("project_flocks.id %s", direction),
|
||||
}
|
||||
case "kandangs":
|
||||
return []string{
|
||||
fmt.Sprintf("(SELECT COUNT(*) FROM project_flock_kandangs pfk WHERE pfk.project_flock_id = project_flocks.id) %s", direction),
|
||||
fmt.Sprintf("project_flocks.id %s", direction),
|
||||
}
|
||||
case "period":
|
||||
return []string{
|
||||
fmt.Sprintf("project_flocks.period %s", direction),
|
||||
fmt.Sprintf("project_flocks.id %s", direction),
|
||||
}
|
||||
default:
|
||||
return []string{
|
||||
"project_flocks.created_at DESC",
|
||||
"project_flocks.updated_at DESC",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) ExistsByFlockName(ctx context.Context, flockName string, excludeID *uint) (bool, error) {
|
||||
var count int64
|
||||
q := r.DB().WithContext(ctx).Model(&entity.ProjectFlock{}).Where("flock_name = ?", flockName)
|
||||
if excludeID != nil && *excludeID != 0 {
|
||||
q = q.Where("id <> ?", *excludeID)
|
||||
}
|
||||
if err := q.Count(&count).Error; err != nil {
|
||||
return false, err
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
+48
-3
@@ -13,6 +13,9 @@ type ProjectFlockKandangRepository interface {
|
||||
CreateMany(ctx context.Context, records []*entity.ProjectFlockKandang) error
|
||||
DeleteMany(ctx context.Context, projectFlockID uint, kandangIDs []uint) error
|
||||
GetAll(ctx context.Context) ([]entity.ProjectFlockKandang, error)
|
||||
ListExistingKandangIDs(ctx context.Context, projectFlockID uint, kandangIDs []uint) ([]uint, error)
|
||||
HasKandangsLinkedToOtherProject(ctx context.Context, kandangIDs []uint, exceptProjectID *uint) (bool, error)
|
||||
FindKandangsWithRecordings(ctx context.Context, projectFlockID uint, kandangIDs []uint) ([]entity.Kandang, error)
|
||||
WithTx(tx *gorm.DB) ProjectFlockKandangRepository
|
||||
DB() *gorm.DB
|
||||
}
|
||||
@@ -45,7 +48,6 @@ func (r *projectFlockKandangRepositoryImpl) GetAll(ctx context.Context) ([]entit
|
||||
var records []entity.ProjectFlockKandang
|
||||
if err := r.db.WithContext(ctx).
|
||||
Preload("ProjectFlock").
|
||||
Preload("ProjectFlock.Flock").
|
||||
Preload("ProjectFlock.Fcr").
|
||||
Preload("ProjectFlock.Area").
|
||||
Preload("ProjectFlock.Location").
|
||||
@@ -72,7 +74,6 @@ func (r *projectFlockKandangRepositoryImpl) GetByID(ctx context.Context, id uint
|
||||
record := new(entity.ProjectFlockKandang)
|
||||
if err := r.db.WithContext(ctx).
|
||||
Preload("ProjectFlock").
|
||||
Preload("ProjectFlock.Flock").
|
||||
Preload("ProjectFlock.Fcr").
|
||||
Preload("ProjectFlock.Area").
|
||||
Preload("ProjectFlock.Location").
|
||||
@@ -91,7 +92,6 @@ func (r *projectFlockKandangRepositoryImpl) GetByProjectFlockAndKandang(ctx cont
|
||||
if err := r.db.WithContext(ctx).
|
||||
Where("project_flock_id = ? AND kandang_id = ?", projectFlockID, kandangID).
|
||||
Preload("ProjectFlock").
|
||||
Preload("ProjectFlock.Flock").
|
||||
Preload("ProjectFlock.Fcr").
|
||||
Preload("ProjectFlock.Area").
|
||||
Preload("ProjectFlock.Location").
|
||||
@@ -104,3 +104,48 @@ func (r *projectFlockKandangRepositoryImpl) GetByProjectFlockAndKandang(ctx cont
|
||||
}
|
||||
return record, nil
|
||||
}
|
||||
|
||||
func (r *projectFlockKandangRepositoryImpl) ListExistingKandangIDs(ctx context.Context, projectFlockID uint, kandangIDs []uint) ([]uint, error) {
|
||||
if len(kandangIDs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
var existing []uint
|
||||
err := r.db.WithContext(ctx).
|
||||
Table("project_flock_kandangs").
|
||||
Where("project_flock_id = ? AND kandang_id IN ?", projectFlockID, kandangIDs).
|
||||
Pluck("kandang_id", &existing).Error
|
||||
return existing, err
|
||||
}
|
||||
|
||||
func (r *projectFlockKandangRepositoryImpl) HasKandangsLinkedToOtherProject(ctx context.Context, kandangIDs []uint, exceptProjectID *uint) (bool, error) {
|
||||
if len(kandangIDs) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
q := r.db.WithContext(ctx).
|
||||
Table("project_flock_kandangs").
|
||||
Where("kandang_id IN ?", kandangIDs)
|
||||
if exceptProjectID != nil {
|
||||
q = q.Where("project_flock_id <> ?", *exceptProjectID)
|
||||
}
|
||||
var count int64
|
||||
if err := q.Count(&count).Error; err != nil {
|
||||
return false, err
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
func (r *projectFlockKandangRepositoryImpl) FindKandangsWithRecordings(ctx context.Context, projectFlockID uint, kandangIDs []uint) ([]entity.Kandang, error) {
|
||||
if len(kandangIDs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
var kandangs []entity.Kandang
|
||||
err := r.db.WithContext(ctx).
|
||||
Table("recordings AS r").
|
||||
Select("pfk.kandang_id AS id, COALESCE(k.name, '') AS name").
|
||||
Joins("JOIN project_flock_kandangs AS pfk ON pfk.id = r.project_flock_kandangs_id").
|
||||
Joins("LEFT JOIN kandangs AS k ON k.id = pfk.kandang_id").
|
||||
Where("pfk.project_flock_id = ? AND pfk.kandang_id IN ?", projectFlockID, kandangIDs).
|
||||
Group("pfk.kandang_id, k.name").
|
||||
Scan(&kandangs).Error
|
||||
return kandangs, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user