mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-25 07:45:44 +00:00
FIX[BE]: fixing bug transfer to laying, delet biaya, nominal expesen e, chickin
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/transfer_layings/repositories"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/transfer_layings/validations"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils/fifo"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
@@ -45,6 +46,7 @@ type transferLayingService struct {
|
||||
ProductWarehouseRepo rInventory.ProductWarehouseRepository
|
||||
WarehouseRepo rWarehouse.WarehouseRepository
|
||||
ApprovalService commonSvc.ApprovalService
|
||||
FifoSvc commonSvc.FifoService
|
||||
}
|
||||
|
||||
func NewTransferLayingService(
|
||||
@@ -55,6 +57,7 @@ func NewTransferLayingService(
|
||||
productWarehouseRepo rInventory.ProductWarehouseRepository,
|
||||
warehouseRepo rWarehouse.WarehouseRepository,
|
||||
approvalService commonSvc.ApprovalService,
|
||||
fifoSvc commonSvc.FifoService,
|
||||
validate *validator.Validate,
|
||||
) TransferLayingService {
|
||||
return &transferLayingService{
|
||||
@@ -67,6 +70,7 @@ func NewTransferLayingService(
|
||||
ProductWarehouseRepo: productWarehouseRepo,
|
||||
WarehouseRepo: warehouseRepo,
|
||||
ApprovalService: approvalService,
|
||||
FifoSvc: fifoSvc,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,15 +272,20 @@ func (s *transferLayingService) CreateOne(c *fiber.Ctx, req *validation.Create)
|
||||
CreatedBy: actorID,
|
||||
}
|
||||
|
||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||
if len(sourceWarehouseMap) > 0 {
|
||||
for _, pwID := range sourceWarehouseMap {
|
||||
createBody.ProductWarehouseId = &pwID
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Repository.WithTx(dbTransaction).CreateOne(c.Context(), createBody, nil); err != nil {
|
||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||
repoTx := s.Repository.WithTx(dbTransaction)
|
||||
|
||||
if err := repoTx.CreateOne(c.Context(), createBody, nil); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create transfer laying record")
|
||||
}
|
||||
|
||||
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
||||
projectFlockPopulationRepoTx := s.ProjectFlockPopulationRepo.WithTx(dbTransaction)
|
||||
|
||||
for _, sourceDetail := range req.SourceKandangs {
|
||||
productWarehouseId := sourceWarehouseMap[sourceDetail.ProjectFlockKandangId]
|
||||
|
||||
@@ -290,13 +299,6 @@ func (s *transferLayingService) CreateOne(c *fiber.Ctx, req *validation.Create)
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create transfer source")
|
||||
}
|
||||
|
||||
if err := s.reduceProjectFlockPopulation(c.Context(), projectFlockPopulationRepoTx, sourceDetail.ProjectFlockKandangId, sourceDetail.Quantity); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to reduce project flock population")
|
||||
}
|
||||
|
||||
if err := productWarehouseRepoTx.PatchOne(c.Context(), productWarehouseId, map[string]any{"qty": gorm.Expr("qty - ?", sourceDetail.Quantity)}, nil); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update source warehouse quantity")
|
||||
}
|
||||
}
|
||||
|
||||
for _, targetDetail := range req.TargetKandangs {
|
||||
@@ -325,6 +327,22 @@ func (s *transferLayingService) CreateOne(c *fiber.Ctx, req *validation.Create)
|
||||
}
|
||||
}
|
||||
|
||||
// Set DestProductWarehouseID untuk STOCKABLE role (ambil dari target pertama)
|
||||
if len(req.TargetKandangs) > 0 {
|
||||
firstTargetPWID := req.TargetKandangs[0].ProjectFlockKandangId
|
||||
// Cari ProductWarehouse untuk target kandang
|
||||
targetWarehouse, _ := s.WarehouseRepo.GetLatestByKandangID(c.Context(), firstTargetPWID)
|
||||
if targetWarehouse != nil {
|
||||
// Query ProductWarehouse by warehouse and kandang
|
||||
var targetPW entity.ProductWarehouse
|
||||
err := dbTransaction.Where("warehouse_id = ? AND project_flock_kandang_id = ?", targetWarehouse.Id, firstTargetPWID).
|
||||
First(&targetPW).Error
|
||||
if err == nil {
|
||||
createBody.DestProductWarehouseID = &targetPW.Id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := createApprovalTransferLaying(c.Context(), dbTransaction, createBody.Id, createBody.CreatedBy); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create transfer approval")
|
||||
}
|
||||
@@ -339,7 +357,7 @@ func (s *transferLayingService) CreateOne(c *fiber.Ctx, req *validation.Create)
|
||||
return s.GetOne(c, createBody.Id)
|
||||
}
|
||||
|
||||
func (s transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint) (*entity.LayingTransfer, error) {
|
||||
func (s *transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint) (*entity.LayingTransfer, error) {
|
||||
if err := s.Validate.Struct(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -381,6 +399,7 @@ func (s transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update, i
|
||||
}
|
||||
|
||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||
repoTx := s.Repository.WithTx(dbTransaction)
|
||||
projectFlockPopulationRepoTx := s.ProjectFlockPopulationRepo.WithTx(dbTransaction)
|
||||
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
||||
|
||||
@@ -416,7 +435,7 @@ func (s transferLayingService) UpdateOne(c *fiber.Ctx, req *validation.Update, i
|
||||
totalSourceQty += source.Quantity
|
||||
}
|
||||
|
||||
if err := s.Repository.WithTx(dbTransaction).PatchOne(c.Context(), id, map[string]any{
|
||||
if err := repoTx.PatchOne(c.Context(), id, map[string]any{
|
||||
"transfer_date": transferDate,
|
||||
"notes": req.Reason,
|
||||
"pending_usage_qty": &totalSourceQty,
|
||||
@@ -531,8 +550,9 @@ func (s transferLayingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
}
|
||||
}
|
||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||
|
||||
repoTx := s.Repository.WithTx(dbTransaction)
|
||||
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
||||
projectFlockPopulationRepoTx := s.ProjectFlockPopulationRepo.WithTx(dbTransaction)
|
||||
|
||||
sourceRepoTx := repository.NewLayingTransferSourceRepository(dbTransaction)
|
||||
sources, err := sourceRepoTx.GetByLayingTransferId(c.Context(), id)
|
||||
@@ -551,7 +571,6 @@ func (s transferLayingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
}
|
||||
}
|
||||
|
||||
projectFlockPopulationRepoTx := s.ProjectFlockPopulationRepo.WithTx(dbTransaction)
|
||||
for _, source := range sources {
|
||||
populations, err := projectFlockPopulationRepoTx.GetByProjectFlockKandangID(c.Context(), source.SourceProjectFlockKandangId)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -575,7 +594,7 @@ func (s transferLayingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Repository.WithTx(dbTransaction).DeleteOne(c.Context(), id); err != nil {
|
||||
if err := repoTx.DeleteOne(c.Context(), id); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to delete transfer laying")
|
||||
}
|
||||
|
||||
@@ -624,14 +643,13 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
|
||||
}
|
||||
|
||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||
|
||||
repoTx := s.Repository.WithTx(dbTransaction)
|
||||
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
||||
sourceRepoTx := repository.NewLayingTransferSourceRepository(dbTransaction)
|
||||
targetRepoTx := repository.NewLayingTransferTargetRepository(dbTransaction)
|
||||
productWarehouseRepoTx := s.ProductWarehouseRepo.WithTx(dbTransaction)
|
||||
|
||||
for _, approvableID := range approvableIDs {
|
||||
transfer, err := s.Repository.GetByID(c.Context(), approvableID, nil)
|
||||
transfer, err := repoTx.GetByID(c.Context(), approvableID, nil)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("TransferLaying %d not found", approvableID))
|
||||
@@ -664,44 +682,45 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
|
||||
}
|
||||
|
||||
if len(sources) > 0 && len(targets) > 0 {
|
||||
firstSource := sources[0]
|
||||
if firstSource.ProductWarehouseId == nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Source product warehouse not found for transfer %d", approvableID))
|
||||
}
|
||||
|
||||
sourceWarehouse, err := productWarehouseRepoTx.GetByID(c.Context(), *firstSource.ProductWarehouseId, nil)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get source warehouse")
|
||||
}
|
||||
|
||||
for _, target := range targets {
|
||||
|
||||
targetPFK, err := s.ProjectFlockKandangRepo.GetByID(c.Context(), target.TargetProjectFlockKandangId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
continue
|
||||
}
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get target project flock kandang")
|
||||
for _, source := range sources {
|
||||
if source.ProductWarehouseId == nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Source product warehouse not found for transfer %d", approvableID))
|
||||
}
|
||||
|
||||
targetWarehouse, err := s.WarehouseRepo.GetLatestByKandangID(c.Context(), targetPFK.KandangId)
|
||||
_, err := s.FifoSvc.Consume(c.Context(), commonSvc.StockConsumeRequest{
|
||||
UsableKey: fifo.UsableKeyTransferToLaying,
|
||||
UsableID: approvableID,
|
||||
ProductWarehouseID: *source.ProductWarehouseId,
|
||||
Quantity: source.Qty,
|
||||
AllowPending: false,
|
||||
Tx: dbTransaction,
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
continue
|
||||
}
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to get target warehouse")
|
||||
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to consume FIFO stock for source %d: %v", source.ProductWarehouseId, err))
|
||||
}
|
||||
}
|
||||
|
||||
if transfer.DestProductWarehouseID != nil {
|
||||
note := fmt.Sprintf("Transfer to Laying #%s", transfer.TransferNumber)
|
||||
replenishResult, err := s.FifoSvc.Replenish(c.Context(), commonSvc.StockReplenishRequest{
|
||||
StockableKey: fifo.StockableKeyTransferToLaying,
|
||||
StockableID: approvableID,
|
||||
ProductWarehouseID: *transfer.DestProductWarehouseID,
|
||||
Quantity: *transfer.PendingUsageQty,
|
||||
Note: ¬e,
|
||||
Tx: dbTransaction,
|
||||
})
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to replenish stock to destination warehouse: %v", err))
|
||||
}
|
||||
|
||||
if _, err := s.getOrCreateProductWarehouse(
|
||||
c.Context(),
|
||||
dbTransaction,
|
||||
sourceWarehouse.ProductId,
|
||||
targetWarehouse.Id,
|
||||
target.Qty,
|
||||
actorID,
|
||||
&target.TargetProjectFlockKandangId, // Set flock ID agar bisa di-chickin di target flock
|
||||
); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to create or update product warehouse")
|
||||
if err := dbTransaction.Model(&entity.LayingTransfer{}).
|
||||
Where("id = ?", approvableID).
|
||||
Updates(map[string]interface{}{
|
||||
"total_qty": replenishResult.AddedQuantity,
|
||||
}).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update total quantity for transfer")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -709,9 +728,10 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
|
||||
usageQty := *transfer.PendingUsageQty
|
||||
updateData := map[string]any{
|
||||
"usage_qty": usageQty,
|
||||
"total_qty": usageQty, // Same as usage_qty for initial transfer
|
||||
"pending_usage_qty": nil,
|
||||
}
|
||||
if err := s.Repository.WithTx(dbTransaction).PatchOne(c.Context(), approvableID, updateData, nil); err != nil {
|
||||
if err := repoTx.PatchOne(c.Context(), approvableID, updateData, nil); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update transfer laying status")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user