namespace qdr.app.studiou.orders2printpack.EmailStorage { /// /// Helper class for working with email items and their file operations. /// Provides a convenient wrapper around MetadataItem with additional functionality /// for file system operations, validation, and state management. /// public class EmailItem { #region Private Fields /// /// The underlying metadata item containing email and processing information /// private readonly MetadataItem _metadata; /// /// Base directory path where email item directories are located /// private readonly string _basePath; #endregion #region Constructor /// /// Initializes a new instance of the EmailItem class /// /// The metadata item containing email information /// Base directory path for file operations /// Thrown when metadata or basePath is null public EmailItem(MetadataItem metadata, string basePath) { _metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); _basePath = basePath ?? throw new ArgumentNullException(nameof(basePath)); } #endregion #region Public Properties /// /// Gets the underlying metadata item /// public MetadataItem Metadata => _metadata; /// /// Gets the full directory path for this email item /// Combines the base path with the directory name from metadata /// public string DirectoryPath => Path.Combine(_basePath, _metadata.DirectoryName); /// /// Gets a value indicating whether the directory exists on the file system /// public bool DirectoryExists => Directory.Exists(DirectoryPath); /// /// Gets all JPG files in the email item's directory /// Returns an empty enumerable if the directory doesn't exist /// public IEnumerable JpgFiles => DirectoryExists ? Directory.GetFiles(DirectoryPath, "*.jpg") : Enumerable.Empty(); /// /// Gets the count of JPG files in the directory /// public int FileCount => JpgFiles.Count(); /// /// Gets the total size in bytes of all JPG files in the directory /// public long TotalFileSize => JpgFiles.Sum(f => new FileInfo(f).Length); /// /// Gets a value indicating whether this item is ready for processing /// Checks that the state is Ready, directory exists, and contains files /// public bool IsReadyForProcessing => _metadata.State == EmailStateEnum.Ready && DirectoryExists && FileCount > 0; /// /// Gets a value indicating whether this item can be reset /// Items cannot be reset while they are being processed or uploaded /// public bool CanBeReset => _metadata.State != EmailStateEnum.Processing && _metadata.State != EmailStateEnum.Uploading; /// /// Gets the normalized filename for the recipient (safe for file system) /// Replaces @ with _at_ and . with _dot_ to create filesystem-safe names /// public string NormalizedRecipient => _metadata.EmailAddress.Replace("@", "_at_").Replace(".", "_dot_"); #endregion #region Public Methods /// /// Generates the zip filename for this item based on recipient and timestamp /// /// Optional timestamp to use, defaults to current time /// A formatted zip filename in the format: studioufoto_{recipient}_{timestamp}.zip public string GenerateZipFileName(DateTime? timestamp = null) => $"studioufoto_{NormalizedRecipient}_{(timestamp ?? DateTime.Now):yyyyMMdd_HHmmss}.zip"; /// /// Validates that the item is in a consistent state for processing /// /// A tuple containing validation result and list of issues found public (bool IsValid, List Issues) Validate() { var issues = new List(); // Check required email address if (string.IsNullOrEmpty(_metadata.EmailAddress)) issues.Add("Email address is required"); // Check directory and files existence if (!DirectoryExists) issues.Add($"Directory does not exist: {DirectoryPath}"); else if (FileCount == 0) issues.Add("No JPG files found in directory"); // Check required email content if (string.IsNullOrEmpty(_metadata.Subject)) issues.Add("Email subject is required"); if (string.IsNullOrEmpty(_metadata.Body)) issues.Add("Email body is required"); return (issues.Count == 0, issues); } /// /// Gets a summary of the item for display purposes /// Includes recipient, file count, current state, and associated orders /// /// A formatted summary string public string GetSummary() => $"{_metadata.EmailAddress} - {FileCount} files, {_metadata.State}, Orders: {_metadata.Orders}"; #endregion } }