feat[BE-127]: create available qty API and inisiate sales order and delivery order

This commit is contained in:
aguhh18
2025-11-07 13:24:48 +07:00
parent ba12320d12
commit 6e69e97d26
24 changed files with 695 additions and 68 deletions
@@ -31,6 +31,7 @@ type TransferLayingService interface {
UpdateOne(ctx *fiber.Ctx, req *validation.Update, id uint) (*entity.LayingTransfer, error)
DeleteOne(ctx *fiber.Ctx, id uint) error
Approval(ctx *fiber.Ctx, req *validation.Approve) ([]entity.LayingTransfer, error)
GetAvailableQtyPerKandang(ctx *fiber.Ctx, projectFlockID uint) (*entity.ProjectFlock, map[uint]float64, error)
}
type transferLayingService struct {
@@ -92,32 +93,7 @@ func (s transferLayingService) GetAll(c *fiber.Ctx, params *validation.Query) ([
transferLayings, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
db = s.withRelations(db)
if params.SourceProjectFlockId != 0 {
db = db.Where("from_project_flock_id = ?", params.SourceProjectFlockId)
}
if params.TargetProjectFlockId != 0 {
db = db.Where("to_project_flock_id = ?", params.TargetProjectFlockId)
}
if params.TransferDateFrom != "" {
db = db.Where("transfer_date >= ?", params.TransferDateFrom)
}
if params.TransferDateTo != "" {
db = db.Where("transfer_date <= ?", params.TransferDateTo)
}
if params.TransferNumber != "" {
db = db.Where("transfer_number ILIKE ?", "%"+params.TransferNumber+"%")
}
sortField := "created_at"
if params.Sort != "" {
sortField = params.Sort
}
sortOrder := "DESC"
if params.Order == "asc" {
sortOrder = "ASC"
}
db = db.Order(fmt.Sprintf("%s %s", sortField, sortOrder))
db = db.Order("created_at DESC")
return db
})
@@ -126,19 +102,14 @@ func (s transferLayingService) GetAll(c *fiber.Ctx, params *validation.Query) ([
return nil, 0, err
}
if params.ApprovalStatus != "" {
var filtered []entity.LayingTransfer
approvalRepo := commonRepo.NewApprovalRepository(s.Repository.DB())
for _, transfer := range transferLayings {
latestApproval, err := approvalRepo.LatestByTarget(c.Context(), string(utils.ApprovalWorkflowTransferToLaying), transfer.Id, nil)
if err == nil && latestApproval != nil && latestApproval.Action != nil {
if string(*latestApproval.Action) == params.ApprovalStatus {
filtered = append(filtered, transfer)
}
}
approvalRepo := commonRepo.NewApprovalRepository(s.Repository.DB())
for i, transfer := range transferLayings {
latestApproval, err := approvalRepo.LatestByTarget(c.Context(), string(utils.ApprovalWorkflowTransferToLaying), transfer.Id, func(db *gorm.DB) *gorm.DB {
return db.Preload("ActionUser")
})
if err == nil && latestApproval != nil {
transferLayings[i].LatestApproval = latestApproval
}
transferLayings = filtered
}
return transferLayings, total, nil
@@ -155,7 +126,9 @@ func (s transferLayingService) GetOne(c *fiber.Ctx, id uint) (*entity.LayingTran
}
approvalRepo := commonRepo.NewApprovalRepository(s.Repository.DB())
latestApproval, err := approvalRepo.LatestByTarget(c.Context(), string(utils.ApprovalWorkflowTransferToLaying), transferLaying.Id, nil)
latestApproval, err := approvalRepo.LatestByTarget(c.Context(), string(utils.ApprovalWorkflowTransferToLaying), transferLaying.Id, func(db *gorm.DB) *gorm.DB {
return db.Preload("ActionUser")
})
if err == nil && latestApproval != nil {
transferLaying.LatestApproval = latestApproval
}
@@ -547,7 +520,6 @@ func (s transferLayingService) DeleteOne(c *fiber.Ctx, id uint) error {
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Cannot delete transfer laying with status %s", action))
}
}
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
@@ -851,8 +823,6 @@ func (s *transferLayingService) restoreProjectFlockPopulation(ctx context.Contex
return fiber.NewError(fiber.StatusBadRequest, "No populations found for restoration")
}
// Restore in LIFO order (from newest to oldest)
// Add all quantity back to the last (newest) population
if len(populations) > 0 {
lastPop := populations[len(populations)-1]
newQty := lastPop.TotalQty + quantityToRestore
@@ -863,3 +833,37 @@ func (s *transferLayingService) restoreProjectFlockPopulation(ctx context.Contex
return nil
}
func (s transferLayingService) GetAvailableQtyPerKandang(ctx *fiber.Ctx, projectFlockID uint) (*entity.ProjectFlock, map[uint]float64, error) {
pf, err := s.ProjectFlockRepo.GetByID(ctx.Context(), projectFlockID, func(db *gorm.DB) *gorm.DB {
return db
})
if err != nil {
s.Log.Errorf("Failed to get project flock %d: %+v", projectFlockID, err)
return nil, nil, fiber.NewError(fiber.StatusNotFound, "Project flock not found")
}
kandangs, _, err := s.ProjectFlockKandangRepo.GetAll(ctx.Context(), 0, 1000, func(db *gorm.DB) *gorm.DB {
return db.Where("project_flock_id = ?", projectFlockID).Order("kandang_id ASC")
})
if err != nil {
s.Log.Errorf("Failed to get kandangs for project flock %d: %+v", projectFlockID, err)
return nil, nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch kandangs")
}
kandangAvailableQty := make(map[uint]float64)
for _, kandang := range kandangs {
totalQty, err := s.ProjectFlockPopulationRepo.GetTotalQtyByProjectFlockKandangID(ctx.Context(), kandang.Id)
if err != nil {
s.Log.Warnf("Failed to get total qty for kandang %d: %+v", kandang.Id, err)
kandangAvailableQty[kandang.Id] = 0
continue
}
kandangAvailableQty[kandang.Id] = totalQty
}
return pf, kandangAvailableQty, nil
}