0% found this document useful (0 votes)
39 views11 pages

Read This

The document describes steps to create a console application to manage product sales. It involves creating classes like Product, Sale, Menu and MenuBank to represent products, sales, application menus and menu banks. Methods are added to Program class to initialize sample products, simulate menu selection and perform actions like view, create, search and delete sales. The application provides a menu driven interface to manage product sales data using these classes.

Uploaded by

koklola18
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views11 pages

Read This

The document describes steps to create a console application to manage product sales. It involves creating classes like Product, Sale, Menu and MenuBank to represent products, sales, application menus and menu banks. Methods are added to Program class to initialize sample products, simulate menu selection and perform actions like view, create, search and delete sales. The application provides a menu driven interface to manage product sales data using these classes.

Uploaded by

koklola18
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Lab17-Managing Product Sales

Create an console application to manage product sellings.

Step 1: Creating Project

Creating a console project named “SellingProducts”, the source file “Program.cs” might be coded as follow:
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}

Step 2: Modifying Program (1)

Adding static methods: ViewSales, CreateSales, SearchSales, DeleteSales, and ExitProgram in the class Program.
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}

private static void ViewSales()


{
Console.WriteLine();
Console.WriteLine("[Viewing Sales]");
}

private static void CreateSales()


{
Console.WriteLine();
Console.WriteLine("[Creating Sales]");
}

private static void SearchSales()


{
Console.WriteLine();
Console.WriteLine("[Searching Sales]");
}

private static void DeleteSales()


{
Console.WriteLine();
Console.WriteLine("[Deleting Sales]");
}

static void ExitProgram()


{
Environment.Exit(0);
}

Step 3: Creating a new class

 Creating a new class, Menu, presenting a menu with a text and action to perform operation. The source file,
Menu.cs is coded as follow:
public class Menu
{
public string Text { get; set; }
public Action Action { get; set; }
}

 Creating a new class, MenuBank, presenting a bank of menues to display for user to select. The source file,
MenuBank.cs is coded as follow:
public class MenuBank
{
public string Title { get; set; } = "";
public List<Menu> Menues { get; set; } = new();

public void Show()


{
Console.WriteLine($"[{Title} menu]");
for(int k=0; k<Menues.Count; k++)
{
var menu = Menues[k];
Console.WriteLine($"{k + 1,3}-{menu.Text}");
}
}
public Menu GetMenu(string leading="")
{
int begin = 1;
int end = Menues.Count;
int input = Input(1, Menues.Count, "Index", new string(' ', 2));
return Menues[input - 1];
}
public static int Input(int lower, int upper, string text, string leading="")
{
while (true)
{
Console.Write($"{leading}{text}({lower}-{upper}): ");
if (int.TryParse(Console.ReadLine(), out var input) == false)
{
Console.WriteLine($"{leading}>Invalid input format");
continue;
}
if (lower <= input && input <= upper) return input;
Console.WriteLine(
$"{leading}>The input is {input}, the input must be in [{lower}, {upper}]");
}
}
}

Step 4: Modifying Program (2)

In the class Program, add a new static method MenuSimulate(), and modify the Main() method as following:
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Selling Products");
MenuBank mainBank = new MenuBank()
{
Title = "Sales",
Menues =
{
new Menu() { Text = "Viewing", Action=ViewSales},
new Menu() { Text = "Creating", Action = CreateSales },
new Menu() { Text = "Searching", Action=SearchSales},
new Menu() { Text = "Deleting", Action = DeleteSales},
new Menu() { Text = "Exiting", Action = ExitProgram}
}
};
MenuSimulate(mainBank);

static void MenuSimulate(MenuBank bank)


{
while (true)
{
Console.WriteLine();
bank.Show();
var actingMenu = bank.GetMenu(new string(' ', 2));
actingMenu.Action();
if (actingMenu.Action == ReturnBack) break;
}
}

Step 5: Testing Program

Build and run the program to test how the progrom operates with a given menu bank.

After testing, let go to next steps.

Step 6: Creating Product Models

Create a new class Product representing a product. The source file, Product.cs, was coded as follow:
public class Product
{
protected static int count = 0;
public static string IdPrefix { get; set; } = "PRD";
public static string GetNewId() { return $"{IdPrefix}-{++count:00000000}"; }
public static Product Create()
{
Product prd = new Product(GetNewId());
return prd;
}
public static Product Create(string name, double price)
{
Product prd = new Product(GetNewId(), name, price);
return prd;
}

private Product(string id) { this.id = id; }


private Product(string id, string name, double price)
{
this.id = id; Name = name; Price = price;
}

protected string id="";

public string Id { get => id; }


public string Name { get; set; } = "";
public double Price { get; set; } = 0.0;
public override string ToString()
{
return $"{Id}({Name}, {Price:C2})";
}
}

Step 7: Creating Product Manager


Create a new class ProductManager representing a manager of products. The source file, ProductManager.cs, was
coded as follow:
public class ProductManager
{
#region Singleton
private static ProductManager? instance = null;
private ProductManager() { }
public static ProductManager GetInstance()
{
if (instance == null) instance = new ProductManager();
return instance;
}
#endregion

#region Products
private Dictionary<string, Product> dictPrds = new Dictionary<string, Product>();

public int Count => dictPrds.Count;


public Product? Add(string name, double price)
{
Product prd = Product.Create(name, price);
Add(prd);
return prd;
}
public void Add(Product prd)
{
if (prd == null) throw new Exception("Null product to be added");
if (dictPrds.ContainsKey(prd.Id))
throw new Exception("The product does already exist");
dictPrds.Add(prd.Id, prd);
}
public Product? Get(string id)
{
try
{
return dictPrds[id];
}
catch (Exception) { return null; }
}
public bool Remove(Product prd)
{
if (prd == null) return false;
return dictPrds.Remove(prd.Id);
}
public Product? RemoveProduct(string id)
{
if (dictPrds.ContainsKey(id) == false) return null;
if (dictPrds.Remove(id, out Product? prd) == true)
return prd;
else
return null;
}
public List<Product> All => dictPrds.Values.ToList<Product>();
public List<string> AllIds => dictPrds.Keys.ToList<string>();
#endregion
}

Step 8: Initializing Products

Create a static method InitializeProducts() in the class Program, and modify the Main() method to initialize products to
be sold.
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Selling Products");
InitializeProducts();
MenuBank mainBank = new MenuBank()
...
}

...

static void InitializeProducts()


{
ProductManager mgr = ProductManager.GetInstance();
mgr.Add(Product.Create("Product1", 23.5));
mgr.Add(Product.Create("Product2", 15.0));
mgr.Add(Product.Create("Product3", 5.0));
mgr.Add(Product.Create("Product4", 3.5));
mgr.Add(Product.Create("Product5", 30.0));
}

Step 9: Creating Sale Models

Create a new class Sale representing a sale. The source file, Sale.cs, was coded as follow:
public class Sale
{
protected static int count = 0;
public static string IdPrefix { get; set; } = "SAL";
public static string GetNewId() { return $"{IdPrefix}-{++count:0000}"; }

public static Sale Create(Product product, double quantity)


{
Sale sale = new Sale(GetNewId(), product, quantity);
return sale;
}
public static Sale? Create(string productId, double quantity)
{
Product? prd = ProductManager.GetInstance().Get(productId);
if (prd == null) return null;
Sale sale = Create(prd, quantity);
return sale;
}

protected string id="";


private Sale(string id) { this.id = id; }
private Sale(string id, Product prd, double quantity)
{
this.id = id;
Product = prd;
Quantity = quantity;
}

public string Id { get => id; }


public Product Product { get; set; } = null!;
public double Quantity { get; set; }
public double? Amount
{
get
{
if (Product == null) return null;
return Quantity * Product.Price;
}
}

Step 10: Creating Product Manager


Create a new class SaleManager representing a manager of products. The source file, SaleManager.cs, was coded as
follow:
public class SaleManager
{
#region Singleton
private static SaleManager? instance = null;
private SaleManager() { }
public static SaleManager GetInstance()
{
if (instance == null) instance = new SaleManager();
return instance;
}
#endregion

#region Sales
private Dictionary<string, Sale> dictSales = new Dictionary<string, Sale>();

public Sale? Add(string productId, double quantity)


{
Product? prd = ProductManager.GetInstance().Get(productId);
if(prd==null) return null;
return Add(prd, quantity);
}
public Sale Add(Product product, double quantity)
{
Sale sale = Sale.Create(product, quantity);
Add(sale);
return sale;
}
public void Add(Sale sale)
{
if (dictSales.ContainsKey(sale.Id))
throw new Exception("The sale does already exist");
dictSales.Add(sale.Id, sale);
if (dictPrdSales.TryGetValue(sale.Product, out var sales)==true)
{
sales.Add(sale);
}
else
{
dictPrdSales.Add(sale.Product, new List<Sale> { sale });
}
}
public Sale? Get(string id)
{
if (dictSales.ContainsKey(id) == false) return null;
return dictSales[id];
}
public bool Remove(Sale sale)
{
return dictSales.Remove(sale.Id);
}
public Sale? Remove(string id)
{
if (dictSales.TryGetValue(id, out var sale))
{
if ( Remove(sale)) return sale;
}
return null;
}
public List<Sale> All => dictSales.Values.ToList<Sale>();
public List<string> AllIds => dictSales.Keys.ToList<string>();
#endregion

#region Product-Sales
private Dictionary<Product, List<Sale>> dictPrdSales =
new Dictionary<Product, List<Sale>>();
public List<Sale> GetFor(Product prd)
{
try
{
return dictPrdSales[prd];
}
catch (Exception)
{
return new List<Sale>();
}
}
public List<Product> AllProducts=> dictPrdSales.Keys.ToList<Product>();

#endregion
}

Step 11: Initializing Sales

Create a static method InitializeSales() in the class Program, and modify the Main() method to initialize sales for some
products.
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Selling Products");
InitializeProducts();
InitializeSales();
MenuBank mainBank = new MenuBank()
...
}

...

static void InitializeSales()


{
var prds = ProductManager.GetInstance().All;
var p1 = prds.FirstOrDefault(e => e.Name == "Product1");
var p2 = prds.FirstOrDefault(e => e.Name == "Product2");
SaleManager smgr = SaleManager.GetInstance();
if (p1 != null)
{
smgr.Add(p1, 30);
smgr.Add(p1, 50);
}
if (p2 != null)
{
smgr.Add(p2, 5);
smgr.Add(p2, 20);
smgr.Add(p2, 10);
}
}

Step 12: Viewing Sales

 In the class Program, create static methods: ViewAllSales(), ViewProductSales(), and ReturnBack()
 In the class Program, modify the existing static method ViewSales()
internal class Program
{
...
static void ViewSales()
{
MenuBank bank = new MenuBank()
{
Title = "Viewing Sales",
Menues = {
new Menu() { Text = "ALL Sales", Action = ViewAllSales },
new Menu() { Text = "Sales by Products", Action = ViewProductSales },
new Menu() { Text = "Returning back", Action = ReturnBack }
}
};
MenuSimulate(bank);
}
...
private static void ReturnBack()
{
Console.WriteLine();
Console.WriteLine("Returning back...");
}

private static void ViewProductSales()


{
Console.WriteLine();
Console.WriteLine("[Viewing sales groupped by products]");
SaleManager mgr = SaleManager.GetInstance();
var prds = mgr.AllProducts;
Console.WriteLine($"Sold products: {prds.Count}");
Console.WriteLine($"{"ProductId",-12} {"Price($)", -8} {"Total($)",12} {"SaleId",-8}
{"Qty", 5} {"Amount($)",12}");
Console.WriteLine(new string('=', 12 + 1 + 8 + 1 + 12 + 1 + 8 + 1 + 5 + 12));
prds.ForEach(p =>
{
var sales = mgr.GetFor(p);
var total = sales.Sum(s => s.Amount);
Console.WriteLine($"{p.Id,-12} {p.Price,8} {total,12:n2} ");
string leading = new string(' ', 12 + 1 + 8 + 1 + 12);
sales.ForEach(s =>
{
Console.WriteLine($"{leading} {s.Id, -8} {s.Quantity, 5} {s.Amount,12:n2}");
});
});
}

private static void ViewAllSales()


{
Console.WriteLine();
Console.WriteLine("[Viewing all sales]");
SaleManager mgr = SaleManager.GetInstance();
var ids = mgr.AllIds;
Console.WriteLine($"Sales: {ids.Count}");
Console.WriteLine($"{"Id",-8} {"Amount($)",12} {"Qty",5} {"Product", -60}");
Console.WriteLine(new string('=', 8 + 1 + 12 + 1+ 5 + 1 + 60));
ids.ForEach(id =>
{
var sale = mgr.Get(id);
if (sale != null)
Console.WriteLine($"{sale.Id,8} {sale.Amount,12:n2} {sale.Quantity,5:n2}
{sale.Product.ToString(),-60}");
});
}
}

Step 13: Testing Program (2)

Build and run the program to test how the progrom operates on Viewing Sales.
After testing, let go to next steps.

Step 14: Creating Sales

In the class Program, create a new static method GetBrowseProduct() modify the existing static method CreateSales().
internal class Program
{
...

static Product? GetBrowseProduct()


{
var prds = ProductManager.GetInstance().All;
if (prds.Count == 0)
{
Console.WriteLine("No products to be browsed for");
return null;
}

Console.WriteLine($"{"Index", 8} {"Product", -50}");


Console.WriteLine(new string('=', 8+1+50));
for(int k=1; k<=prds.Count; k++)
{
Console.WriteLine($"{k,8} {prds[k-1].ToString()}");
}
int input = MenuBank.Input(1, prds.Count, "Index", new string(' ', 4));
return prds[input - 1];
}

static void CreateSales()


{
Console.WriteLine();
Console.WriteLine("[Creating Sales]");
var prdMgr = ProductManager.GetInstance();
if (prdMgr.Count==0)
{
Console.WriteLine("No products to perform a sale");
}
//sale
while (true)
{
Product? prd = null;
double qty = 0.0;
//product
while (true)
{
Console.Write("Product Id(F2 to browse for product): ");

ConsoleKeyInfo keyInfo = Console.ReadKey();


if (keyInfo.Key == ConsoleKey.F2)
{
Console.WriteLine("(F2)");
prd = GetBrowseProduct();
}
else
{
var pid = Console.ReadLine() ?? "";
if (pid != "") pid = (keyInfo.KeyChar.ToString() + pid).ToUpper();
prd = prdMgr.Get(pid);
}
if (prd != null) break;
}
//quantity
while (true)
{
Console.Write("Quantity: ");
if (double.TryParse(Console.ReadLine(), out qty) == false)
{
Console.WriteLine("Invalid quantity format");
continue;
}
else
{
if (qty > 0) break;
Console.WriteLine($"Invalid quantity, {qty}");
}
}

SaleManager.GetInstance().Add(prd, qty);
Console.WriteLine("Successfully created a new sale");
Console.Write("\nEsc to stop, any key for another new sale...");
if (Console.ReadKey(true).Key == ConsoleKey.Escape) break;
Console.WriteLine();
}
Console.WriteLine();
}

Step 15: Testing Program (3)

Build and run the program to test how the progrom operates on creating sales.

After testing, let go to next steps.

Step 16: Searching Sales

In the class Program, modify the existing static method SearchSales().


internal class Program
{
...

static void SearchSales()


{
Console.WriteLine();
Console.WriteLine("[Searching Sales]");
var saleMgr = SaleManager.GetInstance();
while (true)
{
Console.Write("Sale Id: ");
var saleId = (Console.ReadLine() ?? "").ToUpper();
var sale = saleMgr.Get(saleId);
if (sale == null)
Console.WriteLine($"No sale with the id, {saleId}");
else
{
Console.WriteLine("Found!");
Console.WriteLine($"Sale Id : {sale.Id}");
Console.WriteLine($"Product : {sale.Product.ToString()}");
Console.WriteLine($"Quantity : {sale.Quantity}");
Console.WriteLine($"Amount($): {sale.Amount:n2}");
}
Console.Write("\nEsc to stop, any key for another new sale...");
if (Console.ReadKey(true).Key == ConsoleKey.Escape) break;
Console.WriteLine();
}
Console.WriteLine();
}
}
Step 17: Testing Program (4)

Build and run the program to test how the progrom operates on searching for sales.

After testing, let go to next steps.


Step 18: Deleting Sales

In the class Program, modify the existing static method DeleteSales().


internal class Program
{
...

static void DeleteSales()


{
Console.WriteLine();
Console.WriteLine("[Deleting Sales]");
var saleMgr = SaleManager.GetInstance();
while (true)
{
Console.Write("Sale Id: ");

var saleId = (Console.ReadLine() ?? "").ToUpper();


var sale = saleMgr.Get(saleId);
if (sale == null)
Console.WriteLine($"No sale with the id, {saleId}");
else
{
Console.WriteLine("The sale to be deleted");
Console.WriteLine($"Sale Id : {sale.Id}");
Console.WriteLine($"Product : {sale.Product.ToString()}");
Console.WriteLine($"Quantity : {sale.Quantity}");
Console.WriteLine($"Amount($): {sale.Amount:n2}");
Console.Write("Are you sure to delete(y/n): ");
Char confirm = ' ';
while(true)
{
confirm = Char.ToUpper(Console.ReadKey(true).KeyChar);
if (confirm == 'Y' || confirm == 'N') break;
}
Console.WriteLine(confirm);
if (confirm == 'Y')
{
if (saleMgr.Remove(saleId) != null)
{
Console.WriteLine("Successfully deleted");
}
}
}
Console.Write("\nEsc to stop, any key for another deletion...");
var input = Console.ReadKey(true);
if (input.Key == ConsoleKey.Escape) break;
Console.WriteLine();
}
Console.WriteLine();
}

Step 19: Testing Program (4)

Build and run the program to test how the progrom operates on deleting existing sales.

Step 20: Testing Program (final)

Run the program to test all operations to make sure it works property.

You might also like