c# project report - storage.googleapis.com · merit of straightforward user interface and user...

22
1 COMP 2210 Visual Programming Project Report Project Title: Automated Ordering System at Restaurants Team #7 Members: Anton Bukreev Tiasa Mondol

Upload: phungkiet

Post on 16-Aug-2019

231 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

1

COMP 2210 Visual Programming

Project Report

Project Title: Automated Ordering

System at Restaurants

Team #7

Members: Anton Bukreev

Tiasa Mondol

Page 2: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

2

Point Of Sale Software

Point of sale software helps small business automate their routine processes and minimize the waiting

time for the customer. Therefore, this kind of software should be as simple and intuitive as possible.

Since most of small businesses already own a desktop computer, they can use it as a front-desk to take

orders. The software on today’s market is overwhelmingly expensive and unnecessarily complicated.

Personnel usually needs training to accommodate to this kind of software. That’s why we decided to

make a POS software that is super-easy to use, easy to install and useful to any small business.

Basic features:

● Can be installed to any windows-based machine

● Also works on Windows RT tablets

● Is totally free

● Can run even on the oldest computers

● Simple!

This Point of Sale software is written in C#, using only standard class library, that means it can run on

both x64 and x32 systems, Intel- or ARM-based versions of windows, as long as it supports .NET

Framework.

Developing stages

At first, the purpose of the whole project was proposed: to make a simple and easy to use POS software

that wouldn’t require any personnel training since it would be intuitive. It should work on both

keyboard\mouse devices and touch screens, so all the controls were designed with touch screen in

mind: minimum size of the user interface should not be less than 10mm on the screen and the space

between elements should not be less than 5mm. Having that in mind, the team began to research on

existing POS software and User Interfaces it have. Team soon figured out that all of existing software,

available for small business is too complicated and not easy to set up at all. Our software had to

resemble key User Interface elements of existing software to help people, who already had used POS

software before, adapt to our software with less effort.

We then created the simplest User Interface anyone can imagine – several big buttons with clear bold

captions and straightforward controls. We included some additional buttons, that aren’t usually a part

of POS UI, but are convenient to have at hand: for example, we added a “delete last” control, that just

removes the item last added to the order. Remembering touch controls, we’ve made a numeric input

panel, that is used through all the application to enter numbers from touch screen.

Database was designed to solve several problems at once: to store the information for the POS Software

and to provide a usable and convenient back-end, where administrator could add information about

items and generate financial reports, based on sales made through the application. We have chosen

Page 3: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

3

Microsoft Access database because it is a format that is publicly available through Microsoft Office suite,

that is probably installed on most Windows machines. Other database engines like MySQL maybe

provide more features, but are hard to maintain for non-trained personnel and are unnecessarily

complicated for the small application of this kind.

Designing database was essential step in application planning before implementing features in code

since it describes most of the data structures used in the application. Once we finished the database

design stage, we start to create data structures for the app. Since it is an application of rather small

scale, only two simple structures were used: one for an item in stock that represents a dish or a service

in menu, and one for a sale event that makes discount to the whole order. Both data structures are

stored in a separate class that contains just the prototypes of those classes.

Next, we began to implement logic behind the user interface. We’ve created panels that are accessed

just like dialogue boxes and can return a value after they are closed. We’ve created a custom button

class that contains an ID of an item it represents. Space on the screen is quite limited when you think of

touch screens with all their big touch-oriented controls, so we figured out a way to navigate through

virtually unlimited number of items with just buttons. We used a layout of a square 5x3 elements, which

are separated to pages. User can move back and forth through the pages and select needed item. Even

if the item is lots of clicks away – user can always use a barcode button and manually enter the ID of

needed item or service and it could possibly save some time for the customer.

Class structure

There are three forms in the application: one main form called POSForm, one form for the digital input,

called NumericInputDialog and third, representing a sale deal picker panel, named SaleFormDialog. Their

source code is available in the Listing section of this document.

There is a class, responsible for all the database management – DBAdapter. It is used as an interface to

database and it provides simple to use methods for getting items for a specified order or getting

information about the sale, based on it’s ID. This allows us to separate the interface and the

implementation of database transactions. In real words, if we ever decide to change the database model

– all we have to do is to change few methods in this class without refactoring the whole application.

Handy!

There is a class called DataTypes, that is just a prototype container for two classes – Good and Sale.

Those are the data structures that have their own parameters and used independently. If any new data

types will be created – they would be stored in this class. It allows us to store small pieces of code in one

place and easily create Lists of objects of the same type.

Class ButtonWithId is a custom button control that is just a regular button, but with a pointer to an

integer ID. It is used to dynamically add lots of buttons that represent items or sale events to the form.

When user clicks one – it is vital to know what item ID was selected. That is why we store ID within a

button.

Page 4: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

4

Database design Database of this application consists of three main tables: Items, Orders and OrderItems.

Items table contains data about items or services for sale and the main form is filled with the buttons,

generated from this information. It includes name, price, relative URL to a picture of this item, and of

course, ID.

Orders table contains data about orders: one order is comprised of multiple items and possibly has a

discount applied. This table stores the final price for the order and the tax applied to it. Yes, the total can

be calculated dynamically based on the prices of the items in the order, but this data redundancy is

needed in case the item price changes. Since we store the total order amount in a separate field – we

still will be able to create valid financial reports based on order total.

OrderItems table contains the ‘links’ from the order to items. In this way, you can easily ask the DB

about all the items from order number X and get their detailed information. It is comprised of just two

fields: OrderID and ItemID.

We did not implement any predefined financial reports since it can confuse the end user. Most of the

companies require different format of reports anyways, and since Access is giving all the tools to create

the needed report in defined format – we are leaving report generation to the end user or

administrator.

Difficulties faced

None of us was aware that Microsoft Access does not implement full SQL stack. For example, it does not

support the LIMIT keyword, which is quite essential when you do pagination. The workaround is quite a

peculiar thing itself: we use two nested queries, asking DB to get last 12 results which are not in the

second query. Here is an example, where we are skipping 24 records from the beginning and getting

next 12 records:

SELECT TOP 12 * FROM Items WHERE ID NOT IN (SELECT TOP 24 ID FROM Items)

Another difficulty was to implement a panel for getting a user input – a digital input with touch-enabled

controls or just a panel to select a sale from a list. The difficulty here was to create a custom response

from dialog box. We mitigated this difficulty by passing the reference to a parent in a newly created

form and making the new form call itself as a dialog of referenced parent. In this way, the flexibility was

achieved: this dialogue window could be called with a single line of code from any form, not just exact

selected one. The source code of the implementation of this concept can be found in Listing section.

Page 5: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

5

Testing We’ve tested our application on male and female gorillas – both demonstrated full confidence with POS

software after control time of 10 minutes. We believe, it is a decent result that can be considered a

merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently

didn’t like the Windows RT tablet and ate it during the test, so it’s results couldn’t be acquired.

Shortcomings and future work Of course, every application have its shortcomings at the early development stages. This Point of Sale

application is no exception. Here is the list of several shortcomings and the proposed ways to mitigate

them:

● Only one discount can be active at a time

Just need to make the smart discount storage and calculation. This is a rather simple thing to do

so it can be a decent candidate for the next version.

● Needs MS Access to run and maintain

Let’s face it: not everybody has paid for Office suite. There are free DB engines out there – not

so user-friendly and not so simple, but we need to give user a choice. The application could have

a universal connection selector setting – with Microsoft Access as default for the sake of

simplicity.

● Images are served from local storage on HDD.

There are several possible scenarios to mitigate this shortcoming: first, the application could use

a remote web-server with images, This makes more sense in case of a remote DB provider, so all

the data and images could be stored in the cloud and just cached locally. Second way of solving

it: images should be served in a packed format and unpacked only during execution. However,

this requires a mechanism of controlling the resource versions, which is not user-friendly.

● The application has too few settings.

This is actually not a bad thing, taking the ease of use in account. But some basic settings would

be essential – like where is DB file, what type of DB it is, how much is the tax, etc.

This list is a short overview of non-essential shortcomings that are quite easy to mitigate. This list can be

used as a plan for future work on this software and demonstrates some futures from possible future

versions.

Used resources

MSDN Library – http://msdn.microsoft.com/library

Page 6: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

6

C# For Dummies – Bill Sempf, Chuck Sphar, Stephen Randy Davis. 2010, Wiley Publishing ©

Stack Overflow – http://stackoverflow.com

Slides by Mridula Sharma – http://mridulasharma.com

Screenshots

The Interface :

Page 7: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

7

Barcode Scanner :

Page 8: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

8

Sale Selection:

Database Update :

Class listings

POSForm.cs

/*************************************************************** * C# Project : Automated Ordering System : Point of Sale * Team #7

Page 9: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

9

* Members: Anton Bukreev , Tiasa Mondol */

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.Collections;

namespace WindowsFormsApplication4 { public partial class POSForm : Form { private DBAdaptor db; // Listt with ordered items private List<DataTypes.Good> currentOrder; private int currentSale = 0; private int currentOffset = 0; private int currentBevOffset = 0; public int orderno=0; public POSForm() {

InitializeComponent(); // Beverage previous next button not shown at first

button4.Enabled = false; button4.Visible = false; button5.Enabled = false; button5.Visible = false; button6.Enabled = false; button6.Visible = false; db = new DBAdaptor(); drawGoods(); currentOrder = new List<DataTypes.Good>(); }

// Populating the form with item button from data base public void addGoodButton(int id, string imageURL, string name) { ButtonWithId btn = new ButtonWithId(); if (imageURL == "" || !File.Exists(imageURL)) imageURL = @"C:\Users\Toxuin\Documents\IMAGES\noItemImage.png"; btn.Image = Image.FromFile(imageURL);;

Page 10: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

10

btn.ImageAlign = System.Drawing.ContentAlignment.BottomCenter; btn.Width = 120; btn.Height = 120; btn.ItemId = id; btn.Text = name; btn.TextAlign = System.Drawing.ContentAlignment.TopCenter; btn.Click += (sender, evnt) => { itemClickCallback(((ButtonWithId)sender).ItemId); };

// Setting the buttom number limit Point lctn = goodsBox.DisplayRectangle.Location; int initY = lctn.Y; int initX = 30; int row = (int)(goodsBox.Controls.Count / 5); int col = goodsBox.Controls.Count - (row * 5); lctn.Y = initY + row * 130; lctn.X = initX + col * 130; btn.Location = lctn;

goodsBox.Controls.Add(btn); }

// Drawing fast foods private void drawGoods() { button2.Enabled = true; button3.Enabled = true; if (currentOffset == 0) button2.Enabled = false; goodsBox.Controls.Clear();

List<DataTypes.Good> itemsList = db.getGoods(currentOffset, 20);

foreach (DataTypes.Good goodey in itemsList) { addGoodButton(goodey.id, goodey.imageURL, goodey.name); } if (itemsList.Count < 20) button3.Enabled = false; }

private void button3_Click_1(object sender, EventArgs e) { currentOffset = currentOffset + 20; drawGoods(); }

private void button2_Click_1(object sender, EventArgs e) { currentOffset = currentOffset - 20;

Page 11: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

11

if (currentOffset < 0) currentOffset = 0; drawGoods(); }

// Drawing Beverage private void drawBeverage() { button4.Enabled = true; button5.Enabled = true; if (currentBevOffset == 0) button4.Enabled = false; goodsBox.Controls.Clear();

List<DataTypes.Good> itemsList = db.getBeverage(currentBevOffset, 20);

foreach (DataTypes.Good goodey in itemsList) { addGoodButton(goodey.id, goodey.imageURL, goodey.name); } if (itemsList.Count < 20) button5.Enabled = false; }

// SALE PANEL private void btnSale_Click(object sender, EventArgs e) { SalesFormDialog sfd = new SalesFormDialog(this); if (sfd.getSaleValue() <= 0) { // CANCELLED MessageBox.Show("No Sale Selected"); return; } else if (sfd.getSaleValue() > 100) { // CHECK FOR > 100 - MEANS DB CRAZEH MessageBox.Show("DB ERROR"); return; }

currentSale = sfd.getSaleValue(); MessageBox.Show("Sale Value updated to "+currentSale+"%"); recalculateTotal(); }

private void goodManualBtn_Click(object sender, EventArgs e) { NumericInputDialog nid = new NumericInputDialog(this); DataTypes.Good goodey = db.getItemById((int)nid.getResult()); if (goodey != null)

Page 12: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

12

{ // DO MAGIC HERE AS WELL MessageBox.Show(goodey.name); itemClickCallback(goodey.id); } else MessageBox.Show("Item not found!"); }

private void button1_Click(object sender, EventArgs e) { button2.Enabled = false; button2.Visible = false; button3.Enabled = false; button3.Visible = false; button4.Visible = true; button5.Visible = true; button6.Visible = true; button6.Enabled = true; currentBevOffset = 0; drawBeverage(); }

private void itemClickCallback(int id) { // THIS FUNCTION IS CALLED WHENEVER USER CLICKS THE ITEM BUTTON DataTypes.Good item = db.getItemById(id); currentOrder.Add(item); recieptListBox.Items.Add(item.name + " " + item.price); recalculateTotal();

}

private void recalculateTotal() { double total = 0; foreach (DataTypes.Good thingy in currentOrder) { total += thingy.price; } if (currentSale != 0) total = total - (total / 100 * currentSale); printButton.Text = "Total: " + total; }

private void printButton_Click(object sender, EventArgs e) { // SAVE CURRENT ORDER TO DB orderno++; db.saveOrder(currentOrder, currentSale , orderno); currentOrder = new List<DataTypes.Good>(); currentSale = 0; printButton.Text = "Total: " + 0;

Page 13: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

13

recieptListBox.Items.Clear(); MessageBox.Show("Order was succesfully updated to Database"); }

private void btnDelLast_Click(object sender, EventArgs e) { if (currentOrder.Count == 0) return; currentOrder.RemoveAt((currentOrder.Count) - 1); // RECALCULATE SALE ITEM POSITION IN RECIEPT!!! redrawReciept(); }

// Updates the receipt box private void redrawReciept() { recieptListBox.Items.Clear(); foreach (DataTypes.Good thingy in currentOrder) { recieptListBox.Items.Add(thingy.name + " " + thingy.price); }

recalculateTotal(); }

private void button4_Click(object sender, EventArgs e) { currentBevOffset = currentBevOffset - 20; if (currentBevOffset < 0) currentBevOffset = 0; drawBeverage(); }

private void button5_Click(object sender, EventArgs e) { currentBevOffset = currentBevOffset + 20; drawBeverage(); }

private void button6_Click(object sender, EventArgs e) { button1.Visible = true; button1.Enabled = true; button4.Enabled = false; button4.Visible = false; button5.Enabled = false; button5.Visible = false; button2.Visible = true; button3.Visible = true;

Page 14: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

14

button6.Visible = false; button6.Enabled = false; currentOffset = 0; drawGoods(); }

} }

DataTypes.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;

// making two data types of good and sale namespace WindowsFormsApplication4 { class DataTypes {

public class Good { public int id; public string name; public string imageURL; public double price; }

public class Sale { public int id; public string name; public int value; }

} }

ButtonWithId.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;

Page 15: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

15

// Separately Created Button class that serve our purpose namespace WindowsFormsApplication4 { public class ButtonWithId : Button { public int id; public int ItemId { get { return id; } set { id = value; } } } }

DBAdaptor.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data.OleDb; using System.Data.SqlClient;

namespace WindowsFormsApplication4 { class DBAdaptor {

private OleDbConnection connection = null; private bool ready = false;

public DBAdaptor() { if (connection == null) reopenConnection(); connection.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;" + @"Data Source= G:\Project\AwesomePOS-master\AwesomePOS.accdb;Persist Security Info=False;"; try { connection.Open(); ready = true; } catch (Exception ex) { Console.WriteLine("Failed to connect to data source!!! " + ex); } }

private void reopenConnection() { if (connection != null) closeConnection(); connection = new System.Data.OleDb.OleDbConnection();

Page 16: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

16

}

public void closeConnection() { connection.Close(); connection.Dispose(); ready = false; }

public DataTypes.Good getItemById(int itemId) { DataTypes.Good goodey = new DataTypes.Good(); string sqlStr = @"SELECT * FROM Items WHERE ID = " + itemId; OleDbCommand cmd = new OleDbCommand(sqlStr, connection); OleDbDataReader reader = cmd.ExecuteReader(); if (reader.Read()) { goodey.id = Convert.ToInt32(reader["ID"].ToString()); goodey.imageURL = reader["ImageURL"].ToString(); goodey.name = reader["ProductName"].ToString(); goodey.price = Convert.ToDouble(reader["Price"].ToString()); } else return null; return goodey; }

public List<int> getItemsForOrderId(int orderId) { List<int> list = new List<int>(); OleDbCommand cmd = new OleDbCommand("SELECT ProductId FROM OrderItems WHERE OrderId = " + orderId, connection); OleDbDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { list.Add(Convert.ToInt32(reader["ProductId"].ToString())); } return list; }

// Get sales with appropitae excape numbers public List<DataTypes.Sale> getSales(int skip = 0, int count = 0) { List<DataTypes.Sale> list = new List<DataTypes.Sale>();

string sqlString = @"SELECT * FROM Sales "; if (skip != 0 || count != 0) sqlString += @"WHERE ID BETWEEN " + (skip+1) + " AND " + (skip+count) + " AND ACTIVE = YES"; else sqlString += @" WHERE ACTIVE = YES"; OleDbCommand cmd = new OleDbCommand(sqlString, connection); OleDbDataReader reader = cmd.ExecuteReader();

Page 17: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

17

while (reader.Read()) { DataTypes.Sale sale = new DataTypes.Sale(); sale.id = Convert.ToInt32(reader["ID"].ToString()); sale.name = reader["SaleName"].ToString(); sale.value = Convert.ToInt32(reader["SaleValue"].ToString()); list.Add(sale); } return list; }

public List<DataTypes.Good> getBeverage(int skip = 0, int count = 0) { List<DataTypes.Good> list = new List<DataTypes.Good>(); string sqlString; if (skip != 0) sqlString = @"SELECT TOP " + count + " * FROM Items WHERE ID NOT IN (SELECT TOP " + skip + " ID FROM Items WHERE Type=" + "\'" + "Beverage" + "\'" + ") AND Type=" + "\'" + "Beverage" + "\'"; else sqlString = @"SELECT TOP " + count + " * FROM Items WHERE Type=" + "\'" + "Beverage" + "\'"; OleDbCommand cmd = new OleDbCommand(sqlString, connection); OleDbDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { DataTypes.Good goodey = new DataTypes.Good(); goodey.id = Convert.ToInt32(reader["ID"].ToString()); goodey.name = reader["ProductName"].ToString(); goodey.imageURL = goodey.imageURL = "G:/Project/AwesomePOS-master/Images/icon_2/" + goodey.name.ToLower() + ".png";

goodey.price = Convert.ToDouble(reader["Price"].ToString()); list.Add(goodey); } return list; }

public List<DataTypes.Good> getGoods(int skip = 0, int count = 0) { List<DataTypes.Good> list = new List<DataTypes.Good>(); string sqlString ; if (skip != 0) sqlString = @"SELECT TOP " + count + " * FROM Items WHERE ID NOT IN (SELECT TOP " + skip + " ID FROM Items WHERE Type=" + "\'" + "Food" + "\'" + ") AND Type=" + "\'" + "Food" + "\'"; else sqlString = @"SELECT TOP " + count + " * FROM Items WHERE Type=" + "\'" + "Food" + "\'"; OleDbCommand cmd = new OleDbCommand(sqlString, connection); OleDbDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { DataTypes.Good goodey = new DataTypes.Good(); goodey.id = Convert.ToInt32(reader["ID"].ToString()); goodey.name = reader["ProductName"].ToString(); goodey.imageURL = @"G:\Project\AwesomePOS-

Page 18: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

18

master\Images\icon_2\"+goodey.name.ToLower()+".png"; goodey.price = Convert.ToDouble(reader["Price"].ToString()); list.Add(goodey); } return list; } public DataTypes.Sale getSaleById(int saleId) { DataTypes.Sale sale = new DataTypes.Sale(); string sqlStr = @"SELECT * FROM Sales WHERE ID = " + saleId + " AND Active = YES"; OleDbCommand cmd = new OleDbCommand(sqlStr, connection); OleDbDataReader reader = cmd.ExecuteReader(); if (reader.Read()) { sale.id = Convert.ToInt32(reader["ID"].ToString()); sale.value = Convert.ToInt32(reader["SaleValue"].ToString()); sale.name = reader["SaleName"].ToString(); } else return null; return sale; }

public bool testConnection() { return ready; }

internal void saveOrder(List<DataTypes.Good> currentOrder, int saleValue, int orderno) { double total = 0; OleDbCommand cmd = connection.CreateCommand(); foreach (DataTypes.Good thingy in currentOrder) { total += thingy.price; cmd.CommandText = @"INSERT INTO OrderItems (OrderId, ProductId) VALUES ('"+ orderno + "','" + thingy.id + "')"; cmd.ExecuteNonQuery();

}

cmd.CommandText = @"INSERT INTO Orders (ID ,Total, Tax, SaleValue) VALUES ("+orderno+",'"+ total + "','" + (total*saleValue/100) + "','"+saleValue+"')"; cmd.ExecuteNonQuery(); } } }

Page 19: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

19

SaleFormDialogue.cs: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;

namespace WindowsFormsApplication4 { public partial class SalesFormDialog : Form { private string saleName = ""; private int saleValue = 0;

private int currentOffset = 0;

private DBAdaptor db;

public SalesFormDialog(IWin32Window owner) { InitializeComponent(); db = new DBAdaptor(); redrawSales();

if (this.ShowDialog(owner) == DialogResult.OK) { //calls itself } db.closeConnection(); this.Dispose(); }

private void redrawSales() { prevBtn.Enabled = true; nextBtn.Enabled = true; if (currentOffset == 0) prevBtn.Enabled = false; saleBox.Controls.Clear(); List<DataTypes.Sale> saleList = db.getSales(currentOffset, 12); foreach (DataTypes.Sale sale in saleList) { addSaleButton(sale.id, sale.name); } if (saleList.Count < 12) nextBtn.Enabled = false; }

Page 20: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

20

public void addSaleButton(int id, string name) { ButtonWithId btn = new ButtonWithId(); btn.Width = 120; btn.Height = 50; btn.ItemId = id; btn.Text = name; btn.Click += (sender, evnt) => { saleClickCallback(((ButtonWithId)sender).ItemId); };

// COULD GO OFF THE SCREEN Point lctn = saleBox.DisplayRectangle.Location; int initY = lctn.Y; int initX = 20; int row = (int)(saleBox.Controls.Count / 3); int col = saleBox.Controls.Count - (row * 3); lctn.Y = initY + row * 60; lctn.X = initX + col * 130; btn.Location = lctn; saleBox.Controls.Add(btn); }

private void saleClickCallback(int id) { DataTypes.Sale sale = new DataTypes.Sale(); if (id != 0) sale = db.getSaleById(id); saleValue = sale.value; saleName = sale.name; this.Dispose(); }

private void saleManualBtn_Click(object sender, EventArgs e) { NumericInputDialog nid = new NumericInputDialog(this); saleValue = (int) nid.getResult(); saleName = "Custom sale"; this.Dispose(); }

public int getSaleValue() { return saleValue; }

public string getSaleName() { return saleName; }

private void nextBtn_Click(object sender, EventArgs e) { currentOffset = currentOffset + 12; redrawSales(); }

Page 21: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

21

private void prevBtn_Click(object sender, EventArgs e) { currentOffset = currentOffset - 12; if (currentOffset < 0) currentOffset = 0; redrawSales(); } } }

NumericInputDialogue.cs: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; // Numeric input dialogue for bar code namespace WindowsFormsApplication4 { public partial class NumericInputDialog : Form { private double result = 0; public NumericInputDialog(IWin32Window owner) { InitializeComponent(); if (this.ShowDialog(owner) == DialogResult.OK) { result = Double.Parse(numTextBox.Text); } this.Dispose(); } public TextBox numText;

private void clearBtn_Click(object sender, EventArgs e) { numTextBox.Text = ""; }

private void numBtn_Click(object sender, EventArgs e) { if (numTextBox.Text.Length >= 8) return; Button pushedButton = (Button)sender; if (pushedButton.Text.Length == 2 && numTextBox.Text.Length >= 7) return; numTextBox.Text += pushedButton.Text; Console.Beep(); // NOT WORKEY ON x64 SYSTEM. }

private void backspaceBtn_Click(object sender, EventArgs e) { if (numTextBox.Text == "") return; numTextBox.Text = numTextBox.Text.Remove(numTextBox.Text.Length - 1, 1);

Page 22: C# Project Report - storage.googleapis.com · merit of straightforward User Interface and user friendly controls. However, one of gorillas apparently However, one of gorillas apparently

22

}

public double getResult() { return result; } } }