From 14cc7ef2ae8b593cf36a6cd422821ee32233cfeb Mon Sep 17 00:00:00 2001 From: ragilap Date: Wed, 4 Feb 2026 13:31:20 +0700 Subject: [PATCH] [FEAT/BE] Add field purchase response get all --- .../common/service/common.fifo.service.go | 109 ++++++++++++------ .../modules/purchases/dto/purchase.dto.go | 64 +++++++++- 2 files changed, 131 insertions(+), 42 deletions(-) diff --git a/internal/common/service/common.fifo.service.go b/internal/common/service/common.fifo.service.go index 190bf819..fd1812fb 100644 --- a/internal/common/service/common.fifo.service.go +++ b/internal/common/service/common.fifo.service.go @@ -743,8 +743,6 @@ func (s *fifoService) releaseUsagePortion( if expectedWarehouseID == 0 || alloc.ProductWarehouseId == expectedWarehouseID { continue } - fmt.Printf("WARN[FIFO] ALLOC WAREHOUSE MISMATCH usable_key=%s usable_id=%d alloc_id=%d expected_pw=%d actual_pw=%d\n", - usableKey.String(), usableID, alloc.Id, expectedWarehouseID, alloc.ProductWarehouseId) if err := tx.Model(&entities.StockAllocation{}). Where("id = ?", alloc.Id). Update("product_warehouse_id", expectedWarehouseID).Error; err != nil { @@ -848,41 +846,80 @@ func (s *fifoService) fetchPendingCandidates(ctx context.Context, tx *gorm.DB, p cfg.Columns.CreatedAt, ) - var rows []struct { - ID uint - Pending float64 - CreatedAt time.Time - } - - query := tx.Table(cfg.Table). - Select(selectStmt). - Where(fmt.Sprintf("%s = ?", cfg.Columns.ProductWarehouseID), productWarehouseID). - Where(fmt.Sprintf("%s > 0", cfg.Columns.PendingQuantity)). - Limit(s.pendingBatchPerUsable) - - if cfg.Scope != nil { - query = cfg.Scope(query) - } - - for _, order := range s.orderClauses(cfg.OrderBy) { - query = query.Order(order) - } - - if err := query.Find(&rows).Error; err != nil { - return nil, err - } - - for _, row := range rows { - if row.Pending <= 0 { - continue + if cfg.Columns.CreatedAt == cfg.Columns.ID { + var rows []struct { + ID uint + Pending float64 + CreatedAt int64 + } + + query := tx.Table(cfg.Table). + Select(selectStmt). + Where(fmt.Sprintf("%s = ?", cfg.Columns.ProductWarehouseID), productWarehouseID). + Where(fmt.Sprintf("%s > 0", cfg.Columns.PendingQuantity)). + Limit(s.pendingBatchPerUsable) + + if cfg.Scope != nil { + query = cfg.Scope(query) + } + + for _, order := range s.orderClauses(cfg.OrderBy) { + query = query.Order(order) + } + + if err := query.Find(&rows).Error; err != nil { + return nil, err + } + + for _, row := range rows { + if row.Pending <= 0 { + continue + } + candidates = append(candidates, pendingCandidate{ + UsableKey: key, + Config: cfg, + UsableID: row.ID, + Pending: row.Pending, + CreatedAt: time.Unix(0, row.CreatedAt), + }) + } + } else { + var rows []struct { + ID uint + Pending float64 + CreatedAt time.Time + } + + query := tx.Table(cfg.Table). + Select(selectStmt). + Where(fmt.Sprintf("%s = ?", cfg.Columns.ProductWarehouseID), productWarehouseID). + Where(fmt.Sprintf("%s > 0", cfg.Columns.PendingQuantity)). + Limit(s.pendingBatchPerUsable) + + if cfg.Scope != nil { + query = cfg.Scope(query) + } + + for _, order := range s.orderClauses(cfg.OrderBy) { + query = query.Order(order) + } + + if err := query.Find(&rows).Error; err != nil { + return nil, err + } + + for _, row := range rows { + if row.Pending <= 0 { + continue + } + candidates = append(candidates, pendingCandidate{ + UsableKey: key, + Config: cfg, + UsableID: row.ID, + Pending: row.Pending, + CreatedAt: row.CreatedAt, + }) } - candidates = append(candidates, pendingCandidate{ - UsableKey: key, - Config: cfg, - UsableID: row.ID, - Pending: row.Pending, - CreatedAt: row.CreatedAt, - }) } } diff --git a/internal/modules/purchases/dto/purchase.dto.go b/internal/modules/purchases/dto/purchase.dto.go index 1956729c..444c41f0 100644 --- a/internal/modules/purchases/dto/purchase.dto.go +++ b/internal/modules/purchases/dto/purchase.dto.go @@ -1,6 +1,7 @@ package dto import ( + "strings" "time" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" @@ -24,12 +25,17 @@ type PurchaseRelationDTO struct { type PurchaseListDTO struct { PurchaseRelationDTO - Supplier *supplierDTO.SupplierRelationDTO `json:"supplier"` - DueDate *time.Time `json:"due_date"` - CreatedUser *userDTO.UserRelationDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - LatestApproval *approvalDTO.ApprovalRelationDTO `json:"latest_approval"` + Supplier *supplierDTO.SupplierRelationDTO `json:"supplier"` + DueDate *time.Time `json:"due_date"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + RequesterName string `json:"requester_name"` + PoExpedition []string `json:"po_expedition"` + Products []productDTO.ProductRelationDTO `json:"products"` + Location *locationDTO.LocationRelationDTO `json:"location"` + Area *areaDTO.AreaRelationDTO `json:"area"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + LatestApproval *approvalDTO.ApprovalRelationDTO `json:"latest_approval"` } type PurchaseDetailDTO struct { @@ -146,6 +152,10 @@ func ToPurchaseListDTO(p entity.Purchase) PurchaseListDTO { mapped := userDTO.ToUserRelationDTO(p.CreatedUser) createdUser = &mapped } + requesterName := "" + if createdUser != nil { + requesterName = createdUser.Name + } var latestApproval *approvalDTO.ApprovalRelationDTO if p.LatestApproval != nil && p.LatestApproval.Id != 0 { @@ -153,11 +163,53 @@ func ToPurchaseListDTO(p entity.Purchase) PurchaseListDTO { latestApproval = &mapped } + var ( + poExpedition []string + location *locationDTO.LocationRelationDTO + area *areaDTO.AreaRelationDTO + ) + productMap := make(map[uint]productDTO.ProductRelationDTO) + expeditionRefSet := make(map[string]struct{}) + for i := range p.Items { + item := p.Items[i] + if item.Product != nil && item.Product.Id != 0 { + if _, exists := productMap[item.Product.Id]; !exists { + productMap[item.Product.Id] = productDTO.ToProductRelationDTO(*item.Product) + } + } + if item.ExpenseNonstock != nil && item.ExpenseNonstock.Expense != nil { + ref := strings.TrimSpace(item.ExpenseNonstock.Expense.ReferenceNumber) + if ref != "" { + if _, exists := expeditionRefSet[ref]; !exists { + expeditionRefSet[ref] = struct{}{} + poExpedition = append(poExpedition, ref) + } + } + } + if location == nil && item.Warehouse != nil && item.Warehouse.Location != nil && item.Warehouse.Location.Id != 0 { + loc := locationDTO.ToLocationRelationDTO(*item.Warehouse.Location) + location = &loc + } + if area == nil && item.Warehouse != nil && item.Warehouse.Area.Id != 0 { + ar := areaDTO.ToAreaRelationDTO(item.Warehouse.Area) + area = &ar + } + } + products := make([]productDTO.ProductRelationDTO, 0, len(productMap)) + for _, prod := range productMap { + products = append(products, prod) + } + return PurchaseListDTO{ PurchaseRelationDTO: ToPurchaseRelationDTO(&p), Supplier: supplier, DueDate: p.DueDate, CreatedUser: createdUser, + RequesterName: requesterName, + PoExpedition: poExpedition, + Products: products, + Location: location, + Area: area, CreatedAt: p.CreatedAt, UpdatedAt: p.UpdatedAt, LatestApproval: latestApproval,