From 2a3154042cc1aa75f77b99ca45a191e4c0c282b7 Mon Sep 17 00:00:00 2001 From: ragilap Date: Wed, 1 Apr 2026 15:58:00 +0700 Subject: [PATCH 1/4] fix filter purchase query param and search --- .../purchases/services/purchase.service.go | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/internal/modules/purchases/services/purchase.service.go b/internal/modules/purchases/services/purchase.service.go index a48e103d..5afc24a0 100644 --- a/internal/modules/purchases/services/purchase.service.go +++ b/internal/modules/purchases/services/purchase.service.go @@ -175,6 +175,7 @@ func (s *purchaseService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti for i := range approvalStatuses { approvalStatuses[i] = normalizeApprovalStatusFilter(approvalStatuses[i]) } + approvalStatus := normalizeApprovalStatusFilter(params.ApprovalStatus) purchases, total, err := s.PurchaseRepo.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB { db = s.withRelations(db) @@ -195,9 +196,14 @@ func (s *purchaseService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti db = db.Where("purchases.po_date >= ?", *poDateStart) } + if poDateStart != nil { + db = db.Where("purchases.po_date >= ?", *poDateStart) + } + if poDateEnd != nil { db = db.Where("purchases.po_date < ?", *poDateEnd) } + if scope.Restrict { if len(scope.IDs) == 0 { return db.Where("1 = 0") @@ -320,6 +326,70 @@ func (s *purchaseService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti ) } + if approvalStatus != "" { + approvalLike := "%" + approvalStatus + "%" + db = db.Where( + `EXISTS ( + SELECT 1 + FROM approvals a + WHERE a.approvable_type = ? + AND a.approvable_id = purchases.id + AND a.id = ( + SELECT a2.id + FROM approvals a2 + WHERE a2.approvable_type = ? + AND a2.approvable_id = purchases.id + ORDER BY a2.action_at DESC, a2.id DESC + LIMIT 1 + ) + AND ( + LOWER(COALESCE(a.step_name, '')) LIKE ? + OR LOWER(COALESCE(CAST(a.action AS TEXT), '')) LIKE ? + OR CAST(a.step_number AS TEXT) = ? + ) + )`, + utils.ApprovalWorkflowPurchase.String(), + utils.ApprovalWorkflowPurchase.String(), + approvalLike, + approvalLike, + approvalStatus, + ) + } + + if search != "" { + like := "%" + search + "%" + db = db.Where( + `( + LOWER(COALESCE(purchases.pr_number, '')) LIKE ? + OR LOWER(COALESCE(purchases.po_number, '')) LIKE ? + OR EXISTS ( + SELECT 1 + FROM suppliers s + WHERE s.id = purchases.supplier_id + AND LOWER(COALESCE(s.name, '')) LIKE ? + ) + OR EXISTS ( + SELECT 1 + FROM users u + WHERE u.id = purchases.created_by + AND LOWER(COALESCE(u.name, '')) LIKE ? + ) + OR EXISTS ( + SELECT 1 + FROM purchase_items pi + JOIN products p ON p.id = pi.product_id + WHERE pi.purchase_id = purchases.id + AND LOWER(COALESCE(p.name, '')) LIKE ? + ) + )`, + like, + like, + like, + like, + like, + ) + } + return db.Order("created_at DESC").Order("purchases.id DESC") }) From aa9863646ecf582d00d5cde822d930002a75200a Mon Sep 17 00:00:00 2001 From: ragilap Date: Wed, 1 Apr 2026 16:06:57 +0700 Subject: [PATCH 2/4] fix filter purchase ?approval_status=approved,rejected and ?product_category_id=1,2,3 --- .../purchases/services/purchase.service.go | 64 ++++++++++--------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/internal/modules/purchases/services/purchase.service.go b/internal/modules/purchases/services/purchase.service.go index 5afc24a0..3617ceff 100644 --- a/internal/modules/purchases/services/purchase.service.go +++ b/internal/modules/purchases/services/purchase.service.go @@ -175,7 +175,6 @@ func (s *purchaseService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti for i := range approvalStatuses { approvalStatuses[i] = normalizeApprovalStatusFilter(approvalStatuses[i]) } - approvalStatus := normalizeApprovalStatusFilter(params.ApprovalStatus) purchases, total, err := s.PurchaseRepo.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB { db = s.withRelations(db) @@ -326,34 +325,41 @@ func (s *purchaseService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti ) } - if approvalStatus != "" { - approvalLike := "%" + approvalStatus + "%" - db = db.Where( - `EXISTS ( - SELECT 1 - FROM approvals a - WHERE a.approvable_type = ? - AND a.approvable_id = purchases.id - AND a.id = ( - SELECT a2.id - FROM approvals a2 - WHERE a2.approvable_type = ? - AND a2.approvable_id = purchases.id - ORDER BY a2.action_at DESC, a2.id DESC - LIMIT 1 - ) - AND ( - LOWER(COALESCE(a.step_name, '')) LIKE ? - OR LOWER(COALESCE(CAST(a.action AS TEXT), '')) LIKE ? - OR CAST(a.step_number AS TEXT) = ? - ) - )`, - utils.ApprovalWorkflowPurchase.String(), - utils.ApprovalWorkflowPurchase.String(), - approvalLike, - approvalLike, - approvalStatus, - ) + if len(approvalStatuses) > 0 { + approvalConditions := make([]string, 0, len(approvalStatuses)) + approvalArgs := make([]any, 0, 2+(len(approvalStatuses)*3)) + approvalArgs = append(approvalArgs, utils.ApprovalWorkflowPurchase.String(), utils.ApprovalWorkflowPurchase.String()) + for _, status := range approvalStatuses { + if status == "" { + continue + } + like := "%" + status + "%" + approvalConditions = append(approvalConditions, `(LOWER(COALESCE(a.step_name, '')) LIKE ? OR LOWER(COALESCE(CAST(a.action AS TEXT), '')) LIKE ? OR CAST(a.step_number AS TEXT) = ?)`) + approvalArgs = append(approvalArgs, like, like, status) + } + + if len(approvalConditions) > 0 { + approvalClause := strings.Join(approvalConditions, " OR ") + approvalQuery := fmt.Sprintf( + `EXISTS ( + SELECT 1 + FROM approvals a + WHERE a.approvable_type = ? + AND a.approvable_id = purchases.id + AND a.id = ( + SELECT a2.id + FROM approvals a2 + WHERE a2.approvable_type = ? + AND a2.approvable_id = purchases.id + ORDER BY a2.action_at DESC, a2.id DESC + LIMIT 1 + ) + AND (%s) + )`, + approvalClause, + ) + db = db.Where(approvalQuery, approvalArgs...) + } } if search != "" { From b58e9a10b1c9372e2f49f9cff82b16e2b0c58c17 Mon Sep 17 00:00:00 2001 From: ragilap Date: Wed, 1 Apr 2026 16:25:04 +0700 Subject: [PATCH 3/4] fix filter purchase supplier repport --- internal/modules/repports/controllers/repport.controller.go | 1 + .../repports/repositories/purchase_supplier.repository.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/modules/repports/controllers/repport.controller.go b/internal/modules/repports/controllers/repport.controller.go index 5e33d2a0..5d85a53e 100644 --- a/internal/modules/repports/controllers/repport.controller.go +++ b/internal/modules/repports/controllers/repport.controller.go @@ -432,6 +432,7 @@ func (c *RepportController) GetProductionResult(ctx *fiber.Ctx) error { func parseCommaSeparatedInt64s(raw string) ([]int64, error) { return parseCommaSeparatedInt64sWithField(raw, "supplier_ids") } + func parseCommaSeparatedInt64sWithField(raw, field string) ([]int64, error) { raw = strings.TrimSpace(raw) if raw == "" { diff --git a/internal/modules/repports/repositories/purchase_supplier.repository.go b/internal/modules/repports/repositories/purchase_supplier.repository.go index d4860d3d..f484a6f1 100644 --- a/internal/modules/repports/repositories/purchase_supplier.repository.go +++ b/internal/modules/repports/repositories/purchase_supplier.repository.go @@ -71,7 +71,7 @@ func (r *purchaseSupplierRepositoryImpl) baseSupplierQuery(ctx context.Context, if len(filters.ProductCategoryIDs) > 0 { db = db. Joins("JOIN products ON products.id = purchase_items.product_id"). - Where("products.product_category_id IN ?", filters.ProductCategoryIDs) + Where("products.product_category_id IN ?", filters.ProductCategoryIDs) } if len(filters.AreaIDs) > 0 || filters.AllowedAreaIDs != nil { @@ -194,7 +194,7 @@ func (r *purchaseSupplierRepositoryImpl) GetItemsBySuppliers(ctx context.Context if len(filters.ProductCategoryIDs) > 0 { db = db. Joins("JOIN products ON products.id = purchase_items.product_id"). - Where("products.product_category_id IN ?", filters.ProductCategoryIDs) + Where("products.product_category_id IN ?", filters.ProductCategoryIDs) } if len(filters.AreaIDs) > 0 || filters.AllowedAreaIDs != nil { db = db.Joins("JOIN warehouses ON warehouses.id = purchase_items.warehouse_id") From 450d1e8ceed6cd8de055c921d222ce7810d7fbd7 Mon Sep 17 00:00:00 2001 From: giovanni Date: Wed, 8 Apr 2026 14:24:04 +0700 Subject: [PATCH 4/4] add filter lokasi and bop to purchase order --- .../purchases/services/purchase.service.go | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/internal/modules/purchases/services/purchase.service.go b/internal/modules/purchases/services/purchase.service.go index 3617ceff..0b360b1e 100644 --- a/internal/modules/purchases/services/purchase.service.go +++ b/internal/modules/purchases/services/purchase.service.go @@ -316,12 +316,30 @@ func (s *purchaseService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti WHERE pi.purchase_id = purchases.id AND LOWER(COALESCE(p.name, '')) LIKE ? ) + OR EXISTS ( + SELECT 1 + FROM purchase_items pi + JOIN warehouses w ON w.id = pi.warehouse_id + JOIN locations l ON l.id = w.location_id + WHERE pi.purchase_id = purchases.id + AND LOWER(COALESCE(l.name, '')) LIKE ? + ) + OR EXISTS ( + SELECT 1 + FROM purchase_items pi + JOIN expense_nonstocks en ON en.id = pi.expense_nonstock_id + JOIN expenses e ON e.id = en.expense_id + WHERE pi.purchase_id = purchases.id + AND LOWER(COALESCE(e.reference_number, '')) LIKE ? + ) )`, like, like, like, like, like, + like, + like, ) } @@ -387,12 +405,30 @@ func (s *purchaseService) GetAll(c *fiber.Ctx, params *validation.Query) ([]enti WHERE pi.purchase_id = purchases.id AND LOWER(COALESCE(p.name, '')) LIKE ? ) + OR EXISTS ( + SELECT 1 + FROM purchase_items pi + JOIN warehouses w ON w.id = pi.warehouse_id + JOIN locations l ON l.id = w.location_id + WHERE pi.purchase_id = purchases.id + AND LOWER(COALESCE(l.name, '')) LIKE ? + ) + OR EXISTS ( + SELECT 1 + FROM purchase_items pi + JOIN expense_nonstocks en ON en.id = pi.expense_nonstock_id + JOIN expenses e ON e.id = en.expense_id + WHERE pi.purchase_id = purchases.id + AND LOWER(COALESCE(e.reference_number, '')) LIKE ? + ) )`, like, like, like, like, like, + like, + like, ) }