Skip to content

Commit

Permalink
change report to parsing column name
Browse files Browse the repository at this point in the history
  • Loading branch information
abuzuhri committed Mar 2, 2022
1 parent b54e5fe commit 43c0d2f
Show file tree
Hide file tree
Showing 6 changed files with 548 additions and 25 deletions.
4 changes: 1 addition & 3 deletions Source/FikaAmazonAPI.SampleCode/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ static async Task Main(string[] args)
IsActiveLimitRate = true
});



ReportManager reportManager2 = new ReportManager(amazonConnection);
var products2 = await reportManager2.GetProductsAsync(); //GET_MERCHANT_LISTINGS_ALL_DATA
var products2 = await reportManager2.GetReturnFBAOrderAsync(3); //GET_MERCHANT_LISTINGS_ALL_DATA


ParameterOrderList serachOrderList = new ParameterOrderList();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace FikaAmazonAPI.ReportGeneration.ReportDataTable
{
public static class RowExtensionMethods
{
public static string GetString(this TableRow row, string id)
{
return AValueWithThisIdExists(row, id)
? row[id]
: null;
}
public static int GetInt32(this TableRow row, string id)
{
return AValueWithThisIdExists(row, id) && TheValueIsNotEmpty(row, id)
? Convert.ToInt32(row[id])
: int.MinValue;
}
public static long GetInt64(this TableRow row, string id)
{
return AValueWithThisIdExists(row, id) && TheValueIsNotEmpty(row, id)
? Convert.ToInt64(row[id])
: long.MinValue;
}
public static decimal GetDecimal(this TableRow row, string id)
{
return AValueWithThisIdExists(row, id) && TheValueIsNotEmpty(row, id)
? Convert.ToDecimal(row[id])
: decimal.MinValue;
}
public static DateTime GetDateTime(this TableRow row, string id)
{
return AValueWithThisIdExists(row, id) && TheValueIsNotEmpty(row, id)
? Convert.ToDateTime(row[id])
: DateTime.MinValue;
}
public static bool GetBoolean(this TableRow row, string id)
{
if (TheBooleanValueIsEmpty(row, id))
return false;

AssertThatTheRequestIsValid(row, id);

return string.Equals(row[id], "true", StringComparison.OrdinalIgnoreCase);
}
private static void AssertThatTheRequestIsValid(TableRow row, string id)
{
AssertThatAValueWithThisIdExistsInThisRow(row, id);
AssertThatThisIsAnAcceptableBoolValue(row, id);
}
private static void AssertThatThisIsAnAcceptableBoolValue(TableRow row, string id)
{
var acceptedValues = new[] { "true", "false" };
if (acceptedValues.Contains(row[id], StringComparer.OrdinalIgnoreCase) == false)
throw new InvalidCastException($"You must use 'true' or 'false' when setting bools for {id}");
}

private static void AssertThatAValueWithThisIdExistsInThisRow(TableRow row, string id)
{
if (AValueWithThisIdExists(row, id) == false)
throw new InvalidOperationException($"{id} could not be found in the row.");
}
private static bool TheBooleanValueIsEmpty(TableRow row, string id)
{
return AValueWithThisIdExists(row, id) && string.IsNullOrEmpty(row[id]);
}

public static float GetSingle(this TableRow row, string id)
{
return AValueWithThisIdExists(row, id) && TheValueIsNotEmpty(row, id)
? Convert.ToSingle(row[id])
: float.MinValue;
}
public static char GetChar(this TableRow row, string id)
{
return Convert.ToChar(row[id]);
}
public static T GetDiscreteEnum<T>(this TableRow row, string id) where T : struct, IConvertible
{
var value = row[id].Replace(" ", string.Empty);
T @enum;
if (Enum.TryParse(value, true, out @enum))
return @enum;

throw new InvalidOperationException($"No enum with value {value} found in enum {typeof(T).Name}");
}
public static T GetDiscreteEnum<T>(this TableRow row, string id, T defaultValue) where T : struct, IConvertible
{
var value = row[id].Replace(" ", string.Empty);
T @enum;
return Enum.TryParse(value, true, out @enum) ? @enum : defaultValue;
}
public static TEnum GetEnumValue<TEnum>(this TableRow row, string id)
{
return (TEnum)Enum.Parse(typeof(TEnum), row[id]);
}
public static Enum GetEnum<T>(this TableRow row, string id) where T : class
{
return GetTheEnumValue<T>(row[id], id);
}
private static Enum GetTheEnumValue<T>(string rowValue, string propertyName) where T : class
{
var value = rowValue.Replace(" ", string.Empty);

var enumType = GetTheEnumType<T>(propertyName, value);

return Enum.Parse(enumType, value, true) as Enum;
}

private static Type GetTheEnumType<T>(string propertyName, string value)
{
var propertyType = (from property in typeof(T).GetProperties()
where property.Name == propertyName
&& property.PropertyType.IsEnum
&& EnumValueIsDefinedCaseInsensitve(property.PropertyType, value)
select property.PropertyType).FirstOrDefault();

if (propertyType == null)
throw new InvalidOperationException($"No enum with value {value} found in type {typeof(T).Name}");

return propertyType;
}
private static bool EnumValueIsDefinedCaseInsensitve(Type @enum, string value)
{
Enum parsedEnum = null;
try
{
parsedEnum = Enum.Parse(@enum, value, true) as Enum;
}
catch
{
// just catch it
}

return parsedEnum != null;
}
public static Guid GetGuid(this TableRow row, string id)
{
return AValueWithThisIdExists(row, id) && TheValueIsNotEmpty(row, id)
? new Guid(row[id])
: new Guid();
}
public static double GetDouble(this TableRow row, string id)
{
return AValueWithThisIdExists(row, id) && TheValueIsNotEmpty(row, id)
? Convert.ToDouble(row[id])
: double.MinValue;
}
private static bool AValueWithThisIdExists(IEnumerable<KeyValuePair<string, string>> row, string id)
{
return row.Any(x => x.Key == id);
}
private static bool TheValueIsNotEmpty(TableRow row, string id)
{
return string.IsNullOrEmpty(row[id]) == false;
}
}
}
179 changes: 179 additions & 0 deletions Source/FikaAmazonAPI/ReportGeneration/ReportDataTable/Table.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace FikaAmazonAPI.ReportGeneration.ReportDataTable
{
public class Table
{
internal const string ERROR_NO_CELLS_TO_ADD = "No cells to add";
internal const string ERROR_NO_HEADER_TO_ADD = "No headers to add";
internal const string ERROR_COLUMN_NAME_NOT_FOUND = "Could not find a column named '{0}' in the table.";
internal const string ERROR_CELLS_NOT_MATCHING_HEADERS = "The number of cells ({0}) you are trying to add doesn't match the number of columns ({1})";

private readonly string[] header;
private readonly TableRows rows = new TableRows();

public ICollection<string> Header
{
get { return header; }
}

public TableRows Rows
{
get { return rows; }
}

public int RowCount
{
get { return rows.Count; }
}

public Table(params string[] header)
{

if (header == null || header.Length == 0)
{
throw new ArgumentException(ERROR_NO_HEADER_TO_ADD, "header");
}
for (int colIndex = 0; colIndex < header.Length; colIndex++)
header[colIndex] = header[colIndex] ?? string.Empty;
this.header = header;
}

public static Table ConvertFromCSV(string path, char separator = '\t')
{
var lines = File.ReadAllLines(path);

var table = new Table(lines.First().Split(separator));


lines.Skip(1).ToList().ForEach(a => ConvertFromCSVAddRow(table, a, separator));
return table;
}
private static void ConvertFromCSVAddRow(Table table, string line, char separator)
{
table.AddRow(line.Split(separator));
}
public bool ContainsColumn(string column)
{
return GetHeaderIndex(column, false) >= 0;
}

internal int GetHeaderIndex(string column, bool throwIfNotFound = true)
{
int index = Array.IndexOf(header, column);
if (!throwIfNotFound)
return index;
if (index < 0)
{
var mess = string.Format(
ERROR_COLUMN_NAME_NOT_FOUND + "\nThe table looks like this:\n{1}",
column,
this);
throw new IndexOutOfRangeException(mess);
}
return index;
}

public void AddRow(IDictionary<string, string> values)
{
string[] cells = new string[header.Length];
foreach (var value in values)
{
int headerIndex = GetHeaderIndex(value.Key);
cells[headerIndex] = value.Value;
}

AddRow(cells);
}

public void AddRow(params string[] cells)
{
if (cells == null)
throw new Exception(ERROR_NO_CELLS_TO_ADD);

if (cells.Length != header.Length)
{
var mess =
string.Format(
ERROR_CELLS_NOT_MATCHING_HEADERS + ".\nThe table looks like this\n{2}",
cells.Length,
header.Length,
this);
throw new ArgumentException(mess);
}
var row = new TableRow(this, cells);
rows.Add(row);
}

public void RenameColumn(string oldColumn, string newColumn)
{
int colIndex = GetHeaderIndex(oldColumn);
header[colIndex] = newColumn;
}

public override string ToString()
{
return ToString(false, true);
}

public string ToString(bool headersOnly = false, bool withNewline = true)
{
int[] columnWidths = new int[header.Length];
for (int colIndex = 0; colIndex < header.Length; colIndex++)
columnWidths[colIndex] = header[colIndex].Length;

if (!headersOnly)
{
foreach (TableRow row in rows)
{
for (int colIndex = 0; colIndex < header.Length; colIndex++)
columnWidths[colIndex] = Math.Max(columnWidths[colIndex], row[colIndex].Length);
}
}

StringBuilder builder = new StringBuilder();
AddTableRow(builder, header, columnWidths);

if (!headersOnly)
{
foreach (TableRow row in rows)
AddTableRow(builder, row.Select(pair => pair.Value), columnWidths);
}

if (!withNewline)
{
var newlineLength = Environment.NewLine.Length;
builder.Remove(builder.Length - newlineLength, newlineLength);
}

return builder.ToString();
}

private void AddTableRow(StringBuilder builder, IEnumerable<string> cells, int[] widths)
{
const string margin = " ";
const string separator = "|";
int colIndex = 0;

builder.Append(separator);
foreach (string cell in cells)
{
builder.Append(margin);

builder.Append(cell);
builder.Append(' ', widths[colIndex] - cell.Length);

builder.Append(margin);
builder.Append(separator);

colIndex++;
}

builder.AppendLine();
}
}
}
Loading

0 comments on commit 43c0d2f

Please sign in to comment.