namespace Supermarket; public abstract class Product { public const char Separator = ';'; public const string Invalid = "Invalid!"; /// /// The constructor of Product /// /// The product name /// The bar code /// The quantity 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; } /// /// The product name /// public string ProductName { get; } /// /// The bar code of the product /// public string Barcode { get; } /// /// The quantity of the product /// public int Quantity { get; } /// /// The CSV column names /// protected virtual string[] CsvColumnNames => [nameof(Barcode), nameof(ProductName), nameof(Quantity)]; /// /// The CSV column values /// protected virtual string[] CsvColumnValues => [Barcode, ProductName, Quantity.ToString()]; /// /// The CSV header /// /// The formatted CSV header public string GetCsvHeader() => string.Join(Separator, CsvColumnNames); /// /// The CSV line /// /// The formatted CSV line with values public string ToCsv() => ToCsvLine(CsvColumnValues, Separator); /// /// The CSV line generator /// /// The values /// The separator /// The formatted CSV line protected static string ToCsvLine(string[] values, char separator) => String.Join(separator, values); /// /// Checks if the bar code is valid /// /// The bar code to check /// True if the bar code is valid, false otherwise 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()); } /// /// Appends new values to an existing array /// /// The array to append to /// The array of values to append /// The type /// The complete array 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(); } }