private void ShowPage(IQueryable <Asset> assets, int pageSize, int pageIndex) { IEnumerable <Asset> page = assets.Skip(pageSize * pageIndex).Take(pageSize).ToList(); foreach (Asset a in page) { IConsoleOutput.Color color = IConsoleOutput.Color.WHITE; if (a.ExpiryDate < DateTime.Now || a.ExpiryDate < DateTime.Now.AddMonths(3)) // Passed expiry date or 3 months left { color = IConsoleOutput.Color.RED; } else if (a.ExpiryDate < DateTime.Now.AddMonths(6)) { color = IConsoleOutput.Color.YELLOW; } OutputHandle.PutMessage( a.AssetID.ToString().PadRight(IndexdPad) + a.ModelName.PadRight(Pad) + a.PurchaseDate.ToShortDateString().PadRight(Pad) + a.ExpiryDate.ToShortDateString().PadRight(Pad) + //a.Price.ToString().PadRight(pricePad) + CurrencyConverter.PriceToString(a.Price, Offices.GetOffice(a.OfficeID).OfficeLocalCulture).PadRight(Pad) + Offices.GetOffice(a.OfficeID).ToString().PadRight(Pad), color, newLine: false); switch (a) { case Computer computer: OutputHandle.PutMessage( computer.OperatingSystem.PadRight(Pad) + computer.RAM.PadRight(Pad) + computer.Processor.PadRight(Pad), color); break; case Cellphone phone: OutputHandle.PutMessage( phone.PhoneOperator.PadRight(Pad) + phone.PhoneNumber.PadRight(Pad), color); break; } } }
public bool DeleteAssetCommand(string cmdName, string[] cmdArgs) { OutputHandle.PutMessage("Enter the id of the asset you wish to delete."); int id = 0; while (!int.TryParse(InputHandle.GetEditableInputWithDefaultText(), out id)) { OutputHandle.PutMessage("Please enter a valid number.", IConsoleOutput.Color.YELLOW); } if (Assets.GetAsset(id) == null) { OutputHandle.PutMessage("The provided id does not exist in the system.", IConsoleOutput.Color.YELLOW); return(false); } Assets.DeleteAsset(id); return(true); }
/// <summary> /// Generates some basic reports about the system. /// <returns></returns> public bool GenerateReport(string cmdName, string[] cmdArgs) { int assetCount = Assets.Count; int numExpiredAssets = Assets.GetAssets(a => a.ExpiryDate < DateTime.Now).Count(); int numAssetsOlderThanFiveYears = Assets.GetAssets(a => a.PurchaseDate.AddYears(5) < DateTime.Now).Count(); int numAssetsExpireThreeMonths = Assets.GetAssets(a => a.ExpiryDate > DateTime.Now && a.ExpiryDate < DateTime.Now.AddMonths(3)).Count(); int numAssetsExpireSixMonths = Assets.GetAssets(a => !(a.ExpiryDate < DateTime.Now || a.ExpiryDate < DateTime.Now.AddMonths(3)) && a.ExpiryDate < DateTime.Now.AddMonths(6)).Count(); OutputHandle.PutMessage("Statistics:"); OutputHandle.PutMessage($"A total of {assetCount} assets are being tracked."); OutputHandle.PutMessage($"{numExpiredAssets} assets are past their exiry date."); OutputHandle.PutMessage($"{numAssetsExpireThreeMonths} assets have expired or will expire within 3 months."); OutputHandle.PutMessage($"{numAssetsExpireSixMonths} assets will expire within 6 months."); OutputHandle.PutMessage($"{numAssetsOlderThanFiveYears} assets are older than 5 years."); return(true); }
private bool ListFiltered(Expression <Func <Asset, bool> > predicate) { if (Assets.Count == 0) { OutputHandle.PutMessage("No assets in database.", IConsoleOutput.Color.GREEN); return(true); } var query = Assets.GetQueriable() .Where(predicate) //.OrderBy(a => Offices.GetOffice(a.OfficeID).Location) .OrderBy(a => a.OfficeID) .ThenBy(a => a.PurchaseDate); // Used when scrolling int pageSize = 20; int totalPageNum = query.Count() / pageSize; // Is there no better way than executing the query here? int currentPageIndex = 0; OutputHandle.PutMessage("Enter a number to go to that page. Type 'up' or 'down' to scroll up or down.", IConsoleOutput.Color.GREEN); OutputHandle.PutMessage("Type anything else to exit.", IConsoleOutput.Color.GREEN); // Header OutputHandle.PutMessage( "Id".PadRight(IndexdPad) + "Model".PadRight(Pad) + "Purchase Date".PadRight(Pad) + "Expiry Date".PadRight(Pad) + "Price".PadRight(Pad) + "Office Location".PadRight(Pad) + "Other info ...".PadRight(Pad)); ShowPage(query, pageSize, currentPageIndex); // Let user scroll up or down among the pages // Loop until user is finished string input = ""; bool notDone = true; while (notDone) { OutputHandle.PutMessage($"Displaying page {currentPageIndex + 1} of {totalPageNum}."); input = InputHandle.GetEditableInputWithDefaultText(currentPageIndex == 0 ? "down" : "").ToLower(); if (input == "down") { if (currentPageIndex + 1 >= totalPageNum) { OutputHandle.PutMessage("No more assets.", IConsoleOutput.Color.GREEN); } else { currentPageIndex++; ShowPage(query, pageSize, currentPageIndex); } } else if (input == "up") { if (currentPageIndex == 0) { OutputHandle.PutMessage("You are already at the top page.", IConsoleOutput.Color.YELLOW); } else { currentPageIndex--; ShowPage(query, pageSize, currentPageIndex); } } else if (int.TryParse(input, out int userSelectedPage)) { if (userSelectedPage > 0 && userSelectedPage <= totalPageNum) { currentPageIndex = userSelectedPage - 1; // index is zero-based, but index in ui is not ShowPage(query, pageSize, currentPageIndex); } else { OutputHandle.PutMessage("Invalid page.", IConsoleOutput.Color.YELLOW); } } else { OutputHandle.PutMessage("Aborted."); notDone = false; } } return(true); }
/// <summary> /// Implementation of the 'add' command. Current usage: /// add Computer /// add Cellphone /// </summary> public bool AddAssetCommand(string cmdName, string[] cmdArgs) { Dictionary <string, string> parameters = new Dictionary <string, string>(); // Type of asset string type; if (cmdArgs.Length > 0 && cmdArgs[0].ToLower() == "computer") { type = "Computer"; } else if (cmdArgs.Length > 0 && cmdArgs[0].ToLower() == "cellphone") { type = "Cellphone"; } else { OutputHandle.PutMessage("Usage: 'add computer' or 'add cellphone'.", IConsoleOutput.Color.YELLOW); OutputHandle.PutMessage("Note that these are the only assets that are implemented in this iteration."); return(false); } parameters["Type"] = type; // Logic to get location OutputHandle.PutMessage("In which country is the office located?"); Office office = Offices.GetOffice(InputHandle.GetEditableInputWithDefaultText()); while (office == null) { OutputHandle.PutMessage("Unknown country, please try again.", IConsoleOutput.Color.RED); OutputHandle.PutMessage("Available options: "); foreach (Office o in Offices.GetOffices()) { OutputHandle.PutMessage(o.Location); } office = Offices.GetOffice(InputHandle.GetEditableInputWithDefaultText()); } OutputHandle.PutMessage($"Location set: {office}."); OutputHandle.PutMessage(""); parameters["OfficeID"] = office.OfficeID.ToString(); // Purchase date OutputHandle.PutMessage("Enter date of purchase. The date should be in local time."); DateTime purchaseDate; while (!DateTime.TryParse(InputHandle.GetEditableInputWithDefaultText(), out purchaseDate)) { OutputHandle.PutMessage("Please enter a valid date.", IConsoleOutput.Color.RED); } parameters["PurchaseDate"] = purchaseDate.ToString(); // Expiry date DateTime expiryDate = purchaseDate.AddYears(3); OutputHandle.PutMessage($"The expiry date has been calculated to: {expiryDate.ToShortDateString()} (local time)."); parameters["ExpiryDate"] = expiryDate.ToString(); // Price double price = -1; OutputHandle.PutMessage("Enter purchase price of asset, in USD."); while (!double.TryParse(InputHandle.GetEditableInputWithDefaultText(), out price) || price < 0) { if (price < 0) { OutputHandle.PutMessage("Price must not be less than 0.", IConsoleOutput.Color.RED); } else { OutputHandle.PutMessage("Please enter a valid number.", IConsoleOutput.Color.RED); } } parameters["Price"] = price.ToString(); // Model name OutputHandle.PutMessage("Enter model name."); string name = InputHandle.GetEditableInputWithDefaultText(); while (string.IsNullOrEmpty(name) || string.IsNullOrWhiteSpace(name)) { OutputHandle.PutMessage("Name is blank. Please enter a valid model name.", IConsoleOutput.Color.RED); name = InputHandle.GetEditableInputWithDefaultText(); } parameters["ModelName"] = name; // Read type-specific data if (type == "Computer") { // OS OutputHandle.PutMessage("Please enter the OS of the computer."); string os = InputHandle.GetEditableInputWithDefaultText().Trim(); while (string.IsNullOrEmpty(os)) { OutputHandle.PutMessage("Name cannot be blank.", IConsoleOutput.Color.RED); os = InputHandle.GetEditableInputWithDefaultText().Trim(); } parameters["OS"] = os; // RAM OutputHandle.PutMessage("Please enter the amount of RAM in the computer."); string RAM = InputHandle.GetEditableInputWithDefaultText().Trim(); while (string.IsNullOrEmpty(RAM)) { OutputHandle.PutMessage("Name cannot be blank.", IConsoleOutput.Color.RED); RAM = InputHandle.GetEditableInputWithDefaultText().Trim(); } parameters["RAM"] = RAM; // Processor OutputHandle.PutMessage("Please enter the processor."); string processor = InputHandle.GetEditableInputWithDefaultText().Trim(); while (string.IsNullOrEmpty(processor)) { OutputHandle.PutMessage("Name cannot be blank.", IConsoleOutput.Color.RED); processor = InputHandle.GetEditableInputWithDefaultText().Trim(); } parameters["Processor"] = processor; } else // Cellphone { // Operator OutputHandle.PutMessage("Please enter the name of the phone operator."); string phoneOperator = InputHandle.GetEditableInputWithDefaultText().Trim(); while (string.IsNullOrEmpty(phoneOperator)) { OutputHandle.PutMessage("Name cannot be blank.", IConsoleOutput.Color.RED); phoneOperator = InputHandle.GetEditableInputWithDefaultText().Trim(); } parameters["PhoneOperator"] = phoneOperator; // Phone number OutputHandle.PutMessage("Please enter the phone number."); string phoneNumber = InputHandle.GetEditableInputWithDefaultText().Trim(); while (string.IsNullOrEmpty(phoneNumber)) { OutputHandle.PutMessage("Name cannot be blank.", IConsoleOutput.Color.RED); phoneNumber = InputHandle.GetEditableInputWithDefaultText().Trim(); } parameters["PhoneNumber"] = phoneNumber; } try { Assets.AddAsset(parameters); } catch (Exception e) { OutputHandle.PutMessage(e.Message); } OutputHandle.PutMessage("Asset added to the system successfully."); return(true); }
public bool UpdateAssetCommand(string cmdName, string[] cmdArgs) { OutputHandle.PutMessage("Enter the id of the asset you wish to modify."); int id = 0; while (!int.TryParse(InputHandle.GetEditableInputWithDefaultText(), out id)) { OutputHandle.PutMessage("Please enter a valid number.", IConsoleOutput.Color.YELLOW); } Asset changeTarget = Assets.GetAsset(id); // We will make changes to this object, and then transfer them to the original object // after validation. If the user entered something wrong, we can revert to the old state // by simply discarding this object. // This method seems to be the simplest when using the reflection-based approach, since we // do not know the order in which the properties will be presented to the user. Asset tmpCopy = changeTarget.ShallowCopy(); PropertyInfo[] properties = tmpCopy.GetType().GetProperties(); foreach (var property in properties) { if (property.Name != "AssetID") // We don't want the user changing the id! { OutputHandle.PutMessage("Enter a new '" + property.Name + "' or press return to keep the existing value."); // This could probably be written nicer without code duplication ... if (property.PropertyType == typeof(string)) { string newValue = InputHandle.GetEditableInputWithDefaultText(property.GetValue(changeTarget).ToString()); while (string.IsNullOrEmpty(newValue)) { OutputHandle.PutMessage("Please enter a valid string.", IConsoleOutput.Color.YELLOW); } property.SetValue(tmpCopy, newValue); } else if (property.PropertyType == typeof(int)) { int newValue = 0; while (!int.TryParse( InputHandle.GetEditableInputWithDefaultText(property.GetValue(changeTarget).ToString()), out newValue)) { OutputHandle.PutMessage("Please enter a valid number.", IConsoleOutput.Color.YELLOW); } property.SetValue(tmpCopy, newValue); } else if (property.PropertyType == typeof(double)) { double newValue = 0; while (!double.TryParse( InputHandle.GetEditableInputWithDefaultText(property.GetValue(changeTarget).ToString()), out newValue)) { OutputHandle.PutMessage("Please enter a valid number.", IConsoleOutput.Color.YELLOW); } property.SetValue(tmpCopy, newValue); } else if (property.PropertyType == typeof(DateTime)) { DateTime newValue; while (!DateTime.TryParse( InputHandle.GetEditableInputWithDefaultText(property.GetValue(changeTarget).ToString()), out newValue)) { OutputHandle.PutMessage("Please enter a valid Date.", IConsoleOutput.Color.YELLOW); } property.SetValue(tmpCopy, newValue); } else { throw new InvalidOperationException("Unknown type error: " + property.Name); } } } // Now check that the dates and prices are correct if (tmpCopy.Price < 0) { OutputHandle.PutMessage("Error: The price must not be negative.", IConsoleOutput.Color.RED); return(false); } else if (tmpCopy.ExpiryDate < tmpCopy.PurchaseDate) { OutputHandle.PutMessage("Error: Expiry date cannot come after purchase date.", IConsoleOutput.Color.RED); return(false); } else if (DateTime.Now < tmpCopy.PurchaseDate) { OutputHandle.PutMessage("Error: The specified purchase date is in the future. The asset tracker is not a list of things to buy!", IConsoleOutput.Color.RED); return(false); } else if (Offices.GetOffice(tmpCopy.OfficeID) == null) { OutputHandle.PutMessage($"Error: An office with the specified id does not exist: {tmpCopy.OfficeID}.", IConsoleOutput.Color.RED); return(false); } else // If we get here things should be OK, we can now save changes { foreach (var property in properties) { if (property.Name != "AssetID") { property.SetValue(changeTarget, property.GetValue(tmpCopy)); } } Assets.UpdateAsset(changeTarget); OutputHandle.PutMessage("Changes saved."); return(true); } }