package commands import ( "context" "fmt" "autostore/internal/application/interfaces" "autostore/internal/domain/specifications" ) type HandleExpiredItemsCommand struct { itemRepo interfaces.IItemRepository orderService interfaces.IOrderService timeProvider interfaces.ITimeProvider expirationSpec *specifications.ItemExpirationSpec logger interfaces.ILogger } func NewHandleExpiredItemsCommand( itemRepo interfaces.IItemRepository, orderService interfaces.IOrderService, timeProvider interfaces.ITimeProvider, expirationSpec *specifications.ItemExpirationSpec, logger interfaces.ILogger, ) *HandleExpiredItemsCommand { return &HandleExpiredItemsCommand{ itemRepo: itemRepo, orderService: orderService, timeProvider: timeProvider, expirationSpec: expirationSpec, logger: logger, } } func (c *HandleExpiredItemsCommand) Execute(ctx context.Context) error { c.logger.Info(ctx, "Starting expired items processing") currentTime := c.timeProvider.Now() expirationSpec := c.expirationSpec.GetSpec(currentTime) expiredItems, err := c.itemRepo.FindWhere(ctx, expirationSpec) if err != nil { c.logger.Error(ctx, "Failed to find expired items", "error", err) return fmt.Errorf("failed to find expired items: %w", err) } c.logger.Info(ctx, "Found expired items", "count", len(expiredItems)) for _, item := range expiredItems { c.logger.Info(ctx, "Processing expired item", "item_id", item.GetID().String(), "item_name", item.GetName()) if err := c.orderService.OrderItem(ctx, item); err != nil { c.logger.Error(ctx, "Failed to order replacement item", "item_id", item.GetID().String(), "error", err) continue } if err := c.itemRepo.Delete(ctx, item.GetID()); err != nil { c.logger.Error(ctx, "Failed to delete expired item", "item_id", item.GetID().String(), "error", err) return fmt.Errorf("failed to delete expired item %s: %w", item.GetID().String(), err) } c.logger.Info(ctx, "Successfully processed expired item", "item_id", item.GetID().String()) } c.logger.Info(ctx, "Completed expired items processing", "processed_count", len(expiredItems)) return nil }