/// <summary> /// Extracts expense data from a block of text /// </summary> /// <param name="text">Text to process</param> /// <param name="cancellationToken">Default cancellation token</param> /// <returns></returns> public async Task <ExpenseResourceModel> ExtractExpenseAsync(string text, CancellationToken cancellationToken = default) { ExpenseResourceModel resourceModel = new ExpenseResourceModel(); await Task.Run(() => { if (string.IsNullOrEmpty(text)) { throw new EmailProcessingException("Text block can not be empty"); } // Load the email text as html doc HtmlDocument htmlDocument = new HtmlDocument(); htmlDocument.LoadHtml(text); // Detect tags that are not closed if (htmlDocument.ContainsUnclosedTags()) { throw new UnclosedTagException("Block of text has unclosed tag(s)"); } // Extract data HtmlNode expenseNode = htmlDocument.DocumentNode.SelectSingleNode("//expense"); if (expenseNode == null) { throw new EmailProcessingException("Expense element does not exist or is invalid"); } if (expenseNode.HasChildNodes) { HtmlNode costCentre = expenseNode.SelectSingleNode("//cost_centre"); HtmlNode total = expenseNode.SelectSingleNode("//total"); HtmlNode paymentMethod = expenseNode.SelectSingleNode("//payment_method"); if (total == null) { throw new MissingElementException("Total node is required"); } decimal totalValue = decimal.Parse(total.InnerText, CultureInfo.InvariantCulture); resourceModel.CostCentre = costCentre != null ? costCentre.InnerText : "UNKNOWN"; resourceModel.Total = totalValue; resourceModel.PaymentMethod = paymentMethod.InnerText; resourceModel.TotalExcludingGST = FinancialCalculations.CalculateTotalNetFromTotalGross(totalValue); resourceModel.GSTValue = FinancialCalculations.CalculateGSTValueFromTotalGross(totalValue); } }, cancellationToken); return(resourceModel); }
public async Task Service_Get_ExpenseResourceModel() { // Arrange string text = FakeDataHelper.EmailProcessing.CorrectExpenseTextBlock; // Act ExpenseResourceModel model = await EmailProcessingService.ExtractExpenseAsync(text); // Assert Assert.IsNotNull(model); Assert.AreEqual("DEV002", model.CostCentre); Assert.AreEqual(1024.01m, model.Total); Assert.AreEqual(890.44m, model.TotalExcludingGST); Assert.AreEqual(133.57m, model.GSTValue); Assert.AreEqual("personal card", model.PaymentMethod); }
public async Task Controller_Get_ExpenseResourceModel_No_CostCentre() { // Arrange string text = FakeDataHelper.EmailProcessing.MissingCostCentreExpenseTextBlock; // Act IActionResult result = await EmailProcessingController.Expense1_0(text); // Assert ExpenseResourceModel model = ((OkObjectResult)result).Value as ExpenseResourceModel; Assert.IsNotNull(model); Assert.AreEqual("UNKNOWN", model.CostCentre); Assert.AreEqual(1024.01m, model.Total); Assert.AreEqual(890.44m, model.TotalExcludingGST); Assert.AreEqual(133.57m, model.GSTValue); Assert.AreEqual("personal card", model.PaymentMethod); }