namespace Supermarket; public abstract class Product { public const char Separator = ';'; public const string Invalid = "Invalid!"; protected Product(string productName, string barcode, int quantity) { if (string.IsNullOrWhiteSpace(productName)) { productName = Invalid; } ProductName = productName; Barcode = IsBarcodeValid(barcode) ? barcode : Invalid; Quantity = quantity > 0 ? quantity : 0; } public string ProductName { get; } public string Barcode { get; } public int Quantity { get; } protected virtual string[] CsvColumnNames => [nameof(Barcode), nameof(ProductName), nameof(Quantity)]; protected virtual string[] CsvColumnValues => [Barcode, ProductName, Quantity.ToString()]; public string GetCsvHeader() { string header = String.Empty; for (var i = 0; i < CsvColumnNames.Length; i++) { string columnName = CsvColumnNames[i]; if(i == CsvColumnNames.Length - 1) { header += $"{columnName}"; break; } header += $"{columnName}{Separator}"; } return header; } public string ToCsv() => ToCsvLine(CsvColumnValues, Separator); protected static string ToCsvLine(string[] values, char separator) { string line = string.Empty; for (var i = 0; i < values.Length; i++) { string value = values[i]; if (i == values.Length - 1) { line += $"{value}"; break; } line += $"{value}{separator}"; } return line; } public static bool IsBarcodeValid(string? barcode) { if (barcode == null) { return false; } if(barcode.Length is > 8 or < 8) { return false; } const int evenWeight = 3; const int oddWeight = 1; int weight = 0; for (int i = 0; i < barcode.Length; i++) { if (!char.IsDigit(barcode[i])) { return false; } // Skip check digit if (i == 7) { break; } int digit = int.Parse(barcode[i].ToString()); weight += i % 2 == 0 ? digit * evenWeight : digit * oddWeight; } int calculatedCheckDigit = 10 - (weight % 10); if (calculatedCheckDigit == 10) { calculatedCheckDigit = 0; } return calculatedCheckDigit == int.Parse(barcode[^1].ToString()); } protected static T[] AppendToArray(T[] existingArray, params T[] newValues) { // we are allowed to use Lists, so why not? :) List result = new(existingArray.Length + newValues.Length); result.AddRange(existingArray); result.AddRange(newValues); return result.ToArray(); } }