feature/expense #13

Merged
aefril merged 10 commits from feature/expense into main 2026-06-01 17:20:29 +00:00
6 changed files with 61 additions and 9 deletions
Showing only changes of commit 66a8126da0 - Show all commits

View File

@ -75,6 +75,9 @@ type ListExpenseRequest struct {
Page int `json:"page" validate:"min=1"`
Limit int `json:"limit" validate:"min=1,max=100"`
Search string `json:"search,omitempty"`
OutletID string `json:"outlet_id,omitempty"`
StartDate string `json:"start_date,omitempty"`
EndDate string `json:"end_date,omitempty"`
}
type ListExpenseResponse struct {

View File

@ -164,6 +164,22 @@ func (h *ExpenseHandler) ListExpenses(c *gin.Context) {
req.Search = search
}
// Prioritize outlet_id from context (e.g. outlet-scoped user),
// fall back to query param if context has no outlet.
if contextInfo.OutletID != uuid.Nil {
req.OutletID = contextInfo.OutletID.String()
} else if outletID := c.Query("outlet_id"); outletID != "" {
req.OutletID = outletID
}
if startDate := c.Query("start_date"); startDate != "" {
req.StartDate = startDate
}
if endDate := c.Query("end_date"); endDate != "" {
req.EndDate = endDate
}
validationError, validationErrorCode := h.expenseValidator.ValidateListExpenseRequest(req)
if validationError != nil {
validationResponseError := contract.NewResponseError(validationErrorCode, constants.RequestEntity, validationError.Error())

View File

@ -101,6 +101,9 @@ type ListExpenseRequest struct {
Page int `json:"page"`
Limit int `json:"limit"`
Search string `json:"search,omitempty"`
OutletID string `json:"outlet_id,omitempty"`
StartDate string `json:"start_date,omitempty"`
EndDate string `json:"end_date,omitempty"`
}
type ListExpenseResponse struct {

View File

@ -3,6 +3,7 @@ package repository
import (
"context"
"strings"
"time"
"github.com/google/uuid"
@ -74,6 +75,14 @@ func (r *ExpenseRepositoryImpl) List(ctx context.Context, organizationID uuid.UU
if outletID, ok := value.(uuid.UUID); ok {
query = query.Where("outlet_id = ?", outletID)
}
case "start_date":
if startDate, ok := value.(time.Time); ok {
query = query.Where("transaction_date >= ?", startDate)
}
case "end_date":
if endDate, ok := value.(time.Time); ok {
query = query.Where("transaction_date <= ?", endDate)
}
default:
query = query.Where(key+" = ?", value)
}

View File

@ -3,6 +3,7 @@ package service
import (
"apskel-pos-be/internal/appcontext"
"context"
"time"
"apskel-pos-be/internal/constants"
"apskel-pos-be/internal/contract"
@ -86,6 +87,23 @@ func (s *ExpenseServiceImpl) ListExpenses(ctx context.Context, apctx *appcontext
if modelReq.Search != "" {
filters["search"] = modelReq.Search
}
if modelReq.OutletID != "" {
outletID, err := uuid.Parse(modelReq.OutletID)
if err == nil {
filters["outlet_id"] = outletID
}
}
if modelReq.StartDate != "" {
if startDate, err := time.Parse("2006-01-02", modelReq.StartDate); err == nil {
filters["start_date"] = startDate
}
}
if modelReq.EndDate != "" {
if endDate, err := time.Parse("2006-01-02", modelReq.EndDate); err == nil {
// include the full end date day
filters["end_date"] = endDate.Add(24*time.Hour - time.Nanosecond)
}
}
expenses, totalPages, err := s.expenseProcessor.ListExpenses(ctx, apctx.OrganizationID, filters, modelReq.Page, modelReq.Limit)
if err != nil {

View File

@ -69,6 +69,9 @@ func ListExpenseRequestToModel(req *contract.ListExpenseRequest) *models.ListExp
Page: req.Page,
Limit: req.Limit,
Search: req.Search,
OutletID: req.OutletID,
StartDate: req.StartDate,
EndDate: req.EndDate,
}
}