mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
[FIX/BE-US] fixing stock log delete recording and purchase
This commit is contained in:
@@ -711,6 +711,11 @@ func (s recordingService) Approval(c *fiber.Ctx, req *validation.Approve) ([]ent
|
|||||||
|
|
||||||
func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||||
ctx := c.Context()
|
ctx := c.Context()
|
||||||
|
actorID, err := m.ActorIDFromContext(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
note := fmt.Sprintf("Recording-Delete#%d", id)
|
||||||
|
|
||||||
return s.Repository.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
return s.Repository.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||||
oldDepletions, err := s.Repository.ListDepletions(tx, id)
|
oldDepletions, err := s.Repository.ListDepletions(tx, id)
|
||||||
@@ -719,7 +724,7 @@ func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if s.FifoSvc != nil {
|
if s.FifoSvc != nil {
|
||||||
if err := s.releaseRecordingDepletions(ctx, tx, oldDepletions, "", 0); err != nil {
|
if err := s.releaseRecordingDepletions(ctx, tx, oldDepletions, note, actorID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -741,7 +746,7 @@ func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.releaseRecordingStocks(ctx, tx, oldStocks, "", 0); err != nil {
|
if err := s.releaseRecordingStocks(ctx, tx, oldStocks, note, actorID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -749,6 +754,10 @@ func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := s.logRecordingEggRollback(ctx, tx, oldEggs, note, actorID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.Repository.WithTx(tx).DeleteOne(ctx, id); err != nil {
|
if err := s.Repository.WithTx(tx).DeleteOne(ctx, id); err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fiber.NewError(fiber.StatusNotFound, "Recording not found")
|
return fiber.NewError(fiber.StatusNotFound, "Recording not found")
|
||||||
@@ -761,6 +770,40 @@ func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *recordingService) logRecordingEggRollback(
|
||||||
|
ctx context.Context,
|
||||||
|
tx *gorm.DB,
|
||||||
|
eggs []entity.RecordingEgg,
|
||||||
|
note string,
|
||||||
|
actorID uint,
|
||||||
|
) error {
|
||||||
|
if len(eggs) == 0 || s.StockLogRepo == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(note) == "" || actorID == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, egg := range eggs {
|
||||||
|
if egg.ProductWarehouseId == 0 || egg.Qty <= 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log := &entity.StockLog{
|
||||||
|
ProductWarehouseId: egg.ProductWarehouseId,
|
||||||
|
CreatedBy: actorID,
|
||||||
|
Decrease: float64(egg.Qty),
|
||||||
|
LoggableType: string(utils.StockLogTypeRecording),
|
||||||
|
LoggableId: egg.RecordingId,
|
||||||
|
Notes: note,
|
||||||
|
}
|
||||||
|
if err := s.StockLogRepo.WithTx(tx).CreateOne(ctx, log, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// === Persistence Helpers ===
|
// === Persistence Helpers ===
|
||||||
|
|
||||||
func (s *recordingService) ensureProductWarehousesExist(c *fiber.Ctx, stocks []validation.Stock, depletions []validation.Depletion, eggs []validation.Egg) error {
|
func (s *recordingService) ensureProductWarehousesExist(c *fiber.Ctx, stocks []validation.Stock, depletions []validation.Depletion, eggs []validation.Egg) error {
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ import (
|
|||||||
rSupplier "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/repositories"
|
rSupplier "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/repositories"
|
||||||
rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
||||||
projectFlockKandangRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
projectFlockKandangRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||||
rStockLogs "gitlab.com/mbugroup/lti-api.git/internal/modules/shared/repositories"
|
|
||||||
rPurchase "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases/repositories"
|
rPurchase "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases/repositories"
|
||||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases/validations"
|
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases/validations"
|
||||||
|
rStockLogs "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"
|
||||||
approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals"
|
approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals"
|
||||||
"gitlab.com/mbugroup/lti-api.git/internal/utils/fifo"
|
"gitlab.com/mbugroup/lti-api.git/internal/utils/fifo"
|
||||||
@@ -1256,6 +1256,10 @@ func (s *purchaseService) DeletePurchase(c *fiber.Ctx, id uint) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx := c.Context()
|
ctx := c.Context()
|
||||||
|
actorID, err := m.ActorIDFromContext(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
purchase, err := s.loadPurchase(ctx, id)
|
purchase, err := s.loadPurchase(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -1269,7 +1273,16 @@ func (s *purchaseService) DeletePurchase(c *fiber.Ctx, id uint) error {
|
|||||||
itemsToDelete[i] = item
|
itemsToDelete[i] = item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
note := fmt.Sprintf("Purchase-Delete#%d", purchase.Id)
|
||||||
|
if purchase.PoNumber != nil && strings.TrimSpace(*purchase.PoNumber) != "" {
|
||||||
|
note = fmt.Sprintf("%s#delete", strings.TrimSpace(*purchase.PoNumber))
|
||||||
|
}
|
||||||
|
|
||||||
transactionErr := s.PurchaseRepo.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
transactionErr := s.PurchaseRepo.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||||
|
if err := s.rollbackPurchaseStock(ctx, tx, itemsToDelete, note, actorID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
approvalRepoTx := commonRepo.NewApprovalRepository(tx)
|
approvalRepoTx := commonRepo.NewApprovalRepository(tx)
|
||||||
if err := approvalRepoTx.DeleteByTarget(ctx, utils.ApprovalWorkflowPurchase.String(), uint(id)); err != nil {
|
if err := approvalRepoTx.DeleteByTarget(ctx, utils.ApprovalWorkflowPurchase.String(), uint(id)); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -1305,6 +1318,91 @@ func (s *purchaseService) DeletePurchase(c *fiber.Ctx, id uint) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *purchaseService) rollbackPurchaseStock(ctx context.Context, tx *gorm.DB, items []entity.PurchaseItem, note string, actorID uint) error {
|
||||||
|
if len(items) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pwRepoTx := rProductWarehouse.NewProductWarehouseRepository(tx)
|
||||||
|
stockLogRepoTx := rStockLogs.NewStockLogRepository(tx)
|
||||||
|
deltas := make(map[uint]float64)
|
||||||
|
affected := make(map[uint]struct{})
|
||||||
|
logEntries := make([]struct {
|
||||||
|
pwID uint
|
||||||
|
qty float64
|
||||||
|
}, 0, len(items))
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
if item.ProductWarehouseId == nil || *item.ProductWarehouseId == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if item.TotalQty == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pwID := *item.ProductWarehouseId
|
||||||
|
qty := item.TotalQty
|
||||||
|
|
||||||
|
if s.FifoSvc != nil {
|
||||||
|
if err := s.FifoSvc.AdjustStockableQuantity(ctx, commonSvc.StockAdjustRequest{
|
||||||
|
StockableKey: fifo.StockableKeyPurchaseItems,
|
||||||
|
StockableID: item.Id,
|
||||||
|
ProductWarehouseID: pwID,
|
||||||
|
Quantity: -qty,
|
||||||
|
Tx: tx,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logEntries = append(logEntries, struct {
|
||||||
|
pwID uint
|
||||||
|
qty float64
|
||||||
|
}{pwID: pwID, qty: qty})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
deltas[pwID] -= qty
|
||||||
|
affected[pwID] = struct{}{}
|
||||||
|
logEntries = append(logEntries, struct {
|
||||||
|
pwID uint
|
||||||
|
qty float64
|
||||||
|
}{pwID: pwID, qty: qty})
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.FifoSvc == nil && len(deltas) > 0 {
|
||||||
|
if err := pwRepoTx.AdjustQuantities(ctx, deltas, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(affected) > 0 {
|
||||||
|
if err := pwRepoTx.CleanupEmpty(ctx, affected); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.TrimSpace(note) != "" && actorID != 0 && len(logEntries) > 0 {
|
||||||
|
logs := make([]*entity.StockLog, 0, len(logEntries))
|
||||||
|
for _, entry := range logEntries {
|
||||||
|
if entry.pwID == 0 || entry.qty <= 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
logs = append(logs, &entity.StockLog{
|
||||||
|
ProductWarehouseId: entry.pwID,
|
||||||
|
CreatedBy: actorID,
|
||||||
|
Decrease: entry.qty,
|
||||||
|
LoggableType: string(utils.StockLogTypePurchase),
|
||||||
|
LoggableId: items[0].PurchaseId,
|
||||||
|
Notes: note,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(logs) > 0 {
|
||||||
|
if err := stockLogRepoTx.CreateMany(ctx, logs, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *purchaseService) createPurchaseApproval(
|
func (s *purchaseService) createPurchaseApproval(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
db *gorm.DB,
|
db *gorm.DB,
|
||||||
|
|||||||
Reference in New Issue
Block a user