minor refactor

This commit is contained in:
Mguy13 2023-01-06 16:08:26 +01:00
parent 5366b11f55
commit 0ee2be969f
6 changed files with 138 additions and 136 deletions

View File

@ -1,6 +1,5 @@
using Configuration;
using DTO;
using static Configuration.DemoApplicationConfiguration;
using DTO;
using static Configuration.ApplicationConfigurationService;
namespace OrderParser
{
@ -10,11 +9,12 @@ namespace OrderParser
{
try
{
var filesInfoConfig = DemoApplicationConfiguration.InitializeFrom(args);
var csvFileWriter = new CsvFileWriter(filesInfoConfig.OutputFile);
var filesInfoConfig = Configuration.ApplicationConfigurationService.InitializeFrom(args);
var csvFileWriter = new CsvFileWriterService(filesInfoConfig.OutputFile);
foreach (var jsonFile in filesInfoConfig.JsonFilesInfo)
{
// Could have easily been another service, but only do that when it needs to be scaled.
var orderDTO = Newtonsoft.Json.JsonConvert.DeserializeObject<OrderDto>(File.ReadAllText(jsonFile.FullName));
var orderModel = new OrderModel(orderDTO);

View File

@ -9,6 +9,8 @@
## Infrastructure disclaimer
I come from a background of developing mobile applications in Dart/Flutter, with a different set of conventions (such for file naming etc). I have done some research into doing it and tried sticking to it. But in the end, the architecture is still heavily influenced by practices in mobile development.
Additionally, I haven't focussed too much on Exception handling, since I feel that the scope of this assignment, is just a simple PoC. I do have some basic safeguards for input validation, and basic exception printing.
### Structure
#### Assets
@ -19,8 +21,8 @@ There ae 2 JSON files in the `assets` directory. These can be used as input as c
2. [OrderModel](models/OrderModel.cs): Captures the usable part of the `OrderDTO` that will be written out to the CSV.
#### Services
1. [DemoApplicationConfiguration](services/DemoApplicationConfiguration.cs): Stores the configuration that the program ran with. Such as the command-line args passed (and hence the mode), the actual input data, and the ouput destination. Along with the file-existnece checks
2. [CsvWriter](services/CsvWriter.cs): Writes an order to a file.
1. [ApplicationConfigurationService](services/ApplicationConfigurationService.cs): Stores the configuration that the program ran with. Such as the command-line args passed (and hence the mode), the actual input data, and the ouput destination. Along with the file-existnece checks
2. [CsvWriterService](services/CsvWriterService.cs): Writes an order to a file.
3. Deserializing the JSON was handled by a package. Could have made this into a service ideally, for better scaling up.
#### Packages used

View File

@ -12,7 +12,7 @@
"ProductId": "PID4",
"Description": "pid4 description",
"Amount": 2.5,
"price": 169.0
"price": 69.0
}
]
}

244
review.cs
View File

@ -1,144 +1,144 @@
using SollicitantReview.Models;
using SollicitantReview.Services;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
// using SollicitantReview.Models;
// using SollicitantReview.Services;
// using Microsoft.Extensions.Options;
// using System;
// using System.Collections.Generic;
// using System.IO;
// using System.Linq;
// using System.Text;
// using System.Threading;
// using System.Threading.Tasks;
namespace SollicitantReview
{
public class SollicitantReview
{
private SollicitantReviewSettings options;
private IWriter writer;
private Queue<List<ReviewExportLine>> exportLineQueue;
// namespace SollicitantReview
// {
// public class SollicitantReview
// {
// private SollicitantReviewSettings options;
// private IWriter writer;
// private Queue<List<ReviewExportLine>> exportLineQueue;
public SollicitantReview(IOptions<SollicitantReviewSettings> options, IWriter writer)
{
this.options = options.Value;
this.writer = writer;
this.exportLineQueue = new Queue<List<ReviewExportLine>>();
// public SollicitantReview(IOptions<SollicitantReviewSettings> options, IWriter writer)
// {
// this.options = options.Value;
// this.writer = writer;
// this.exportLineQueue = new Queue<List<ReviewExportLine>>();
var processExportLinesThread = new Thread(new ThreadStart(ProcessReviewExportLines));
processExportLinesThread.Start();
}
// var processExportLinesThread = new Thread(new ThreadStart(ProcessReviewExportLines));
// processExportLinesThread.Start();
// }
public void RegisterOrder(Order order)
{
DeleteOrder(order);
exportLineQueue.Enqueue(ConvertOrderToExportLines(order));
}
// public void RegisterOrder(Order order)
// {
// DeleteOrder(order);
// exportLineQueue.Enqueue(ConvertOrderToExportLines(order));
// }
private string FilterString(string value)
{
return value.Replace(";", ":");
}
// private string FilterString(string value)
// {
// return value.Replace(";", ":");
// }
private void DeleteOrder(Order order)
{
var exportLines = new List<ReviewExportLine>()
{
new ReviewExportLine()
{
Type = "9",
OrderNumber = FilterString(order.OrderNumber),
Amount = "1",
UserId = FilterString(order.User),
JournalPostIndication = "Y"
}
};
// private void DeleteOrder(Order order)
// {
// var exportLines = new List<ReviewExportLine>()
// {
// new ReviewExportLine()
// {
// Type = "9",
// OrderNumber = FilterString(order.OrderNumber),
// Amount = "1",
// UserId = FilterString(order.User),
// JournalPostIndication = "Y"
// }
// };
exportLineQueue.Enqueue(exportLines);
}
// exportLineQueue.Enqueue(exportLines);
// }
private List<ReviewExportLine> ConvertOrderToExportLines(Order order, string userId = null)
{
var exportLines = new List<ReviewExportLine>();
// private List<ReviewExportLine> ConvertOrderToExportLines(Order order, string userId = null)
// {
// var exportLines = new List<ReviewExportLine>();
foreach (var orderLine in order.OrderLines)
{
exportLines.Add(new ReviewExportLine()
{
OrderNumber = FilterString(order.OrderNumber),
Name = FilterString(orderLine.Name),
Amount = FilterString(orderLine.Amount),
ProductNumber = FilterString(orderLine.Number),
ProductDescription = FilterString(orderLine.Description),
UserId = userId == null ? FilterString(order.User) : userId,
Location = FilterString(orderLine.Location),
JournalPostIndication = "Y"
});
}
// foreach (var orderLine in order.OrderLines)
// {
// exportLines.Add(new ReviewExportLine()
// {
// OrderNumber = FilterString(order.OrderNumber),
// Name = FilterString(orderLine.Name),
// Amount = FilterString(orderLine.Amount),
// ProductNumber = FilterString(orderLine.Number),
// ProductDescription = FilterString(orderLine.Description),
// UserId = userId == null ? FilterString(order.User) : userId,
// Location = FilterString(orderLine.Location),
// JournalPostIndication = "Y"
// });
// }
return exportLines;
}
// return exportLines;
// }
private void ProcessReviewExportLines()
{
while(true)
{
if (exportLineQueue.Any() && IsFolderEmpty(options.ReviewFolderPath))
{
var exportLines = exportLineQueue.Dequeue();
var randomStringLength = 7;
// private void ProcessReviewExportLines()
// {
// while(true)
// {
// if (exportLineQueue.Any() && IsFolderEmpty(options.ReviewFolderPath))
// {
// var exportLines = exportLineQueue.Dequeue();
// var randomStringLength = 7;
writer.OpenFile($"{options.ReviewFolderPath}\\{GenerateRandomString(randomStringLength)}.txt");
// writer.OpenFile($"{options.ReviewFolderPath}\\{GenerateRandomString(randomStringLength)}.txt");
foreach (var exportLine in exportLines)
{
writer.WriteLine($"{exportLine.Type};" +
$"{exportLine.OrderNumber};" +
$"{exportLine.Name};" +
$"{exportLine.Amount};" +
$"{exportLine.ProductNumber};" +
$"{exportLine.ProductDescription};" +
$"{exportLine.UserId};" +
$"{exportLine.Location};" +
$"{exportLine.JournalPostIndication};" +
$"{exportLine.Info2}");
}
// foreach (var exportLine in exportLines)
// {
// writer.WriteLine($"{exportLine.Type};" +
// $"{exportLine.OrderNumber};" +
// $"{exportLine.Name};" +
// $"{exportLine.Amount};" +
// $"{exportLine.ProductNumber};" +
// $"{exportLine.ProductDescription};" +
// $"{exportLine.UserId};" +
// $"{exportLine.Location};" +
// $"{exportLine.JournalPostIndication};" +
// $"{exportLine.Info2}");
// }
writer.CloseFile();
}
// writer.CloseFile();
// }
Thread.Sleep(2000);
}
}
// Thread.Sleep(2000);
// }
// }
private bool IsFolderEmpty(string path)
{
DirectoryInfo dirInfo = new DirectoryInfo(path);
// private bool IsFolderEmpty(string path)
// {
// DirectoryInfo dirInfo = new DirectoryInfo(path);
if (!dirInfo.Exists)
{
throw new CouldNotFindReviewDirectory();
}
// if (!dirInfo.Exists)
// {
// throw new CouldNotFindReviewDirectory();
// }
return !dirInfo.GetFiles("*.txt").Any();
}
// return !dirInfo.GetFiles("*.txt").Any();
// }
private string GenerateRandomString(int length)
{
StringBuilder stringBuilder = new StringBuilder();
Random random = new Random();
var ASCIIOffset = 65;
var ASCIIRange = 25;
// private string GenerateRandomString(int length)
// {
// StringBuilder stringBuilder = new StringBuilder();
// Random random = new Random();
// var ASCIIOffset = 65;
// var ASCIIRange = 25;
char letter;
// char letter;
for (int i = 0; i < length; i++)
{
double randomDouble = random.NextDouble();
int shift = Convert.ToInt32(Math.Floor(ASCIIRange * randomDouble));
letter = Convert.ToChar(shift + ASCIIOffset);
stringBuilder.Append(letter);
}
// for (int i = 0; i < length; i++)
// {
// double randomDouble = random.NextDouble();
// int shift = Convert.ToInt32(Math.Floor(ASCIIRange * randomDouble));
// letter = Convert.ToChar(shift + ASCIIOffset);
// stringBuilder.Append(letter);
// }
return stringBuilder.ToString();
}
}
}
// return stringBuilder.ToString();
// }
// }
// }

View File

@ -1,6 +1,6 @@
namespace Configuration
{
public sealed class DemoApplicationConfiguration
public sealed class ApplicationConfigurationService
{
private FileInfo[] jsonFiles;
public FileInfo[] JsonFilesInfo
@ -22,7 +22,7 @@ namespace Configuration
}
}
public static DemoApplicationConfiguration InitializeFrom(string[] args)
public static ApplicationConfigurationService InitializeFrom(string[] args)
{
if (args.Length < 3)
throw new DemoApplicationConfigurationException("Must have atleast: 1 flag, 1 path, 1 output filename");
@ -41,14 +41,14 @@ namespace Configuration
// Assert only a single 'd' was passed
if ( givenFlags.Length == 1 && givenFlags[0].Equals("-d") ) {
string[] filesInDirectory = Directory.GetFiles(givenFilePaths[0]);
return new DemoApplicationConfiguration {
return new ApplicationConfigurationService {
OutputFile = outputFileName,
JsonFilesInfo = filesInDirectory.Select(name => new FileInfo(name)).ToArray(),
};
}
// Assert only '-f' were passed
else if (givenFlags.All((string flag) => flag.Equals("-f"))) {
return new DemoApplicationConfiguration {
return new ApplicationConfigurationService {
OutputFile = outputFileName,
JsonFilesInfo = givenFilePaths.Select(name => new FileInfo(name)).ToArray(),
};

View File

@ -1,12 +1,12 @@
using System.Globalization;
using CsvHelper;
class CsvFileWriter
class CsvFileWriterService
{
private TextWriter textWriter;
private CsvWriter csvWriter;
public CsvFileWriter(FileInfo fileInfo) {
public CsvFileWriterService(FileInfo fileInfo) {
textWriter = new StreamWriter(fileInfo.FullName);
csvWriter = new CsvWriter(textWriter, CultureInfo.InvariantCulture);