feat: editable po_date

This commit is contained in:
Adnan Zahir
2026-04-25 22:47:52 +07:00
parent 732ebd423d
commit eefc9850e1
4 changed files with 64 additions and 0 deletions
@@ -283,6 +283,32 @@ func validatePurchaseDocumentSizes(files []*multipart.FileHeader) error {
return nil
}
func (ctrl *PurchaseController) UpdatePoDate(c *fiber.Ctx) error {
param := c.Params("id")
id, err := strconv.Atoi(param)
if err != nil || id == 0 {
return fiber.NewError(fiber.StatusBadRequest, "Invalid purchase id")
}
req := new(validation.UpdatePoDateRequest)
if err := c.BodyParser(req); err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
}
result, err := ctrl.service.UpdatePoDate(c, uint(id), req)
if err != nil {
return err
}
return c.Status(fiber.StatusOK).
JSON(response.Success{
Code: fiber.StatusOK,
Status: "success",
Message: "Purchase PO date updated successfully",
Data: dto.ToPurchaseDetailDTO(*result),
})
}
func (ctrl *PurchaseController) DeleteItems(c *fiber.Ctx) error {
param := c.Params("id")
id, err := strconv.Atoi(param)
+1
View File
@@ -21,6 +21,7 @@ func Routes(router fiber.Router, purchaseService service.PurchaseService, userSe
route.Post("/:id/approvals/staff", m.RequirePermissions(m.P_PurchaseApprovalStaff), ctrl.ApproveStaffPurchase)
route.Post("/:id/approvals/manager", m.RequirePermissions(m.P_PurchaseApprovalManager), ctrl.ApproveManagerPurchase)
route.Post("/:id/receipts", m.RequirePermissions(m.P_PurchaseReceive), ctrl.ReceiveProducts)
route.Patch("/:id/po-date", m.RequirePermissions(m.P_PurchaseUpdateOne), ctrl.UpdatePoDate)
route.Delete("/:id", m.RequirePermissions(m.P_PurchaseDeleteOne), ctrl.DeletePurchase)
route.Delete("/:id/items", m.RequirePermissions(m.P_PurchaseItemDeleteOne), ctrl.DeleteItems)
}
@@ -45,6 +45,7 @@ type PurchaseService interface {
DeleteItems(ctx *fiber.Ctx, id uint, req *validation.DeletePurchaseItemsRequest) (*entity.Purchase, error)
DeletePurchase(ctx *fiber.Ctx, id uint) error
GetProgressRows(ctx *fiber.Ctx, query *exportprogress.Query) ([]exportprogress.Row, error)
UpdatePoDate(ctx *fiber.Ctx, id uint, req *validation.UpdatePoDateRequest) (*entity.Purchase, error)
}
const (
@@ -798,6 +799,38 @@ func (s *purchaseService) ApproveManagerPurchase(c *fiber.Ctx, id uint, req *val
return updated, nil
}
func (s *purchaseService) UpdatePoDate(c *fiber.Ctx, id uint, req *validation.UpdatePoDateRequest) (*entity.Purchase, error) {
if err := s.Validate.Struct(req); err != nil {
return nil, err
}
parsed, err := utils.ParseDateString(strings.TrimSpace(req.PoDate))
if err != nil {
return nil, utils.BadRequest("po_date must use format YYYY-MM-DD")
}
poDate := parsed.UTC()
purchase, err := s.loadPurchase(c.Context(), id)
if err != nil {
return nil, err
}
if err := s.PurchaseRepo.PatchOne(c.Context(), id, map[string]any{"po_date": poDate}, nil); err != nil {
return nil, utils.Internal("Failed to update po_date")
}
purchase.PoDate = &poDate
updated, err := s.PurchaseRepo.GetByID(c.Context(), purchase.Id, s.withRelations)
if err != nil {
return nil, utils.Internal("Failed to reload purchase")
}
if err := s.attachLatestApproval(c.Context(), updated); err != nil {
s.Log.Warnf("Unable to attach latest approval for purchase %d: %+v", updated.Id, err)
}
return updated, nil
}
func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation.ReceivePurchaseRequest) (*entity.Purchase, error) {
if err := s.Validate.Struct(req); err != nil {
return nil, err
@@ -61,6 +61,10 @@ type DeletePurchaseItemsRequest struct {
ItemIDs []uint `json:"item_ids" validate:"required,min=1,dive,gt=0"`
}
type UpdatePoDateRequest struct {
PoDate string `json:"po_date" validate:"required,datetime=2006-01-02"`
}
type Query struct {
Page int `query:"page" validate:"omitempty,number,min=1"`
Limit int `query:"limit" validate:"omitempty,number,min=1,max=100"`