mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Feat[BE]: enhance transfer laying functionality with comprehensive filtering options and improved DTO structures
This commit is contained in:
+6
-3
@@ -9,6 +9,7 @@ import (
|
||||
service "gitlab.com/mbugroup/lti-api.git/internal/modules/production/transfer_layings/services"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/transfer_layings/validations"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/response"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
@@ -28,9 +29,11 @@ func (u *TransferLayingController) GetAll(c *fiber.Ctx) error {
|
||||
Page: c.QueryInt("page", 1),
|
||||
Limit: c.QueryInt("limit", 10),
|
||||
Search: c.Query("search", ""),
|
||||
TransferDate: c.Query("transfer_date", ""),
|
||||
FlockSource: uint(c.QueryInt("flock_source", 0)),
|
||||
FlockDestination: uint(c.QueryInt("flock_destination", 0)),
|
||||
StartDate: c.Query("start_date", ""),
|
||||
EndDate: c.Query("end_date", ""),
|
||||
FlockSource: utils.ParseQueryUintArray(c.Query("flock_source", "")),
|
||||
FlockDestination: utils.ParseQueryUintArray(c.Query("flock_destination", "")),
|
||||
Status: utils.ParseQueryArray(c.Query("status", "")),
|
||||
}
|
||||
|
||||
if query.Page < 1 || query.Limit < 1 {
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/dto"
|
||||
productWarehouseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/dto"
|
||||
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto"
|
||||
projectFlockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/dto"
|
||||
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
||||
)
|
||||
|
||||
@@ -17,60 +20,35 @@ type TransferLayingRelationDTO struct {
|
||||
Notes string `json:"notes"`
|
||||
}
|
||||
|
||||
type ProjectFlockSummaryDTO struct {
|
||||
Id uint `json:"id"`
|
||||
FlockName string `json:"flock_name"`
|
||||
Category string `json:"category"`
|
||||
}
|
||||
|
||||
type ProductSummaryDTO struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type WarehouseSummaryDTO struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type ProductWarehouseSummaryDTO struct {
|
||||
Product *ProductSummaryDTO `json:"product,omitempty"`
|
||||
Warehouse *WarehouseSummaryDTO `json:"warehouse,omitempty"`
|
||||
}
|
||||
|
||||
type ProjectFlockKandangSummaryDTO struct {
|
||||
Id uint `json:"id"`
|
||||
Kandang *KandangSummaryDTO `json:"kandang,omitempty"`
|
||||
}
|
||||
|
||||
type KandangSummaryDTO struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
type ProjectFlockKandangWithKandangDTO struct {
|
||||
Id uint `json:"id"`
|
||||
KandangId uint `json:"kandang_id"`
|
||||
ProjectFlockId uint `json:"project_flock_id"`
|
||||
Kandang *kandangDTO.KandangRelationDTO `json:"kandang,omitempty"`
|
||||
}
|
||||
|
||||
type LayingTransferSourceDTO struct {
|
||||
SourceProjectFlockKandang *ProjectFlockKandangSummaryDTO `json:"source_project_flock_kandang,omitempty"`
|
||||
Qty float64 `json:"qty"`
|
||||
ProductWarehouse *ProductWarehouseSummaryDTO `json:"product_warehouse,omitempty"`
|
||||
Note string `json:"note,omitempty"`
|
||||
SourceProjectFlockKandang *ProjectFlockKandangWithKandangDTO `json:"source_project_flock_kandang,omitempty"`
|
||||
Qty float64 `json:"qty"`
|
||||
ProductWarehouse *productWarehouseDTO.ProductWarehouseRelationDTO `json:"product_warehouse,omitempty"`
|
||||
Note string `json:"note,omitempty"`
|
||||
}
|
||||
|
||||
type LayingTransferTargetDTO struct {
|
||||
TargetProjectFlockKandang *ProjectFlockKandangSummaryDTO `json:"target_project_flock_kandang,omitempty"`
|
||||
Qty float64 `json:"qty"`
|
||||
ProductWarehouse *ProductWarehouseSummaryDTO `json:"product_warehouse,omitempty"`
|
||||
Note string `json:"note,omitempty"`
|
||||
TargetProjectFlockKandang *ProjectFlockKandangWithKandangDTO `json:"target_project_flock_kandang,omitempty"`
|
||||
Qty float64 `json:"qty"`
|
||||
ProductWarehouse *productWarehouseDTO.ProductWarehouseRelationDTO `json:"product_warehouse,omitempty"`
|
||||
Note string `json:"note,omitempty"`
|
||||
}
|
||||
|
||||
type TransferLayingListDTO struct {
|
||||
TransferLayingRelationDTO
|
||||
FromProjectFlock *ProjectFlockSummaryDTO `json:"from_project_flock,omitempty"`
|
||||
ToProjectFlock *ProjectFlockSummaryDTO `json:"to_project_flock,omitempty"`
|
||||
CreatedBy uint `json:"created_by"`
|
||||
CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Approval *approvalDTO.ApprovalRelationDTO `json:"approval,omitempty"`
|
||||
FromProjectFlock *projectFlockDTO.ProjectFlockRelationDTO `json:"from_project_flock,omitempty"`
|
||||
ToProjectFlock *projectFlockDTO.ProjectFlockRelationDTO `json:"to_project_flock,omitempty"`
|
||||
CreatedBy uint `json:"created_by"`
|
||||
CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Approval *approvalDTO.ApprovalRelationDTO `json:"approval,omitempty"`
|
||||
}
|
||||
|
||||
type TransferLayingDetailDTO struct {
|
||||
@@ -108,68 +86,12 @@ type MaxTargetQtyForTransferDTO struct {
|
||||
|
||||
// === Mapper Functions ===
|
||||
|
||||
func ToProjectFlockSummaryDTO(pf *entity.ProjectFlock) *ProjectFlockSummaryDTO {
|
||||
if pf == nil || pf.Id == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &ProjectFlockSummaryDTO{
|
||||
Id: pf.Id,
|
||||
FlockName: pf.FlockName,
|
||||
Category: pf.Category,
|
||||
}
|
||||
}
|
||||
|
||||
func ToProjectFlockKandangSummaryDTO(pfk *entity.ProjectFlockKandang) *ProjectFlockKandangSummaryDTO {
|
||||
if pfk == nil || pfk.Id == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var kandang *KandangSummaryDTO
|
||||
if pfk.Kandang.Id != 0 {
|
||||
kandang = &KandangSummaryDTO{
|
||||
Id: pfk.Kandang.Id,
|
||||
Name: pfk.Kandang.Name,
|
||||
}
|
||||
}
|
||||
|
||||
return &ProjectFlockKandangSummaryDTO{
|
||||
Id: pfk.Id,
|
||||
Kandang: kandang,
|
||||
}
|
||||
}
|
||||
|
||||
func ToProductSummaryDTO(product *entity.Product) *ProductSummaryDTO {
|
||||
if product == nil || product.Id == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &ProductSummaryDTO{
|
||||
Id: product.Id,
|
||||
Name: product.Name,
|
||||
}
|
||||
}
|
||||
|
||||
func ToWarehouseSummaryDTO(warehouse *entity.Warehouse) *WarehouseSummaryDTO {
|
||||
if warehouse == nil || warehouse.Id == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &WarehouseSummaryDTO{
|
||||
Id: warehouse.Id,
|
||||
Name: warehouse.Name,
|
||||
Type: warehouse.Type,
|
||||
}
|
||||
}
|
||||
|
||||
func ToProductWarehouseSummaryDTO(pw *entity.ProductWarehouse) *ProductWarehouseSummaryDTO {
|
||||
if pw == nil || pw.Id == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &ProductWarehouseSummaryDTO{
|
||||
Product: ToProductSummaryDTO(&pw.Product),
|
||||
Warehouse: ToWarehouseSummaryDTO(&pw.Warehouse),
|
||||
func ToTransferLayingRelationDTO(e entity.LayingTransfer) TransferLayingRelationDTO {
|
||||
return TransferLayingRelationDTO{
|
||||
Id: e.Id,
|
||||
TransferNumber: e.TransferNumber,
|
||||
TransferDate: e.TransferDate,
|
||||
Notes: e.Notes,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,10 +106,29 @@ func ToLayingTransferSourceDTO(source entity.LayingTransferSource) LayingTransfe
|
||||
displayQty = source.RequestedQty
|
||||
}
|
||||
|
||||
var pfkDTO *ProjectFlockKandangWithKandangDTO
|
||||
if source.SourceProjectFlockKandang != nil && source.SourceProjectFlockKandang.Id != 0 {
|
||||
pfkDTO = &ProjectFlockKandangWithKandangDTO{
|
||||
Id: source.SourceProjectFlockKandang.Id,
|
||||
KandangId: source.SourceProjectFlockKandang.KandangId,
|
||||
ProjectFlockId: source.SourceProjectFlockKandang.ProjectFlockId,
|
||||
}
|
||||
if source.SourceProjectFlockKandang.Kandang.Id != 0 {
|
||||
mapped := kandangDTO.ToKandangRelationDTO(source.SourceProjectFlockKandang.Kandang)
|
||||
pfkDTO.Kandang = &mapped
|
||||
}
|
||||
}
|
||||
|
||||
var pwDTO *productWarehouseDTO.ProductWarehouseRelationDTO
|
||||
if source.ProductWarehouse != nil && source.ProductWarehouse.Id != 0 {
|
||||
mapped := productWarehouseDTO.ToProductWarehouseRelationDTO(*source.ProductWarehouse)
|
||||
pwDTO = &mapped
|
||||
}
|
||||
|
||||
return LayingTransferSourceDTO{
|
||||
SourceProjectFlockKandang: ToProjectFlockKandangSummaryDTO(source.SourceProjectFlockKandang),
|
||||
SourceProjectFlockKandang: pfkDTO,
|
||||
Qty: displayQty,
|
||||
ProductWarehouse: ToProductWarehouseSummaryDTO(source.ProductWarehouse),
|
||||
ProductWarehouse: pwDTO,
|
||||
Note: source.Note,
|
||||
}
|
||||
}
|
||||
@@ -204,10 +145,29 @@ func ToLayingTransferSourceDTOs(sources []entity.LayingTransferSource) []LayingT
|
||||
}
|
||||
|
||||
func ToLayingTransferTargetDTO(target entity.LayingTransferTarget) LayingTransferTargetDTO {
|
||||
var pfkDTO *ProjectFlockKandangWithKandangDTO
|
||||
if target.TargetProjectFlockKandang != nil && target.TargetProjectFlockKandang.Id != 0 {
|
||||
pfkDTO = &ProjectFlockKandangWithKandangDTO{
|
||||
Id: target.TargetProjectFlockKandang.Id,
|
||||
KandangId: target.TargetProjectFlockKandang.KandangId,
|
||||
ProjectFlockId: target.TargetProjectFlockKandang.ProjectFlockId,
|
||||
}
|
||||
if target.TargetProjectFlockKandang.Kandang.Id != 0 {
|
||||
mapped := kandangDTO.ToKandangRelationDTO(target.TargetProjectFlockKandang.Kandang)
|
||||
pfkDTO.Kandang = &mapped
|
||||
}
|
||||
}
|
||||
|
||||
var pwDTO *productWarehouseDTO.ProductWarehouseRelationDTO
|
||||
if target.ProductWarehouse != nil && target.ProductWarehouse.Id != 0 {
|
||||
mapped := productWarehouseDTO.ToProductWarehouseRelationDTO(*target.ProductWarehouse)
|
||||
pwDTO = &mapped
|
||||
}
|
||||
|
||||
return LayingTransferTargetDTO{
|
||||
TargetProjectFlockKandang: ToProjectFlockKandangSummaryDTO(target.TargetProjectFlockKandang),
|
||||
Qty: target.TotalQty, // Ambil dari TotalQty (FIFO replenished quantity)
|
||||
ProductWarehouse: ToProductWarehouseSummaryDTO(target.ProductWarehouse),
|
||||
TargetProjectFlockKandang: pfkDTO,
|
||||
Qty: target.TotalQty,
|
||||
ProductWarehouse: pwDTO,
|
||||
Note: target.Note,
|
||||
}
|
||||
}
|
||||
@@ -223,15 +183,6 @@ func ToLayingTransferTargetDTOs(targets []entity.LayingTransferTarget) []LayingT
|
||||
return result
|
||||
}
|
||||
|
||||
func ToTransferLayingRelationDTO(e entity.LayingTransfer) TransferLayingRelationDTO {
|
||||
return TransferLayingRelationDTO{
|
||||
Id: e.Id,
|
||||
TransferNumber: e.TransferNumber,
|
||||
TransferDate: e.TransferDate,
|
||||
Notes: e.Notes,
|
||||
}
|
||||
}
|
||||
|
||||
func ToTransferLayingListDTO(e entity.LayingTransfer) TransferLayingListDTO {
|
||||
var createdUser *userDTO.UserRelationDTO
|
||||
if e.CreatedUser != nil && e.CreatedUser.Id != 0 {
|
||||
@@ -239,26 +190,52 @@ func ToTransferLayingListDTO(e entity.LayingTransfer) TransferLayingListDTO {
|
||||
createdUser = &mapped
|
||||
}
|
||||
|
||||
var approval *approvalDTO.ApprovalRelationDTO
|
||||
if e.LatestApproval != nil {
|
||||
mapped := approvalDTO.ToApprovalDTO(*e.LatestApproval)
|
||||
approval = &mapped
|
||||
}
|
||||
|
||||
// Build from project flock DTO
|
||||
var fromProjectFlock *projectFlockDTO.ProjectFlockRelationDTO
|
||||
if e.FromProjectFlock != nil && e.FromProjectFlock.Id != 0 {
|
||||
fromProjectFlock = &projectFlockDTO.ProjectFlockRelationDTO{
|
||||
Id: e.FromProjectFlock.Id,
|
||||
FlockName: e.FromProjectFlock.FlockName,
|
||||
}
|
||||
}
|
||||
|
||||
var toProjectFlock *projectFlockDTO.ProjectFlockRelationDTO
|
||||
if e.ToProjectFlock != nil && e.ToProjectFlock.Id != 0 {
|
||||
toProjectFlock = &projectFlockDTO.ProjectFlockRelationDTO{
|
||||
Id: e.ToProjectFlock.Id,
|
||||
FlockName: e.ToProjectFlock.FlockName,
|
||||
}
|
||||
}
|
||||
|
||||
return TransferLayingListDTO{
|
||||
TransferLayingRelationDTO: ToTransferLayingRelationDTO(e),
|
||||
FromProjectFlock: ToProjectFlockSummaryDTO(e.FromProjectFlock),
|
||||
ToProjectFlock: ToProjectFlockSummaryDTO(e.ToProjectFlock),
|
||||
FromProjectFlock: fromProjectFlock,
|
||||
ToProjectFlock: toProjectFlock,
|
||||
CreatedBy: e.CreatedBy,
|
||||
CreatedUser: createdUser,
|
||||
CreatedAt: e.CreatedAt,
|
||||
Approval: approval,
|
||||
}
|
||||
}
|
||||
|
||||
func ToTransferLayingDetailDTO(e entity.LayingTransfer, approvals []entity.Approval) TransferLayingDetailDTO {
|
||||
var latestApproval *approvalDTO.ApprovalRelationDTO
|
||||
|
||||
if e.LatestApproval != nil {
|
||||
mapped := approvalDTO.ToApprovalDTO(*e.LatestApproval)
|
||||
// Prioritas: e.LatestApproval > approvals slice
|
||||
approvalToMap := e.LatestApproval
|
||||
if approvalToMap == nil && len(approvals) > 0 {
|
||||
approvalToMap = &approvals[len(approvals)-1]
|
||||
}
|
||||
|
||||
if approvalToMap != nil {
|
||||
mapped := approvalDTO.ToApprovalDTO(*approvalToMap)
|
||||
latestApproval = &mapped
|
||||
} else if len(approvals) > 0 {
|
||||
// Fallback to approvals slice
|
||||
latest := approvalDTO.ToApprovalDTO(approvals[len(approvals)-1])
|
||||
latestApproval = &latest
|
||||
}
|
||||
|
||||
return TransferLayingDetailDTO{
|
||||
@@ -272,13 +249,14 @@ func ToTransferLayingDetailDTO(e entity.LayingTransfer, approvals []entity.Appro
|
||||
func ToTransferLayingDetailDTOWithSingleApproval(e entity.LayingTransfer, approval *entity.Approval) TransferLayingDetailDTO {
|
||||
var mappedApproval *approvalDTO.ApprovalRelationDTO
|
||||
|
||||
// Prefer LatestApproval from entity
|
||||
if e.LatestApproval != nil && e.LatestApproval.Id != 0 {
|
||||
mapped := approvalDTO.ToApprovalDTO(*e.LatestApproval)
|
||||
mappedApproval = &mapped
|
||||
} else if approval != nil && approval.Id != 0 {
|
||||
// Fallback to passed approval parameter
|
||||
mapped := approvalDTO.ToApprovalDTO(*approval)
|
||||
// Prioritas: e.LatestApproval > approval parameter
|
||||
approvalToMap := e.LatestApproval
|
||||
if approvalToMap == nil && approval != nil {
|
||||
approvalToMap = approval
|
||||
}
|
||||
|
||||
if approvalToMap != nil {
|
||||
mapped := approvalDTO.ToApprovalDTO(*approvalToMap)
|
||||
mappedApproval = &mapped
|
||||
}
|
||||
|
||||
|
||||
+94
@@ -2,6 +2,7 @@ package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
@@ -12,6 +13,9 @@ type TransferLayingRepository interface {
|
||||
repository.BaseRepository[entity.LayingTransfer]
|
||||
GetByTransferNumber(ctx context.Context, transferNumber string) (*entity.LayingTransfer, error)
|
||||
IdExists(ctx context.Context, id uint) (bool, error)
|
||||
|
||||
// Tambah method baru untuk query dengan filter lengkap
|
||||
GetAllWithFilters(ctx context.Context, offset int, limit int, params *GetAllFilterParams) ([]entity.LayingTransfer, int64, error)
|
||||
}
|
||||
|
||||
type TransferLayingRepositoryImpl struct {
|
||||
@@ -40,3 +44,93 @@ func (r *TransferLayingRepositoryImpl) GetByTransferNumber(ctx context.Context,
|
||||
}
|
||||
return &transfer, nil
|
||||
}
|
||||
|
||||
type GetAllFilterParams struct {
|
||||
Search string
|
||||
StartDate string
|
||||
EndDate string
|
||||
FlockSource []uint
|
||||
FlockDestination []uint
|
||||
Status []string
|
||||
}
|
||||
|
||||
func (r *TransferLayingRepositoryImpl) GetAllWithFilters(ctx context.Context, offset int, limit int, params *GetAllFilterParams) ([]entity.LayingTransfer, int64, error) {
|
||||
var records []entity.LayingTransfer
|
||||
var total int64
|
||||
|
||||
q := r.db.WithContext(ctx).Model(&entity.LayingTransfer{})
|
||||
|
||||
if params.Search != "" {
|
||||
searchPattern := "%" + params.Search + "%"
|
||||
q = q.Joins("LEFT JOIN project_flocks AS pf_from ON laying_transfers.from_project_flock_id = pf_from.id").
|
||||
Joins("LEFT JOIN project_flocks AS pf_to ON laying_transfers.to_project_flock_id = pf_to.id").
|
||||
Where("laying_transfers.transfer_number ILIKE ? OR laying_transfers.notes ILIKE ? OR pf_from.flock_name ILIKE ? OR pf_to.flock_name ILIKE ?",
|
||||
searchPattern, searchPattern, searchPattern, searchPattern)
|
||||
}
|
||||
|
||||
if params.StartDate != "" && params.EndDate != "" {
|
||||
q = q.Where("transfer_date::date >= ?::date AND transfer_date::date <= ?::date",
|
||||
params.StartDate, params.EndDate)
|
||||
} else if params.StartDate != "" {
|
||||
q = q.Where("transfer_date::date >= ?::date", params.StartDate)
|
||||
} else if params.EndDate != "" {
|
||||
q = q.Where("transfer_date::date <= ?::date", params.EndDate)
|
||||
}
|
||||
|
||||
if len(params.FlockSource) > 0 {
|
||||
q = q.Where("from_project_flock_id IN ?", params.FlockSource)
|
||||
}
|
||||
|
||||
if len(params.FlockDestination) > 0 {
|
||||
q = q.Where("to_project_flock_id IN ?", params.FlockDestination)
|
||||
}
|
||||
|
||||
if len(params.Status) > 0 {
|
||||
statusConditions := []string{}
|
||||
statusValues := []interface{}{}
|
||||
|
||||
for _, status := range params.Status {
|
||||
switch status {
|
||||
case "PENDING":
|
||||
statusConditions = append(statusConditions,
|
||||
"NOT EXISTS (SELECT 1 FROM approvals WHERE approvable_type = 'TRANSFER_TO_LAYINGS' AND approvable_id = laying_transfers.id)")
|
||||
|
||||
case "APPROVED":
|
||||
statusConditions = append(statusConditions,
|
||||
"EXISTS (SELECT 1 FROM approvals WHERE approvable_type = 'TRANSFER_TO_LAYINGS' AND approvable_id = laying_transfers.id AND action = 'APPROVED' ORDER BY created_at DESC LIMIT 1)")
|
||||
|
||||
case "REJECTED":
|
||||
statusConditions = append(statusConditions,
|
||||
"EXISTS (SELECT 1 FROM approvals WHERE approvable_type = 'TRANSFER_TO_LAYINGS' AND approvable_id = laying_transfers.id AND action = 'REJECTED' ORDER BY created_at DESC LIMIT 1)")
|
||||
}
|
||||
}
|
||||
|
||||
if len(statusConditions) > 0 {
|
||||
q = q.Where("("+strings.Join(statusConditions, " OR ")+")", statusValues...)
|
||||
}
|
||||
}
|
||||
|
||||
if err := q.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
q = q.Offset(offset).Limit(limit).
|
||||
Preload("FromProjectFlock").
|
||||
Preload("ToProjectFlock").
|
||||
Preload("CreatedUser").
|
||||
Preload("Sources").
|
||||
Preload("Sources.SourceProjectFlockKandang").
|
||||
Preload("Sources.SourceProjectFlockKandang.Kandang").
|
||||
Preload("Sources.ProductWarehouse").
|
||||
Preload("Targets").
|
||||
Preload("Targets.TargetProjectFlockKandang").
|
||||
Preload("Targets.TargetProjectFlockKandang.Kandang").
|
||||
Preload("Targets.ProductWarehouse").
|
||||
Order("laying_transfers.created_at DESC")
|
||||
|
||||
if err := q.Find(&records).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return records, total, nil
|
||||
}
|
||||
|
||||
@@ -109,34 +109,20 @@ func (s transferLayingService) GetAll(c *fiber.Ctx, params *validation.Query) ([
|
||||
|
||||
offset := (params.Page - 1) * params.Limit
|
||||
|
||||
transferLayings, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
||||
// Apply search and filters
|
||||
if params.Search != "" {
|
||||
searchPattern := "%" + params.Search + "%"
|
||||
db = db.Joins("LEFT JOIN project_flocks AS pf_from ON laying_transfers.from_project_flock_id = pf_from.id").
|
||||
Joins("LEFT JOIN project_flocks AS pf_to ON laying_transfers.to_project_flock_id = pf_to.id").
|
||||
Where("laying_transfers.transfer_number ILIKE ? OR laying_transfers.notes ILIKE ? OR pf_from.flock_name ILIKE ? OR pf_to.flock_name ILIKE ?",
|
||||
searchPattern, searchPattern, searchPattern, searchPattern)
|
||||
}
|
||||
filterParams := &repository.GetAllFilterParams{
|
||||
Search: params.Search,
|
||||
StartDate: params.StartDate,
|
||||
EndDate: params.EndDate,
|
||||
FlockSource: params.FlockSource,
|
||||
FlockDestination: params.FlockDestination,
|
||||
Status: params.Status,
|
||||
}
|
||||
|
||||
if params.TransferDate != "" {
|
||||
db = db.Where("transfer_date::date = ?::date", params.TransferDate)
|
||||
}
|
||||
|
||||
if params.FlockSource > 0 {
|
||||
db = db.Where("from_project_flock_id = ?", params.FlockSource)
|
||||
}
|
||||
|
||||
if params.FlockDestination > 0 {
|
||||
db = db.Where("to_project_flock_id = ?", params.FlockDestination)
|
||||
}
|
||||
|
||||
db = db.Order("created_at DESC")
|
||||
|
||||
db = s.withRelations(db)
|
||||
|
||||
return db
|
||||
})
|
||||
transferLayings, total, err := s.Repository.GetAllWithFilters(c.Context(), offset, params.Limit, filterParams)
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to get transferLayings: %+v", err)
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to get transferLayings: %+v", err)
|
||||
|
||||
+8
-6
@@ -29,12 +29,14 @@ type Update struct {
|
||||
}
|
||||
|
||||
type Query 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"`
|
||||
Search string `query:"search" validate:"omitempty"`
|
||||
TransferDate string `query:"transfer_date" validate:"omitempty"`
|
||||
FlockSource uint `query:"flock_source" validate:"omitempty,number"`
|
||||
FlockDestination uint `query:"flock_destination" validate:"omitempty,number"`
|
||||
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"`
|
||||
StartDate string `query:"start_date" validate:"omitempty"`
|
||||
EndDate string `query:"end_date" validate:"omitempty"`
|
||||
FlockSource []uint `query:"flock_source" validate:"omitempty"`
|
||||
FlockDestination []uint `query:"flock_destination" validate:"omitempty"`
|
||||
Status []string `query:"status" validate:"omitempty"`
|
||||
}
|
||||
|
||||
type Approve struct {
|
||||
|
||||
@@ -2,6 +2,7 @@ package utils
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -47,3 +48,54 @@ func ParseFlags(raw string) []string {
|
||||
sort.Strings(res)
|
||||
return res
|
||||
}
|
||||
|
||||
// ParseQueryArray parses comma-separated string values and returns a slice of trimmed strings
|
||||
// Example: "a, b, c" → ["a", "b", "c"]
|
||||
func ParseQueryArray(raw string) []string {
|
||||
if raw == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
parts := strings.Split(raw, ",")
|
||||
result := make([]string, 0, len(parts))
|
||||
|
||||
for _, p := range parts {
|
||||
trimmed := strings.TrimSpace(p)
|
||||
if trimmed != "" {
|
||||
result = append(result, trimmed)
|
||||
}
|
||||
}
|
||||
|
||||
if len(result) == 0 {
|
||||
return nil
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ParseQueryUintArray parses comma-separated string values and returns a slice of uint
|
||||
// Invalid values are skipped
|
||||
// Example: "1, 2, 3" → [1, 2, 3]
|
||||
func ParseQueryUintArray(raw string) []uint {
|
||||
if raw == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
parts := strings.Split(raw, ",")
|
||||
result := make([]uint, 0, len(parts))
|
||||
|
||||
for _, p := range parts {
|
||||
trimmed := strings.TrimSpace(p)
|
||||
if trimmed == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if num, err := strconv.ParseUint(trimmed, 10, 32); err == nil {
|
||||
result = append(result, uint(num))
|
||||
}
|
||||
}
|
||||
|
||||
if len(result) == 0 {
|
||||
return nil
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user