diff --git a/internal/modules/marketing/controllers/deliveryorder.controller.go b/internal/modules/marketing/controllers/deliveryorder.controller.go index 73904cc3..3a6ca49b 100644 --- a/internal/modules/marketing/controllers/deliveryorder.controller.go +++ b/internal/modules/marketing/controllers/deliveryorder.controller.go @@ -3,6 +3,7 @@ package controller import ( "math" "strconv" + "strings" "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/dto" service "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/services" @@ -23,9 +24,38 @@ func NewDeliveryOrdersController(deliveryOrdersService service.DeliveryOrdersSer } func (u *DeliveryOrdersController) GetAll(c *fiber.Ctx) error { + parseUintListParam := func(param string) ([]uint, error) { + if param == "" { + return nil, nil + } + parts := strings.Split(param, ",") + ids := make([]uint, 0, len(parts)) + for _, part := range parts { + trimmed := strings.TrimSpace(part) + if trimmed == "" { + return nil, strconv.ErrSyntax + } + parsed, err := strconv.ParseUint(trimmed, 10, 64) + if err != nil { + return nil, err + } + ids = append(ids, uint(parsed)) + } + return ids, nil + } + + productIDs, err := parseUintListParam(c.Query("product_ids", "")) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, "Invalid product_ids") + } + query := &validation.DeliveryOrderQuery{ Page: c.QueryInt("page", 1), Limit: c.QueryInt("limit", 10), + Search: strings.TrimSpace(c.Query("search", "")), + ProductIDs: productIDs, + Status: strings.ReplaceAll(strings.TrimSpace(c.Query("status", "")), "_", " "), + CustomerId: uint(c.QueryInt("customer_id", 0)), MarketingId: uint(c.QueryInt("marketing_id", 0)), } diff --git a/internal/modules/marketing/services/deliveryorder.service.go b/internal/modules/marketing/services/deliveryorder.service.go index 493f689f..677ef965 100644 --- a/internal/modules/marketing/services/deliveryorder.service.go +++ b/internal/modules/marketing/services/deliveryorder.service.go @@ -116,6 +116,71 @@ func (s deliveryOrdersService) GetAll(c *fiber.Ctx, params *validation.DeliveryO Preload("Products.ProductWarehouse.Warehouse"). Preload("Products.DeliveryProduct") + if params.Status != "" { + latestApprovalSubQuery := s.MarketingRepo.DB(). + WithContext(c.Context()). + Table("approvals"). + Select("DISTINCT ON (approvable_id) approvable_id, step_name"). + Where("approvable_type = ?", utils.ApprovalWorkflowMarketing.String()). + Order("approvable_id, id DESC") + db = db.Where(`EXISTS ( + SELECT 1 + FROM (?) AS latest_approval + WHERE latest_approval.approvable_id = marketings.id + AND LOWER(latest_approval.step_name) = LOWER(?) + )`, latestApprovalSubQuery, params.Status) + } + + if params.Search != "" { + searchPattern := "%" + params.Search + "%" + db = db.Where(`( + marketings.so_number ILIKE ? OR + EXISTS ( + SELECT 1 + FROM customers c + WHERE c.id = marketings.customer_id + AND c.name ILIKE ? + ) OR + EXISTS ( + SELECT 1 + FROM users su + WHERE su.id = marketings.sales_person_id + AND su.name ILIKE ? + ) OR + EXISTS ( + SELECT 1 + FROM marketing_products mp + JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id + JOIN products p ON p.id = pw.product_id + WHERE mp.marketing_id = marketings.id + AND p.name ILIKE ? + ) OR + EXISTS ( + SELECT 1 + FROM marketing_products mp + JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id + JOIN warehouses w ON w.id = pw.warehouse_id + WHERE mp.marketing_id = marketings.id + AND w.name ILIKE ? + ) + )`, searchPattern, searchPattern, searchPattern, searchPattern, searchPattern) + } + + if len(params.ProductIDs) > 0 { + db = db.Where(`EXISTS ( + SELECT 1 + FROM marketing_products mp + JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id + JOIN products p ON p.id = pw.product_id + WHERE mp.marketing_id = marketings.id + AND p.id IN ? + )`, params.ProductIDs) + } + + if params.CustomerId != 0 { + db = db.Where("marketings.customer_id = ?", params.CustomerId) + } + if scope.Restrict { if len(scope.IDs) == 0 { return db.Where("1 = 0") diff --git a/internal/modules/marketing/validations/deliveryorder.validation.go b/internal/modules/marketing/validations/deliveryorder.validation.go index a879db6f..e4687fad 100644 --- a/internal/modules/marketing/validations/deliveryorder.validation.go +++ b/internal/modules/marketing/validations/deliveryorder.validation.go @@ -19,9 +19,13 @@ type DeliveryOrderUpdate struct { } type DeliveryOrderQuery struct { - Page int `query:"page" validate:"omitempty,number,min=1,gt=0"` - Limit int `query:"limit" validate:"omitempty,number,min=1,max=100,gt=0"` - MarketingId uint `query:"marketing_id" validate:"omitempty,gt=0"` + Page int `query:"page" validate:"omitempty,number,min=1,gt=0"` + Limit int `query:"limit" validate:"omitempty,number,min=1,max=100,gt=0"` + Search string `query:"search" validate:"omitempty,max=100"` + ProductIDs []uint `query:"product_ids" validate:"omitempty,dive,gt=0"` + Status string `query:"status" validate:"omitempty,max=50"` + CustomerId uint `query:"customer_id" validate:"omitempty,gt=0"` + MarketingId uint `query:"marketing_id" validate:"omitempty,gt=0"` } type DeliveryOrderApprove struct { diff --git a/internal/modules/purchases/dto/purchase.dto.go b/internal/modules/purchases/dto/purchase.dto.go index 444c41f0..c8df2294 100644 --- a/internal/modules/purchases/dto/purchase.dto.go +++ b/internal/modules/purchases/dto/purchase.dto.go @@ -25,17 +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"` - 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"` + Supplier *supplierDTO.SupplierRelationDTO `json:"supplier"` + DueDate *time.Time `json:"due_date"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + RequesterName string `json:"requester_name"` + PoExpedition []PoExpeditionDTO `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 { @@ -69,6 +69,11 @@ type PurchaseItemDTO struct { ExpeditionVendor *supplierDTO.SupplierRelationDTO `json:"expedition_vendor,omitempty"` } +type PoExpeditionDTO struct { + Id uint64 `json:"id"` + Refrence string `json:"refrence"` +} + func ToPurchaseRelationDTO(p *entity.Purchase) PurchaseRelationDTO { return PurchaseRelationDTO{ Id: p.Id, @@ -164,12 +169,12 @@ func ToPurchaseListDTO(p entity.Purchase) PurchaseListDTO { } var ( - poExpedition []string + poExpedition = make([]PoExpeditionDTO, 0) location *locationDTO.LocationRelationDTO area *areaDTO.AreaRelationDTO ) productMap := make(map[uint]productDTO.ProductRelationDTO) - expeditionRefSet := make(map[string]struct{}) + expeditionRefSet := make(map[uint64]struct{}) for i := range p.Items { item := p.Items[i] if item.Product != nil && item.Product.Id != 0 { @@ -178,11 +183,15 @@ func ToPurchaseListDTO(p entity.Purchase) PurchaseListDTO { } } 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) + exp := item.ExpenseNonstock.Expense + ref := strings.TrimSpace(exp.ReferenceNumber) + if exp.Id != 0 && ref != "" { + if _, exists := expeditionRefSet[exp.Id]; !exists { + expeditionRefSet[exp.Id] = struct{}{} + poExpedition = append(poExpedition, PoExpeditionDTO{ + Id: exp.Id, + Refrence: ref, + }) } } }