using System.Text.Json; using System.Text.Json.Serialization; using Server.Model; namespace Server.Data { public static class InvoiceData { #region Private Properties private static string DirectoryName => "Invoices"; #endregion #region Public Method DeleteAsync /// /// Deletes an invoice file asynchronously by its ID. /// /// The ID of the invoice to be deleted. /// A task representing the asynchronous delete operation. public static async Task DeleteAsync(string invoiceId) { var fileName = await BuildFileName(invoiceId); if (File.Exists(fileName)) File.Delete(fileName); } #endregion #region Public Method ExistsAsync /// /// Checks if an invoice file exists asynchronously by its ID. /// /// The ID of the invoice to check for existence. /// A task representing the asynchronous check operation, with a boolean result indicating whether the file exists. public static async Task ExistsAsync(string invoiceId) => File.Exists(await BuildFileName(invoiceId)); #endregion #region Public Method LoadAllAsync /// /// Loads all invoices asynchronously. /// /// A task representing the asynchronous operation, with a list of as the result. public static async Task> LoadAllAsync() { var invoices = new List(); var invoiceFiles = Directory.GetFiles(await GetDirectoryAsync(), "Invoice_*.json"); foreach (var file in invoiceFiles) { var invoice = await LoadFileAsync(file); if (invoice != null) invoices.Add(invoice); } return invoices; } #endregion #region Public Method LoadAsync /// /// Loads an invoice asynchronously by its ID. /// /// The ID of the invoice to be loaded. /// The deserialized instance if the file exists; otherwise, null. public static async Task LoadAsync(string invoiceId) { var fileName = await BuildFileName(invoiceId); return await LoadFileAsync(fileName); } #endregion #region Public Method SaveAsync /// /// Saves an invoice asynchronously. /// /// The invoice model to be saved. /// A task representing the asynchronous save operation. public static async Task SaveAsync(InvoiceModel invoice) { // Ensure id is set if (string.IsNullOrWhiteSpace(invoice.InvoiceId)) invoice.InvoiceId = Guid.NewGuid().ToString(); var jsonString = JsonSerializer.Serialize(invoice, new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }); await File.WriteAllTextAsync(await BuildFileName(invoice.InvoiceId), jsonString); } #endregion #region Private Method BuildFileName private static async Task BuildFileName(string invoiceId) { var targetDirectory = await GetDirectoryAsync(); return Path.Combine(targetDirectory, $"Invoice_{invoiceId}.json"); } #endregion #region Private Method LoadFileAsync private static async Task LoadFileAsync(string fileName) { if (!File.Exists(fileName)) return null; var jsonString = await File.ReadAllTextAsync(fileName); return JsonSerializer.Deserialize(jsonString)!; } #endregion /// /// Ensures that the directory for storing invoices exists asynchronously. /// /// A task representing the asynchronous operation to ensure the directory exists. private static Task GetDirectoryAsync() { var parentDirectory = Directory.GetParent(Directory.GetCurrentDirectory()); if (parentDirectory == null) return Task.FromResult(string.Empty); var targetDirectory = Path.Combine(parentDirectory.FullName, DirectoryName); if(!Directory.Exists(targetDirectory)) Directory.CreateDirectory(targetDirectory); return Task.FromResult(targetDirectory); } } }