diff --git a/internal/modules/constants/repositories/constant.repository.go b/internal/modules/constants/repositories/constant.repository.go index 493f4cb9..b9c9cc48 100644 --- a/internal/modules/constants/repositories/constant.repository.go +++ b/internal/modules/constants/repositories/constant.repository.go @@ -83,7 +83,7 @@ func (r *ConstantRepositoryImpl) GetConstants() map[string]interface{} { "KANDANG", }, "stock_log": map[string][]string{ - "log_types": []string{"TRANSFER", "ADJUSTMENT"}, + "log_types": []string{"TRANSFER", "ADJUSTMENT", "MARKETING", "CHICKIN", "PURCHASE", "RECORDING"}, "transaction_types": []string{"INCREASE", "DECREASE"}, }, "supplier_categories": []string{ diff --git a/internal/modules/production/recordings/module.go b/internal/modules/production/recordings/module.go index 71981a9e..23c97788 100644 --- a/internal/modules/production/recordings/module.go +++ b/internal/modules/production/recordings/module.go @@ -16,6 +16,7 @@ import ( rProjectFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" rRecording "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/repositories" sRecording "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/services" + 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/fifo" @@ -31,6 +32,7 @@ func (RecordingModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate projectFlockPopulationRepo := rProjectFlock.NewProjectFlockPopulationRepository(db) productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db) stockAllocationRepo := commonRepo.NewStockAllocationRepository(db) + stockLogRepo := rStockLogs.NewStockLogRepository(db) productionStandardRepo := rProductionStandard.NewProductionStandardRepository(db) productionStandardDetailRepo := rProductionStandard.NewProductionStandardDetailRepository(db) standardGrowthDetailRepo := rProductionStandard.NewStandardGrowthDetailRepository(db) @@ -113,6 +115,7 @@ func (RecordingModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate approvalRepo, approvalService, fifoService, + stockLogRepo, productionStandardService, validate, ) diff --git a/internal/modules/production/recordings/services/recording.service.go b/internal/modules/production/recordings/services/recording.service.go index a5486ab7..4465a039 100644 --- a/internal/modules/production/recordings/services/recording.service.go +++ b/internal/modules/production/recordings/services/recording.service.go @@ -13,6 +13,7 @@ import ( sProductionStandard "gitlab.com/mbugroup/lti-api.git/internal/modules/master/production-standards/services" rProjectFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/repositories" + rStockLogs "gitlab.com/mbugroup/lti-api.git/internal/modules/shared/repositories" validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/validations" "gitlab.com/mbugroup/lti-api.git/internal/utils" approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals" @@ -39,8 +40,8 @@ type RecordingService interface { } type RecordingFIFOIntegrationService interface { - ConsumeRecordingStocks(ctx context.Context, tx *gorm.DB, stocks []entity.RecordingStock) error - ReleaseRecordingStocks(ctx context.Context, tx *gorm.DB, stocks []entity.RecordingStock) error + ConsumeRecordingStocks(ctx context.Context, tx *gorm.DB, stocks []entity.RecordingStock, note string, actorID uint) error + ReleaseRecordingStocks(ctx context.Context, tx *gorm.DB, stocks []entity.RecordingStock, note string, actorID uint) error } var recordingStockUsableKey = fifo.UsableKeyRecordingStock @@ -57,6 +58,7 @@ type recordingService struct { ApprovalSvc commonSvc.ApprovalService ProductionStandardSvc sProductionStandard.ProductionStandardService FifoSvc commonSvc.FifoService + StockLogRepo rStockLogs.StockLogRepository } func NewRecordingService( @@ -67,6 +69,7 @@ func NewRecordingService( approvalRepo commonRepo.ApprovalRepository, approvalSvc commonSvc.ApprovalService, fifoSvc commonSvc.FifoService, + stockLogRepo rStockLogs.StockLogRepository, productionStandardSvc sProductionStandard.ProductionStandardService, validate *validator.Validate, ) RecordingService { @@ -81,6 +84,7 @@ func NewRecordingService( ApprovalSvc: approvalSvc, ProductionStandardSvc: productionStandardSvc, FifoSvc: fifoSvc, + StockLogRepo: stockLogRepo, } } @@ -88,12 +92,14 @@ func NewRecordingFIFOIntegrationService( repo repository.RecordingRepository, productWarehouseRepo rProductWarehouse.ProductWarehouseRepository, fifoSvc commonSvc.FifoService, + stockLogRepo rStockLogs.StockLogRepository, ) RecordingFIFOIntegrationService { return &recordingService{ Log: utils.Log, Repository: repo, ProductWarehouseRepo: productWarehouseRepo, FifoSvc: fifoSvc, + StockLogRepo: stockLogRepo, } } @@ -274,7 +280,8 @@ func (s *recordingService) CreateOne(c *fiber.Ctx, req *validation.Create) (*ent } applyStockDesiredQuantities(mappedStocks, stockDesired, s.FifoSvc != nil) - if err := s.consumeRecordingStocks(ctx, tx, mappedStocks); err != nil { + note := fmt.Sprintf("Recording-Create#%d", createdRecording.Id) + if err := s.consumeRecordingStocks(ctx, tx, mappedStocks, note, actorID); err != nil { return err } @@ -293,7 +300,8 @@ func (s *recordingService) CreateOne(c *fiber.Ctx, req *validation.Create) (*ent return err } if s.FifoSvc != nil { - if err := s.consumeRecordingDepletions(ctx, tx, mappedDepletions); err != nil { + note := fmt.Sprintf("Recording-Create#%d", createdRecording.Id) + if err := s.consumeRecordingDepletions(ctx, tx, mappedDepletions, note, actorID); err != nil { return err } } @@ -304,7 +312,8 @@ func (s *recordingService) CreateOne(c *fiber.Ctx, req *validation.Create) (*ent return err } if s.FifoSvc != nil { - if err := s.replenishRecordingEggs(ctx, tx, mappedEggs); err != nil { + note := fmt.Sprintf("Recording-Create#%d", createdRecording.Id) + if err := s.replenishRecordingEggs(ctx, tx, mappedEggs, note, actorID); err != nil { return err } } @@ -346,6 +355,10 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin } ctx := c.Context() + actorID, err := m.ActorIDFromContext(c) + if err != nil { + return nil, err + } var recordingEntity *entity.Recording var updatedRecording *entity.Recording @@ -431,14 +444,16 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin } if hasStockChanges { - if err := s.syncRecordingStocks(ctx, tx, recordingEntity.Id, existingStocks, req.Stocks); err != nil { + note := fmt.Sprintf("Recording-Edit#%d", recordingEntity.Id) + if err := s.syncRecordingStocks(ctx, tx, recordingEntity.Id, existingStocks, req.Stocks, note, actorID); err != nil { return err } } if hasDepletionChanges { if s.FifoSvc != nil { - if err := s.releaseRecordingDepletions(ctx, tx, existingDepletions); err != nil { + note := fmt.Sprintf("Recording-Edit#%d", recordingEntity.Id) + if err := s.releaseRecordingDepletions(ctx, tx, existingDepletions, note, actorID); err != nil { return err } } @@ -464,7 +479,8 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin } if s.FifoSvc != nil { - if err := s.consumeRecordingDepletions(ctx, tx, mappedDepletions); err != nil { + note := fmt.Sprintf("Recording-Edit#%d", recordingEntity.Id) + if err := s.consumeRecordingDepletions(ctx, tx, mappedDepletions, note, actorID); err != nil { return err } } @@ -480,6 +496,28 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin if err := ensureRecordingEggsUnused(existingEggs); err != nil { return err } + if s.StockLogRepo != nil { + note := fmt.Sprintf("Recording-Edit#%d", recordingEntity.Id) + logs := make([]*entity.StockLog, 0, len(existingEggs)) + for _, egg := range existingEggs { + if egg.ProductWarehouseId == 0 || egg.Qty <= 0 { + continue + } + logs = append(logs, &entity.StockLog{ + ProductWarehouseId: egg.ProductWarehouseId, + CreatedBy: actorID, + Decrease: float64(egg.Qty), + LoggableType: string(utils.StockLogTypeRecording), + LoggableId: recordingEntity.Id, + Notes: note, + }) + } + if len(logs) > 0 { + if err := s.StockLogRepo.WithTx(tx).CreateMany(ctx, logs, nil); err != nil { + return err + } + } + } if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, nil, existingEggs, nil)); err != nil { s.Log.Errorf("Failed to adjust product warehouses for eggs: %+v", err) return err @@ -498,7 +536,8 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin } if s.FifoSvc != nil { - if err := s.replenishRecordingEggs(ctx, tx, mappedEggs); err != nil { + note := fmt.Sprintf("Recording-Edit#%d", recordingEntity.Id) + if err := s.replenishRecordingEggs(ctx, tx, mappedEggs, note, actorID); err != nil { return err } } else { @@ -675,7 +714,7 @@ func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error { return err } if s.FifoSvc != nil { - if err := s.releaseRecordingDepletions(ctx, tx, oldDepletions); err != nil { + if err := s.releaseRecordingDepletions(ctx, tx, oldDepletions, "", 0); err != nil { return err } } @@ -697,7 +736,7 @@ func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error { return err } - if err := s.releaseRecordingStocks(ctx, tx, oldStocks); err != nil { + if err := s.releaseRecordingStocks(ctx, tx, oldStocks, "", 0); err != nil { return err } @@ -756,10 +795,19 @@ func (s *recordingService) ensureProductWarehousesExist(c *fiber.Ctx, stocks []v return nil } -func (s *recordingService) consumeRecordingStocks(ctx context.Context, tx *gorm.DB, stocks []entity.RecordingStock) error { +func (s *recordingService) consumeRecordingStocks( + ctx context.Context, + tx *gorm.DB, + stocks []entity.RecordingStock, + note string, + actorID uint, +) error { if len(stocks) == 0 || s.FifoSvc == nil { return nil } + if strings.TrimSpace(note) != "" && s.StockLogRepo == nil { + return errors.New("stock log repository is not available") + } for _, stock := range stocks { if stock.Id == 0 { @@ -792,15 +840,42 @@ func (s *recordingService) consumeRecordingStocks(ctx context.Context, tx *gorm. if err := s.Repository.UpdateStockUsage(tx, stock.Id, result.UsageQuantity, result.PendingQuantity); err != nil { return err } + + logDecrease := result.UsageQuantity + if result.PendingQuantity > 0 { + logDecrease += result.PendingQuantity + } + if logDecrease > 0 && strings.TrimSpace(note) != "" && actorID != 0 { + log := &entity.StockLog{ + ProductWarehouseId: stock.ProductWarehouseId, + CreatedBy: actorID, + Decrease: logDecrease, + LoggableType: string(utils.StockLogTypeRecording), + LoggableId: stock.RecordingId, + Notes: note, + } + if err := s.StockLogRepo.WithTx(tx).CreateOne(ctx, log, nil); err != nil { + return err + } + } } return nil } -func (s *recordingService) consumeRecordingDepletions(ctx context.Context, tx *gorm.DB, depletions []entity.RecordingDepletion) error { +func (s *recordingService) consumeRecordingDepletions( + ctx context.Context, + tx *gorm.DB, + depletions []entity.RecordingDepletion, + note string, + actorID uint, +) error { if len(depletions) == 0 || s.FifoSvc == nil { return nil } + if strings.TrimSpace(note) != "" && s.StockLogRepo == nil { + return errors.New("stock log repository is not available") + } for _, depletion := range depletions { if depletion.Id == 0 { @@ -832,19 +907,67 @@ func (s *recordingService) consumeRecordingDepletions(ctx context.Context, tx *g if err := s.Repository.UpdateDepletionPending(tx, depletion.Id, result.PendingQuantity); err != nil { return err } + + logDecrease := result.UsageQuantity + if result.PendingQuantity > 0 { + logDecrease += result.PendingQuantity + } + if logDecrease > 0 && strings.TrimSpace(note) != "" && actorID != 0 { + log := &entity.StockLog{ + ProductWarehouseId: sourceWarehouseID, + CreatedBy: actorID, + Decrease: logDecrease, + LoggableType: string(utils.StockLogTypeRecording), + LoggableId: depletion.RecordingId, + Notes: note, + } + if err := s.StockLogRepo.WithTx(tx).CreateOne(ctx, log, nil); err != nil { + return err + } + } + + destDelta := depletion.Qty + depletion.PendingQty + if depletion.ProductWarehouseId != 0 && destDelta > 0 && strings.TrimSpace(note) != "" && actorID != 0 { + log := &entity.StockLog{ + ProductWarehouseId: depletion.ProductWarehouseId, + CreatedBy: actorID, + Increase: destDelta, + LoggableType: string(utils.StockLogTypeRecording), + LoggableId: depletion.RecordingId, + Notes: note, + } + if err := s.StockLogRepo.WithTx(tx).CreateOne(ctx, log, nil); err != nil { + return err + } + } } return nil } -func (s *recordingService) ConsumeRecordingStocks(ctx context.Context, tx *gorm.DB, stocks []entity.RecordingStock) error { - return s.consumeRecordingStocks(ctx, tx, stocks) +func (s *recordingService) ConsumeRecordingStocks( + ctx context.Context, + tx *gorm.DB, + stocks []entity.RecordingStock, + note string, + actorID uint, +) error { + return s.consumeRecordingStocks(ctx, tx, stocks, note, actorID) } -func (s *recordingService) releaseRecordingStocks(ctx context.Context, tx *gorm.DB, stocks []entity.RecordingStock) error { +func (s *recordingService) releaseRecordingStocks( + ctx context.Context, + tx *gorm.DB, + stocks []entity.RecordingStock, + note string, + actorID uint, +) error { if len(stocks) == 0 || s.FifoSvc == nil { return nil } + if strings.TrimSpace(note) != "" && s.StockLogRepo == nil { + return errors.New("stock log repository is not available") + } for _, stock := range stocks { if stock.Id == 0 { @@ -863,15 +986,38 @@ func (s *recordingService) releaseRecordingStocks(ctx context.Context, tx *gorm. if err := s.Repository.UpdateStockUsage(tx, stock.Id, 0, 0); err != nil { return err } + + if stock.UsageQty != nil && *stock.UsageQty > 0 && strings.TrimSpace(note) != "" && actorID != 0 { + log := &entity.StockLog{ + ProductWarehouseId: stock.ProductWarehouseId, + CreatedBy: actorID, + Increase: *stock.UsageQty, + LoggableType: string(utils.StockLogTypeRecording), + LoggableId: stock.RecordingId, + Notes: note, + } + if err := s.StockLogRepo.WithTx(tx).CreateOne(ctx, log, nil); err != nil { + return err + } + } } return nil } -func (s *recordingService) releaseRecordingDepletions(ctx context.Context, tx *gorm.DB, depletions []entity.RecordingDepletion) error { +func (s *recordingService) releaseRecordingDepletions( + ctx context.Context, + tx *gorm.DB, + depletions []entity.RecordingDepletion, + note string, + actorID uint, +) error { if len(depletions) == 0 || s.FifoSvc == nil { return nil } + if strings.TrimSpace(note) != "" && s.StockLogRepo == nil { + return errors.New("stock log repository is not available") + } for _, depletion := range depletions { if depletion.Id == 0 { @@ -898,13 +1044,52 @@ func (s *recordingService) releaseRecordingDepletions(ctx context.Context, tx *g if err := s.Repository.UpdateDepletionPending(tx, depletion.Id, 0); err != nil { return err } + + logIncrease := depletion.Qty + if depletion.PendingQty > 0 { + logIncrease += depletion.PendingQty + } + if logIncrease > 0 && strings.TrimSpace(note) != "" && actorID != 0 { + log := &entity.StockLog{ + ProductWarehouseId: sourceWarehouseID, + CreatedBy: actorID, + Increase: logIncrease, + LoggableType: string(utils.StockLogTypeRecording), + LoggableId: depletion.RecordingId, + Notes: note, + } + if err := s.StockLogRepo.WithTx(tx).CreateOne(ctx, log, nil); err != nil { + return err + } + } + + destDelta := depletion.Qty + depletion.PendingQty + if depletion.ProductWarehouseId != 0 && destDelta > 0 && strings.TrimSpace(note) != "" && actorID != 0 { + log := &entity.StockLog{ + ProductWarehouseId: depletion.ProductWarehouseId, + CreatedBy: actorID, + Decrease: destDelta, + LoggableType: string(utils.StockLogTypeRecording), + LoggableId: depletion.RecordingId, + Notes: note, + } + if err := s.StockLogRepo.WithTx(tx).CreateOne(ctx, log, nil); err != nil { + return err + } + } } return nil } -func (s *recordingService) ReleaseRecordingStocks(ctx context.Context, tx *gorm.DB, stocks []entity.RecordingStock) error { - return s.releaseRecordingStocks(ctx, tx, stocks) +func (s *recordingService) ReleaseRecordingStocks( + ctx context.Context, + tx *gorm.DB, + stocks []entity.RecordingStock, + note string, + actorID uint, +) error { + return s.releaseRecordingStocks(ctx, tx, stocks, note, actorID) } func (s *recordingService) resolvePopulationWarehouseID(ctx context.Context, projectFlockKandangID uint) (uint, error) { @@ -963,27 +1148,48 @@ func (s *recordingService) adjustProductWarehouseQuantities(ctx context.Context, return s.ProductWarehouseRepo.AdjustQuantities(ctx, deltas, func(*gorm.DB) *gorm.DB { return tx }) } -func (s *recordingService) replenishRecordingEggs(ctx context.Context, tx *gorm.DB, eggs []entity.RecordingEgg) error { +func (s *recordingService) replenishRecordingEggs( + ctx context.Context, + tx *gorm.DB, + eggs []entity.RecordingEgg, + note string, + actorID uint, +) error { if len(eggs) == 0 || s.FifoSvc == nil { return nil } + if strings.TrimSpace(note) != "" && s.StockLogRepo == nil { + return errors.New("stock log repository is not available") + } for _, egg := range eggs { if egg.Id == 0 || egg.ProductWarehouseId == 0 || egg.Qty <= 0 { continue } - note := fmt.Sprintf("Recording egg #%d", egg.Id) if _, err := s.FifoSvc.Replenish(ctx, commonSvc.StockReplenishRequest{ StockableKey: fifo.StockableKeyRecordingEgg, StockableID: egg.Id, ProductWarehouseID: egg.ProductWarehouseId, Quantity: float64(egg.Qty), - Note: ¬e, Tx: tx, }); err != nil { s.Log.Errorf("Failed to replenish FIFO stock for recording egg %d: %+v", egg.Id, err) return err } + + if strings.TrimSpace(note) != "" && actorID != 0 { + log := &entity.StockLog{ + ProductWarehouseId: egg.ProductWarehouseId, + CreatedBy: actorID, + Increase: 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 @@ -1034,6 +1240,8 @@ func (s *recordingService) syncRecordingStocks( recordingID uint, existing []entity.RecordingStock, incoming []validation.Stock, + note string, + actorID uint, ) error { if s.FifoSvc == nil { if err := s.Repository.DeleteStocks(tx, recordingID); err != nil { @@ -1080,7 +1288,7 @@ func (s *recordingService) syncRecordingStocks( leftovers = append(leftovers, list...) } if len(leftovers) > 0 { - if err := s.releaseRecordingStocks(ctx, tx, leftovers); err != nil { + if err := s.releaseRecordingStocks(ctx, tx, leftovers, note, actorID); err != nil { return err } ids := make([]uint, 0, len(leftovers)) @@ -1099,7 +1307,7 @@ func (s *recordingService) syncRecordingStocks( if len(stocksToConsume) == 0 { return nil } - return s.consumeRecordingStocks(ctx, tx, stocksToConsume) + return s.consumeRecordingStocks(ctx, tx, stocksToConsume, note, actorID) } type eggTotals struct { diff --git a/internal/modules/purchases/services/purchase.service.go b/internal/modules/purchases/services/purchase.service.go index b7efbc05..6b423d33 100644 --- a/internal/modules/purchases/services/purchase.service.go +++ b/internal/modules/purchases/services/purchase.service.go @@ -18,6 +18,7 @@ import ( rSupplier "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/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" + rStockLogs "gitlab.com/mbugroup/lti-api.git/internal/modules/shared/repositories" rPurchase "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases/repositories" validation "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases/validations" "gitlab.com/mbugroup/lti-api.git/internal/utils" @@ -830,9 +831,16 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation receivingAction = entity.ApprovalActionUpdated } } + noteSuffix := "receive" + if receivingAction == entity.ApprovalActionUpdated { + noteSuffix = "edit-receive" + } + receiveNote := fmt.Sprintf("%s#%s", strings.TrimSpace(*purchase.PoNumber), noteSuffix) + transactionErr := s.PurchaseRepo.DB().WithContext(c.Context()).Transaction(func(tx *gorm.DB) error { repoTx := rPurchase.NewPurchaseRepository(tx) pwRepoTx := rProductWarehouse.NewProductWarehouseRepository(tx) + stockLogRepoTx := rStockLogs.NewStockLogRepository(tx) deltas := make(map[uint]float64) affected := make(map[uint]struct{}) @@ -849,6 +857,11 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation pwID uint qty float64 }, 0, len(prepared)) + logEntries := make([]struct { + itemID uint + pwID uint + delta float64 + }, 0, len(prepared)) for _, prep := range prepared { item := prep.item @@ -869,6 +882,13 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation newPWID = &pwID deltaQty := prep.receivedQty - item.TotalQty + if newPWID != nil && deltaQty != 0 { + logEntries = append(logEntries, struct { + itemID uint + pwID uint + delta float64 + }{itemID: item.Id, pwID: *newPWID, delta: deltaQty}) + } switch { case deltaQty > 0 && newPWID != nil: if s.FifoSvc != nil { @@ -993,6 +1013,33 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation } } + if len(logEntries) > 0 { + logs := make([]*entity.StockLog, 0, len(logEntries)) + for _, entry := range logEntries { + if entry.pwID == 0 || entry.delta == 0 { + continue + } + log := &entity.StockLog{ + ProductWarehouseId: entry.pwID, + CreatedBy: actorID, + LoggableType: string(utils.StockLogTypePurchase), + LoggableId: purchase.Id, + Notes: receiveNote, + } + if entry.delta > 0 { + log.Increase = entry.delta + } else { + log.Decrease = -entry.delta + } + logs = append(logs, log) + } + if len(logs) > 0 { + if err := stockLogRepoTx.CreateMany(c.Context(), logs, nil); err != nil { + return err + } + } + } + if len(affected) > 0 { if err := pwRepoTx.CleanupEmpty(c.Context(), affected); err != nil { return err diff --git a/internal/utils/constant.go b/internal/utils/constant.go index 7d12f5c6..d27b07ef 100644 --- a/internal/utils/constant.go +++ b/internal/utils/constant.go @@ -113,6 +113,8 @@ const ( StockLogTypeTransfer StockLogType = "TRANSFER" StockLogTypeMarketing StockLogType = "MARKETING" StockLogTypeChikin StockLogType = "CHICKIN" + StockLogTypePurchase StockLogType = "PURCHASE" + StockLogTypeRecording StockLogType = "RECORDING" ) // -------------------------------------------------------------------