feat: bulk approve endpoint for marketings and expenses

This commit is contained in:
Adnan Zahir
2026-04-21 20:06:37 +07:00
parent 1e34a0e7b2
commit 0d04397bd5
9 changed files with 607 additions and 11 deletions
@@ -7,10 +7,13 @@ import (
"strconv"
"strings"
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
"gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/dto"
service "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/services"
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/validations"
"gitlab.com/mbugroup/lti-api.git/internal/response"
"gitlab.com/mbugroup/lti-api.git/internal/utils"
approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals"
"github.com/gofiber/fiber/v2"
)
@@ -264,6 +267,51 @@ func (u *ExpenseController) Approval(c *fiber.Ctx) error {
})
}
func (u *ExpenseController) BulkApproveToStatus(c *fiber.Ctx) error {
req := new(validation.BulkApprovalRequest)
if err := c.BodyParser(req); err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
}
targetStep, err := req.ResolveTarget()
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
if req.RequiresDate(targetStep) && strings.TrimSpace(req.Date) == "" {
return fiber.NewError(fiber.StatusBadRequest, "date is required for REALISASI bulk approval")
}
if err := ensureExpenseBulkApprovalPermission(c, targetStep); err != nil {
return err
}
results, err := u.ExpenseService.BulkApproveToStatus(c, req, targetStep)
if err != nil {
return err
}
var (
data interface{}
message = "Bulk approve expense successfully"
)
if len(results) == 1 {
data = results[0]
} else {
message = "Bulk approve expenses successfully"
data = results
}
return c.Status(fiber.StatusOK).
JSON(response.Success{
Code: fiber.StatusOK,
Status: "success",
Message: message,
Data: data,
})
}
func (u *ExpenseController) CreateRealization(c *fiber.Ctx) error {
expenseID := c.Params("id")
id, err := strconv.Atoi(expenseID)
@@ -366,6 +414,31 @@ func (u *ExpenseController) CompleteExpense(c *fiber.Ctx) error {
})
}
func ensureExpenseBulkApprovalPermission(c *fiber.Ctx, targetStep approvalutils.ApprovalStep) error {
requiredPerms := []string{}
switch targetStep {
case utils.ExpenseStepHeadArea:
requiredPerms = []string{m.P_ExpenseApprovalHeadArea}
case utils.ExpenseStepUnitVicePresident:
requiredPerms = []string{m.P_ExpenseApprovalUnitVicePresident}
case utils.ExpenseStepFinance:
requiredPerms = []string{m.P_ExpenseApprovalFinance}
case utils.ExpenseStepRealisasi:
requiredPerms = []string{m.P_ExpenseApprovalFinance, m.P_ExpenseCreateRealizations}
default:
return fiber.NewError(fiber.StatusBadRequest, "Invalid approval target")
}
for _, perm := range requiredPerms {
if !m.HasPermission(c, perm) {
return fiber.NewError(fiber.StatusForbidden, "Insufficient permission")
}
}
return nil
}
func (u *ExpenseController) DeleteDocument(c *fiber.Ctx) error {
expenseID, err := strconv.Atoi(c.Params("id"))
if err != nil {