[FEAT] Add stock logging for transfer laying process and introduce new StockLogType for transfer laying

This commit is contained in:
aguhh18
2026-01-27 20:43:01 +07:00
parent 6cac4f0243
commit e503a84660
2 changed files with 44 additions and 12 deletions
@@ -650,9 +650,9 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
repoTx := s.Repository.WithTx(dbTransaction) repoTx := s.Repository.WithTx(dbTransaction)
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction)) approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
// Gunakan repo baru untuk transaction scope agar bisa akses method custom
sourceRepoTx := repository.NewLayingTransferSourceRepository(dbTransaction) sourceRepoTx := repository.NewLayingTransferSourceRepository(dbTransaction)
targetRepoTx := repository.NewLayingTransferTargetRepository(dbTransaction) targetRepoTx := repository.NewLayingTransferTargetRepository(dbTransaction)
stockLogRepoTx := rStockLogs.NewStockLogRepository(dbTransaction)
for _, approvableID := range approvableIDs { for _, approvableID := range approvableIDs {
transfer, err := repoTx.GetByID(c.Context(), approvableID, nil) transfer, err := repoTx.GetByID(c.Context(), approvableID, nil)
@@ -687,23 +687,28 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
return fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil targets transfer") return fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil targets transfer")
} }
// Hitung total quantity dari targets untuk di-consume dari sources
totalTargetQty := 0.0 totalTargetQty := 0.0
for _, target := range targets { for _, target := range targets {
totalTargetQty += target.TotalQty totalTargetQty += target.TotalQty
} }
// Consume dari laying_transfer_sources (Usable) - akan consume dari ProjectFlockPopulation (Stockable) totalSourceRequested := 0.0
for _, source := range sources {
totalSourceRequested += source.RequestedQty
}
for _, source := range sources { for _, source := range sources {
if source.ProductWarehouseId == nil { if source.ProductWarehouseId == nil {
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Source product warehouse tidak ditemukan untuk transfer %d", approvableID)) return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Source product warehouse tidak ditemukan untuk transfer %d", approvableID))
} }
sourceShare := (source.RequestedQty / totalSourceRequested) * totalTargetQty
consumeResult, err := s.FifoSvc.Consume(c.Context(), commonSvc.StockConsumeRequest{ consumeResult, err := s.FifoSvc.Consume(c.Context(), commonSvc.StockConsumeRequest{
UsableKey: fifo.UsableKeyTransferToLayingOut, UsableKey: fifo.UsableKeyTransferToLayingOut,
UsableID: source.Id, UsableID: source.Id,
ProductWarehouseID: *source.ProductWarehouseId, ProductWarehouseID: *source.ProductWarehouseId,
Quantity: totalTargetQty, Quantity: sourceShare,
AllowPending: false, AllowPending: false,
Tx: dbTransaction, Tx: dbTransaction,
}) })
@@ -717,6 +722,19 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
}, nil); err != nil { }, nil); err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Gagal update source usage qty") return fiber.NewError(fiber.StatusInternalServerError, "Gagal update source usage qty")
} }
stockLogDecrease := &entity.StockLog{
ProductWarehouseId: *source.ProductWarehouseId,
CreatedBy: actorID,
Increase: 0,
Decrease: sourceShare,
LoggableType: string(utils.StockLogTypeTransferLaying),
LoggableId: approvableID,
Notes: fmt.Sprintf("TL #%s", transfer.TransferNumber),
}
if err := stockLogRepoTx.CreateOne(c.Context(), stockLogDecrease, nil); err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Gagal membuat log stok keluar")
}
} }
for _, target := range targets { for _, target := range targets {
@@ -725,7 +743,7 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
} }
note := fmt.Sprintf("Transfer to Laying #%s", transfer.TransferNumber) note := fmt.Sprintf("Transfer to Laying #%s", transfer.TransferNumber)
replenishResult, err := s.FifoSvc.Replenish(c.Context(), commonSvc.StockReplenishRequest{ _, err := s.FifoSvc.Replenish(c.Context(), commonSvc.StockReplenishRequest{
StockableKey: fifo.StockableKeyTransferToLayingIn, StockableKey: fifo.StockableKeyTransferToLayingIn,
StockableID: target.Id, StockableID: target.Id,
ProductWarehouseID: *target.ProductWarehouseId, ProductWarehouseID: *target.ProductWarehouseId,
@@ -738,10 +756,23 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
} }
if err := targetRepoTx.PatchOne(c.Context(), target.Id, map[string]interface{}{ if err := targetRepoTx.PatchOne(c.Context(), target.Id, map[string]interface{}{
"total_qty": replenishResult.AddedQuantity, "total_qty": target.TotalQty,
}, nil); err != nil { }, nil); err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Gagal update target total qty") return fiber.NewError(fiber.StatusInternalServerError, "Gagal update target total qty")
} }
stockLogIncrease := &entity.StockLog{
ProductWarehouseId: *target.ProductWarehouseId,
CreatedBy: actorID,
Increase: target.TotalQty,
Decrease: 0,
LoggableType: string(utils.StockLogTypeTransferLaying),
LoggableId: approvableID,
Notes: fmt.Sprintf("TL #%s", transfer.TransferNumber),
}
if err := stockLogRepoTx.CreateOne(c.Context(), stockLogIncrease, nil); err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Gagal membuat log stok masuk")
}
} }
} }
} }
+7 -6
View File
@@ -109,12 +109,13 @@ const (
type StockLogType string type StockLogType string
const ( const (
StockLogTypeAdjustment StockLogType = "ADJUSTMENT" StockLogTypeAdjustment StockLogType = "ADJUSTMENT"
StockLogTypeTransfer StockLogType = "TRANSFER" StockLogTypeTransfer StockLogType = "TRANSFER"
StockLogTypeMarketing StockLogType = "MARKETING" StockLogTypeTransferLaying StockLogType = "TRANSFER_LAYING"
StockLogTypeChikin StockLogType = "CHICKIN" StockLogTypeMarketing StockLogType = "MARKETING"
StockLogTypePurchase StockLogType = "PURCHASE" StockLogTypeChikin StockLogType = "CHICKIN"
StockLogTypeRecording StockLogType = "RECORDING" StockLogTypePurchase StockLogType = "PURCHASE"
StockLogTypeRecording StockLogType = "RECORDING"
) )
// ------------------------------------------------------------------- // -------------------------------------------------------------------