Mhamdans17 commited on
Commit
6c773a6
·
1 Parent(s): f168cd0

perf: optimize ListProducts using database-level pagination, search, and branch filtering

Browse files
Files changed (1) hide show
  1. controllers/product_controller.go +22 -19
controllers/product_controller.go CHANGED
@@ -4,6 +4,7 @@ import (
4
  "fmt"
5
  "net/http"
6
  "strconv"
 
7
 
8
  "service-warungpos-go/config"
9
  "service-warungpos-go/models"
@@ -292,8 +293,10 @@ func ListProducts(c *gin.Context) {
292
  categoryFilter := c.Query("category_id")
293
  activeOnlyStr := c.DefaultQuery("active_only", "true")
294
  activeOnly := activeOnlyStr == "true"
 
 
 
295
 
296
- var products []models.Product
297
  query := config.DB.Preload("Category").Where("company_id = ?", *user.CompanyID)
298
 
299
  if activeOnly {
@@ -306,30 +309,30 @@ func ListProducts(c *gin.Context) {
306
  }
307
  }
308
 
309
- if err := query.Find(&products).Error; err != nil {
310
- c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal mengambil data produk"})
311
- return
312
  }
313
 
314
- // Filter ketersediaan cabang (BranchProduct)
315
  if branchID != nil {
316
- var branchProducts []models.BranchProduct
317
- config.DB.Where("branch_id = ?", *branchID).Find(&branchProducts)
318
 
319
- bpMap := make(map[uint]bool)
320
- for _, bp := range branchProducts {
321
- bpMap[bp.ProductID] = bp.IsAvailable
 
322
  }
323
-
324
- var filteredProducts []models.Product
325
- for _, p := range products {
326
- isAvailable, exists := bpMap[p.ID]
327
- // Jika belum disetting di cabang (exists=false), default-nya adalah tersedia (isAvailable=true)
328
- if !exists || isAvailable {
329
- filteredProducts = append(filteredProducts, p)
330
- }
331
  }
332
- c.JSON(http.StatusOK, filteredProducts)
 
 
 
 
333
  return
334
  }
335
 
 
4
  "fmt"
5
  "net/http"
6
  "strconv"
7
+ "strings"
8
 
9
  "service-warungpos-go/config"
10
  "service-warungpos-go/models"
 
293
  categoryFilter := c.Query("category_id")
294
  activeOnlyStr := c.DefaultQuery("active_only", "true")
295
  activeOnly := activeOnlyStr == "true"
296
+ searchQuery := c.Query("search")
297
+ limitStr := c.Query("limit")
298
+ skipStr := c.Query("skip")
299
 
 
300
  query := config.DB.Preload("Category").Where("company_id = ?", *user.CompanyID)
301
 
302
  if activeOnly {
 
309
  }
310
  }
311
 
312
+ if searchQuery != "" {
313
+ query = query.Where("LOWER(name) LIKE ? OR LOWER(sku) LIKE ?", "%"+strings.ToLower(searchQuery)+"%", "%"+strings.ToLower(searchQuery)+"%")
 
314
  }
315
 
316
+ // Filter ketersediaan cabang (BranchProduct) di level database
317
  if branchID != nil {
318
+ query = query.Where("id NOT IN (SELECT product_id FROM branch_products WHERE branch_id = ? AND is_available = ?)", *branchID, false)
319
+ }
320
 
321
+ // Terapkan pagination jika limit diisi
322
+ if limitStr != "" {
323
+ if limit, err := strconv.Atoi(limitStr); err == nil {
324
+ query = query.Limit(limit)
325
  }
326
+ }
327
+ if skipStr != "" {
328
+ if skip, err := strconv.Atoi(skipStr); err == nil {
329
+ query = query.Offset(skip)
 
 
 
 
330
  }
331
+ }
332
+
333
+ var products []models.Product
334
+ if err := query.Find(&products).Error; err != nil {
335
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal mengambil data produk"})
336
  return
337
  }
338