fix upser daily checklist status rejected; fix search list daily checklist

This commit is contained in:
giovanni
2026-04-02 14:53:59 +07:00
parent 07b55e79a5
commit 480e430289
3 changed files with 78 additions and 14 deletions
@@ -0,0 +1,9 @@
BEGIN;
DROP INDEX IF EXISTS idx_daily_checklists_unique_non_rejected;
ALTER TABLE daily_checklists
ADD CONSTRAINT daily_checklists_date_kandang_category_key
UNIQUE (date, kandang_id, category);
COMMIT;
@@ -0,0 +1,10 @@
BEGIN;
ALTER TABLE daily_checklists
DROP CONSTRAINT IF EXISTS daily_checklists_date_kandang_category_key;
CREATE UNIQUE INDEX IF NOT EXISTS idx_daily_checklists_unique_non_rejected
ON daily_checklists (date, kandang_id, category)
WHERE (status IS NULL OR status <> 'REJECTED');
COMMIT;
@@ -261,8 +261,11 @@ func (s dailyChecklistService) GetAll(c *fiber.Ctx, params *validation.Query) ([
if params.Search != "" { if params.Search != "" {
re := regexp.MustCompile("[^a-zA-Z0-9]") re := regexp.MustCompile("[^a-zA-Z0-9]")
like := re.ReplaceAll([]byte("%"+params.Search+"%"), []byte("")) normalizedSearch := re.ReplaceAllString(params.Search, "")
db = db.Where("(regexp_replace(k.name, '[^a-zA-Z0-9]', '', 'g') ILIKE ? OR regexp_replace(dc.category::text, '[^a-zA-Z0-9]', '', 'g') ILIKE ?)", string(like), string(like)) if normalizedSearch != "" {
like := "%" + normalizedSearch + "%"
db = db.Where("(regexp_replace(k.name, '[^a-zA-Z0-9]', '', 'g') ILIKE ? OR regexp_replace(dc.category::text, '[^a-zA-Z0-9]', '', 'g') ILIKE ?)", like, like)
}
} }
countDB := db.Session(&gorm.Session{}) countDB := db.Session(&gorm.Session{})
@@ -504,24 +507,66 @@ func (s *dailyChecklistService) CreateOne(c *fiber.Ctx, req *validation.Create)
status := req.Status status := req.Status
category := req.Category category := req.Category
targetID := uint(0)
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(tx *gorm.DB) error {
existing := new(entity.DailyChecklist)
err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).
Where("date = ? AND kandang_id = ? AND category = ? AND (status IS NULL OR status <> ?)", date, req.KandangId, category, "REJECTED").
Take(existing).Error
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
if err == nil {
if err := tx.Model(&entity.DailyChecklist{}).
Where("id = ?", existing.Id).
Update("updated_at", time.Now()).Error; err != nil {
return err
}
targetID = existing.Id
return nil
}
createStatus := status
var rejectedCount int64
if err := tx.Model(&entity.DailyChecklist{}).
Where("date = ? AND kandang_id = ? AND category = ? AND status = ?", date, req.KandangId, category, "REJECTED").
Count(&rejectedCount).Error; err != nil {
return err
}
if rejectedCount > 0 {
createStatus = "DRAFT"
}
createBody := &entity.DailyChecklist{ createBody := &entity.DailyChecklist{
KandangId: req.KandangId, KandangId: req.KandangId,
Date: date, Date: date,
Category: category, Category: category,
Status: &status, Status: &createStatus,
} }
err = s.Repository.DB().WithContext(c.Context()).Clauses(clause.OnConflict{ if err := tx.Create(createBody).Error; err != nil {
Columns: []clause.Column{{Name: "date"}, {Name: "kandang_id"}, {Name: "category"}}, // Handle concurrent insert for active checklist with same key.
DoUpdates: clause.Assignments(map[string]any{"updated_at": time.Now()}), if findErr := tx.
}).Create(createBody).Error Where("date = ? AND kandang_id = ? AND category = ? AND (status IS NULL OR status <> ?)", date, req.KandangId, category, "REJECTED").
Take(existing).Error; findErr == nil {
targetID = existing.Id
return nil
}
return err
}
targetID = createBody.Id
return nil
})
if err != nil { if err != nil {
s.Log.Errorf("Failed to upsert dailyChecklist: %+v", err) s.Log.Errorf("Failed to create/upsert dailyChecklist: %+v", err)
return nil, err return nil, err
} }
return s.GetOne(c, createBody.Id) return s.GetOne(c, targetID)
} }
func (s dailyChecklistService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint) (*entity.DailyChecklist, error) { func (s dailyChecklistService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint) (*entity.DailyChecklist, error) {