Fix adjusment stock chickin, transfer to laying and chickin

This commit is contained in:
ragilap
2026-03-08 23:31:04 +07:00
parent fca96df3d9
commit 45cc057dd4
23 changed files with 1905 additions and 525 deletions
@@ -26,6 +26,7 @@ func (AdjustmentModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validat
warehouseRepo := rWarehouse.NewWarehouseRepository(db)
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
projectFlockKandangRepo := rProjectFlockKandang.NewProjectFlockKandangRepository(db)
projectFlockPopulationRepo := rProjectFlockKandang.NewProjectFlockPopulationRepository(db)
userRepo := rUser.NewUserRepository(db)
productRepo := rproduct.NewProductRepository(db)
adjustmentStockRepo := rAdjustmentStock.NewAdjustmentStockRepository(db)
@@ -40,6 +41,7 @@ func (AdjustmentModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validat
fifoStockV2Service,
validate,
projectFlockKandangRepo,
projectFlockPopulationRepo,
)
userService := sUser.NewUserService(userRepo, validate)
@@ -11,6 +11,7 @@ import (
"github.com/gofiber/fiber/v2"
"github.com/sirupsen/logrus"
common "gitlab.com/mbugroup/lti-api.git/internal/common/service"
fifoV2 "gitlab.com/mbugroup/lti-api.git/internal/common/service/fifo_stock_v2"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
adjustmentStockRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/adjustments/repositories"
@@ -21,6 +22,7 @@ import (
projectFlockKandangRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
stockLogsRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/shared/repositories"
"gitlab.com/mbugroup/lti-api.git/internal/utils"
"gitlab.com/mbugroup/lti-api.git/internal/utils/fifo"
"gorm.io/gorm"
)
@@ -31,15 +33,16 @@ type AdjustmentService interface {
}
type adjustmentService struct {
Log *logrus.Logger
Validate *validator.Validate
StockLogsRepository stockLogsRepo.StockLogRepository
WarehouseRepo warehouseRepo.WarehouseRepository
ProductWarehouseRepo ProductWarehouse.ProductWarehouseRepository
ProductRepo productRepo.ProductRepository
ProjectFlockKandangRepo projectFlockKandangRepo.ProjectFlockKandangRepository
AdjustmentStockRepository adjustmentStockRepo.AdjustmentStockRepository
FifoStockV2Svc common.FifoStockV2Service
Log *logrus.Logger
Validate *validator.Validate
StockLogsRepository stockLogsRepo.StockLogRepository
WarehouseRepo warehouseRepo.WarehouseRepository
ProductWarehouseRepo ProductWarehouse.ProductWarehouseRepository
ProductRepo productRepo.ProductRepository
ProjectFlockKandangRepo projectFlockKandangRepo.ProjectFlockKandangRepository
ProjectFlockPopulationRepo projectFlockKandangRepo.ProjectFlockPopulationRepository
AdjustmentStockRepository adjustmentStockRepo.AdjustmentStockRepository
FifoStockV2Svc common.FifoStockV2Service
}
const (
@@ -57,17 +60,19 @@ func NewAdjustmentService(
fifoStockV2Svc common.FifoStockV2Service,
validate *validator.Validate,
projectFlockKandangRepo projectFlockKandangRepo.ProjectFlockKandangRepository,
projectFlockPopulationRepo projectFlockKandangRepo.ProjectFlockPopulationRepository,
) AdjustmentService {
return &adjustmentService{
Log: utils.Log,
Validate: validate,
StockLogsRepository: stockLogsRepo,
WarehouseRepo: warehouseRepo,
ProductWarehouseRepo: productWarehouseRepo,
ProductRepo: productRepo,
ProjectFlockKandangRepo: projectFlockKandangRepo,
AdjustmentStockRepository: adjustmentStockRepo,
FifoStockV2Svc: fifoStockV2Svc,
Log: utils.Log,
Validate: validate,
StockLogsRepository: stockLogsRepo,
WarehouseRepo: warehouseRepo,
ProductWarehouseRepo: productWarehouseRepo,
ProductRepo: productRepo,
ProjectFlockKandangRepo: projectFlockKandangRepo,
ProjectFlockPopulationRepo: projectFlockPopulationRepo,
AdjustmentStockRepository: adjustmentStockRepo,
FifoStockV2Svc: fifoStockV2Svc,
}
}
@@ -309,6 +314,22 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Failed to refresh depletion destination adjustment stock")
}
consumedPopulationQty := refreshedSource.UsageQty + refreshedSource.PendingQty
if consumedPopulationQty > 0 {
if err := s.allocatePopulationForDepletionAdjustment(
ctx,
tx,
*projectFlockKandangID,
sourcePW.Id,
refreshedSource.Id,
consumedPopulationQty,
); err != nil {
return err
}
if err := s.resyncProjectFlockPopulationUsage(ctx, tx, *projectFlockKandangID); err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Failed to resync project flock population usage")
}
}
if err := s.createAdjustmentStockLog(
ctx,
@@ -614,6 +635,98 @@ func (s *adjustmentService) createAdjustmentStockLog(
return stockLogRepo.CreateOne(ctx, newLog, nil)
}
func (s *adjustmentService) allocatePopulationForDepletionAdjustment(
ctx context.Context,
tx *gorm.DB,
projectFlockKandangID uint,
sourceProductWarehouseID uint,
adjustmentID uint,
consumeQty float64,
) error {
if consumeQty <= 0 {
return nil
}
if tx == nil {
return errors.New("transaction is required")
}
if projectFlockKandangID == 0 || sourceProductWarehouseID == 0 || adjustmentID == 0 {
return fiber.NewError(fiber.StatusBadRequest, "Invalid depletion adjustment population context")
}
if s.ProjectFlockPopulationRepo == nil {
return fiber.NewError(fiber.StatusInternalServerError, "Project flock population repository is not available")
}
popRepoTx := s.ProjectFlockPopulationRepo.WithTx(tx)
populations, err := popRepoTx.GetByProjectFlockKandangIDAndProductWarehouseID(ctx, projectFlockKandangID, sourceProductWarehouseID)
if err != nil {
return err
}
if len(populations) == 0 {
return fiber.NewError(fiber.StatusBadRequest, "Populasi tidak ditemukan untuk depletion adjustment")
}
return fifoV2.AllocatePopulationConsumption(
ctx,
tx,
populations,
sourceProductWarehouseID,
fifo.UsableKeyAdjustmentOut.String(),
adjustmentID,
consumeQty,
)
}
func (s *adjustmentService) resyncProjectFlockPopulationUsage(ctx context.Context, tx *gorm.DB, projectFlockKandangID uint) error {
if tx == nil || projectFlockKandangID == 0 {
return nil
}
idsSubquery := `
SELECT pfp.id
FROM project_flock_populations pfp
JOIN project_chickins pc ON pc.id = pfp.project_chickin_id
WHERE pc.project_flock_kandang_id = ?
`
updateWithAlloc := `
UPDATE project_flock_populations p
SET total_used_qty = COALESCE(a.used, 0)
FROM (
SELECT stockable_id, SUM(qty) AS used
FROM stock_allocations
WHERE stockable_type = 'PROJECT_FLOCK_POPULATION'
AND status = 'ACTIVE'
AND allocation_purpose = 'CONSUME'
GROUP BY stockable_id
) a
WHERE p.id = a.stockable_id
AND p.id IN (` + idsSubquery + `)
`
resetMissing := `
UPDATE project_flock_populations p
SET total_used_qty = 0
WHERE p.id IN (` + idsSubquery + `)
AND NOT EXISTS (
SELECT 1
FROM stock_allocations sa
WHERE sa.stockable_type = 'PROJECT_FLOCK_POPULATION'
AND sa.status = 'ACTIVE'
AND sa.allocation_purpose = 'CONSUME'
AND sa.stockable_id = p.id
)
`
db := tx.WithContext(ctx)
if err := db.Exec(updateWithAlloc, projectFlockKandangID).Error; err != nil {
return err
}
if err := db.Exec(resetMissing, projectFlockKandangID).Error; err != nil {
return err
}
return nil
}
func (s *adjustmentService) AdjustmentHistory(c *fiber.Ctx, query *validation.Query) ([]*entity.AdjustmentStock, int64, error) {
if err := s.Validate.Struct(query); err != nil {
return nil, 0, err