diff --git a/internal/modules/production/recordings/services/recording.service.go b/internal/modules/production/recordings/services/recording.service.go index 5264e32a..3f0e7946 100644 --- a/internal/modules/production/recordings/services/recording.service.go +++ b/internal/modules/production/recordings/services/recording.service.go @@ -3121,6 +3121,12 @@ func (s *recordingService) reflowSyncRecordingStocks( existingByWarehouse[stock.ProductWarehouseId] = append(existingByWarehouse[stock.ProductWarehouseId], stock) } + shouldWriteLog := shouldWriteRecordingStockLog(note, actorID) + if shouldWriteLog && s.StockLogRepo == nil { + return errors.New("stock log repository is not available") + } + resetLogState := newRecordingStockLogState() + stocksToApply := make([]entity.RecordingStock, 0, len(incoming)) for _, item := range incoming { list := existingByWarehouse[item.ProductWarehouseId] @@ -3128,6 +3134,25 @@ func (s *recordingService) reflowSyncRecordingStocks( if len(list) > 0 { stock = list[0] existingByWarehouse[item.ProductWarehouseId] = list[1:] + + // Write reset (increase) stock_log for the OLD consumption BEFORE overwriting UsageQty. + // FIFO internally does Rollback+Reallocate inside reflowApplyRecordingStocks, but the + // corresponding +increase stock_log for the rollback step was previously missing, causing + // stock_log.stock to drift below the true FIFO qty on every in-place edit. + rollbackQty := recordingStockRollbackQty(stock) + if rollbackQty > 1e-6 && shouldWriteLog { + resetLog := &entity.StockLog{ + ProductWarehouseId: stock.ProductWarehouseId, + CreatedBy: actorID, + Increase: rollbackQty, + LoggableType: string(utils.StockLogTypeRecording), + LoggableId: stock.RecordingId, + Notes: note, + } + if err := s.appendRecordingStockLog(ctx, tx, resetLogState, resetLog); err != nil { + return err + } + } } else { zero := 0.0 stock = entity.RecordingStock{