From aab1c3a2d52b05c37c16b8e0b4b756ff40cd5eda Mon Sep 17 00:00:00 2001 From: giovanni Date: Mon, 11 May 2026 13:45:23 +0700 Subject: [PATCH] add api for update data daily checklist by id --- .../controllers/daily-checklist.controller.go | 27 +++++++++ internal/modules/daily-checklists/route.go | 1 + .../services/daily-checklist.service.go | 59 +++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/internal/modules/daily-checklists/controllers/daily-checklist.controller.go b/internal/modules/daily-checklists/controllers/daily-checklist.controller.go index c2f258fd..ec02fc1f 100644 --- a/internal/modules/daily-checklists/controllers/daily-checklist.controller.go +++ b/internal/modules/daily-checklists/controllers/daily-checklist.controller.go @@ -412,6 +412,33 @@ func (u *DailyChecklistController) UpdateOne(c *fiber.Ctx) error { }) } +func (u *DailyChecklistController) UpdateByPut(c *fiber.Ctx) error { + req := new(validation.Create) + param := c.Params("idDailyChecklist") + + id, err := strconv.Atoi(param) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, "Invalid Id") + } + + if err := c.BodyParser(req); err != nil { + return fiber.NewError(fiber.StatusBadRequest, "Invalid request body") + } + + result, err := u.DailyChecklistService.UpdateByPut(c, req, uint(id)) + if err != nil { + return err + } + + return c.Status(fiber.StatusOK). + JSON(response.Success{ + Code: fiber.StatusOK, + Status: "success", + Message: "Update dailyChecklist successfully", + Data: dto.ToDailyChecklistListDTO(*result), + }) +} + func validateDailyChecklistDocumentSizes(files []*multipart.FileHeader) error { const maxDailyChecklistDocumentBytes = 5 * 1024 * 1024 // 5MB for _, file := range files { diff --git a/internal/modules/daily-checklists/route.go b/internal/modules/daily-checklists/route.go index e8965697..7f983a04 100644 --- a/internal/modules/daily-checklists/route.go +++ b/internal/modules/daily-checklists/route.go @@ -59,6 +59,7 @@ func DailyChecklistRoutes(v1 fiber.Router, u user.UserService, s dailyChecklist. route.Post("/assignment", m.RequirePermissions(m.P_DailyChecklistCreateOne), ctrl.UpdateAssignment) route.Patch("/bulk-update", m.RequirePermissions(m.P_DailyChecklistCreateOne), ctrl.BulkUpdate) + route.Put("/:idDailyChecklist", m.RequirePermissions(m.P_DailyChecklistCreateOne), ctrl.UpdateByPut) route.Patch("/:idDailyChecklist", m.RequirePermissions(m.P_DailyChecklistCreateOne), ctrl.UpdateOne) route.Delete("/:idDailyChecklist", m.RequirePermissions(m.P_DailyChecklistCreateOne), ctrl.DeleteOne) } diff --git a/internal/modules/daily-checklists/services/daily-checklist.service.go b/internal/modules/daily-checklists/services/daily-checklist.service.go index 6d367c7a..815aec47 100644 --- a/internal/modules/daily-checklists/services/daily-checklist.service.go +++ b/internal/modules/daily-checklists/services/daily-checklist.service.go @@ -29,6 +29,7 @@ type DailyChecklistService interface { GetOne(ctx *fiber.Ctx, id uint) (*entity.DailyChecklist, error) CreateOne(ctx *fiber.Ctx, req *validation.Create) (*entity.DailyChecklist, error) UpdateOne(ctx *fiber.Ctx, req *validation.Update, id uint) (*entity.DailyChecklist, error) + UpdateByPut(ctx *fiber.Ctx, req *validation.Create, id uint) (*entity.DailyChecklist, error) BulkUpdate(ctx *fiber.Ctx, req *validation.BulkStatusUpdate) ([]entity.DailyChecklist, error) DeleteOne(ctx *fiber.Ctx, id uint) error AssignPhases(ctx *fiber.Ctx, id uint, req *validation.AssignPhases) error @@ -878,6 +879,64 @@ func (s dailyChecklistService) BulkUpdate(c *fiber.Ctx, req *validation.BulkStat return updated, nil } +func (s *dailyChecklistService) UpdateByPut(c *fiber.Ctx, req *validation.Create, id uint) (*entity.DailyChecklist, error) { + if err := s.Validate.Struct(req); err != nil { + return nil, err + } + + if err := s.ensureChecklistAccess(c, id); err != nil { + return nil, err + } + + date, err := time.Parse(dailyChecklistDateLayout, strings.TrimSpace(req.Date)) + if err != nil { + return nil, fiber.NewError(fiber.StatusBadRequest, "invalid date format, use YYYY-MM-DD") + } + + category := req.Category + if req.EmptyKandang { + category = dailyChecklistCategoryEmptyKandang + } + + status := req.Status + + err = s.Repository.DB().WithContext(c.Context()).Transaction(func(tx *gorm.DB) error { + if err := s.lockKandangForChecklistCreation(tx, req.KandangId); err != nil { + return err + } + + var conflictCount int64 + if err := tx.Model(&entity.DailyChecklist{}). + Where("id <> ? AND date = ? AND kandang_id = ? AND category = ? AND deleted_at IS NULL", + id, date, req.KandangId, category). + Count(&conflictCount).Error; err != nil { + return err + } + if conflictCount > 0 { + return fiber.NewError(fiber.StatusConflict, "DailyChecklist already exists with same date, kandang, and category") + } + + result := tx.Model(&entity.DailyChecklist{}).Where("id = ?", id).Updates(map[string]any{ + "date": date, + "kandang_id": req.KandangId, + "category": category, + "status": status, + }) + if result.Error != nil { + return result.Error + } + if result.RowsAffected == 0 { + return gorm.ErrRecordNotFound + } + return nil + }) + if err != nil { + return nil, err + } + + return s.GetOne(c, id) +} + func (s dailyChecklistService) DeleteOne(c *fiber.Ctx, id uint) error { if err := s.ensureChecklistAccess(c, id); err != nil { return err