The stock details will be kept in a file called “Stock.dat” this will be accessed and edited by a record type called “StockDetail” the variables are displayed in the table below:-
The sales details will be kept in a file called “Sales.dat” this will be accessed and edited by a record type called “SalesDetail” the variables are displayed in the table below:-
For Backup Purposes the systems will have an option where it archives all the data files to floppy disk, from this the system can resume a state at which the last back up was made in case of data lose.
Algorithms for data transformation
Data will be processed at a number of places in this project, most notably it will be processed in the check out where once all the Items have been entered a total price will be calculated, this will be done simply with a single variable called ‘total’ every time a new item is added price will be added to the total like :-
Total := total + price;
Another place where data will be processed is to check when items need reordering here a simple comparison will be made with the minimum stock level of data and current stock level like:-
If InStock <= MinStock
then reorder
else nothing;
Identification Validations
The main way of validating data and maintaining the integrity of data will be with the variables I will be setting at the start of the program. For example
Variable Validations
ItemName in the stock table will be a string[20] so it will only accept 20 characters.
ItemCode in the stock table will be an integer so entering a character will bring up an error message, same applies to all integer fields.
Input Validations
I will also set validations so that the same Item code can not be entered twice, every time you enter an item code the program will search through the entire stock table using a sequential search, to see if it finds the item code, if it does it will give you an error message and you will have to enter a different Item Code.
User Interface (design of input and output forms)
Password
The system will be protected by a simple but effective password, which will protect unauthorised access to the system. The password will be stored in an external text file, the system will initially read the password from the text file into memory, Then it will prompt the user to enter a password into the input box below:-
When entering the password the characters entered will not show, instead asterisks will show in there place. After receiving the password the system will compare the password read from the file and the user entered password and using IF statements will grant access to system if they are the same or will prompt the user to re-enter password if incorrect. Re-entry of password will be allowed 3 times before the program exits.
If the password has been entered 3 times incorrectly the system will freeze and will require a restart, this will be achieved by a simple infinite loop.
Menu System
The Menu system will have a list of options which when selected will help you navigate thorough different parts of the program which will bring up the different input and output forms used. The different options which will be displayed will be shown on screen, and one of them will be highlighted to select a option the user will uses the up, down keys to scroll between different options and click enter to select the desired option.
Menu select function
Main Menu diagram
Main Menu
The Main Menu is the menu which is bought up when the system starts after password validation from here all parts of the system can be reached.
-
Check Out – Clicking the check out option will take you to the checkout here Item codes can be entered, total price is calculated and receipt is printed, basically it’s the cashier part for the shop.
-
Stock Table – This will take you to another menu, here all the stock table related options will be shown
-
Sales Table – This will take you to the sales table menu here all the sales related options will be shown.
-
Options – This will take you to the options menu where additional features of the system will be shown.
Stock Table Menu
The Stock Table Menu has options relating to the stock table.
-
Add Record - This will take you to a screen where you can add records to you database.
-
View Edit Delete - This will take you to a screen where you can view the records using the up and down keys as well as let you delete or edit records.
-
Search Record - This will take you to a screen where you can search for records, once found it will display the record.
-
Items Needing Reordering – This will take you to a screen which will display only the items which need reordering.
-
Back to Main Menu - This will take you back to the main menu.
Sales Table Menu
The Sales Table Menu has options relating to the stock table.
-
View or Delete Sale - This will take you to a screen where you can view all the sales and delete sales, using the down key to scroll through records and the ‘d’ key to delete sales.
-
Search Record - This will take you to a screen where you can search for Sales records, once found it will display the record.
-
Return Item – This allow you to return an Item which has been sold.
-
Back to Main Menu - This will take you back to the main menu.
Data Capture
Input Forms and Output Forms
Add Record
Add record will bring up the form used to add items to the stock table.
The add record form will look like the illustration below:
View, Amend and Delete a Record
This Form will be used to view, amend and delete records, you simply use the up and down keys to scroll available records, if you would like to delete a record you press ‘d’ and it will be deleted or if you would like to amend a record you press the ‘e’ key and it will ask you which part of the record you want to amend.
Search Records for sales and stock
This feature will be used to search through the database to find a specific record, it will work by asking for a item code, then searching for the item code, using an IF statement in a loop to compare ever item code with the entered value until the record is found, else if it reaches the end of the file and has not found any matching record it will display a message saying ‘record not found’.
View Items which Need reordering
Here items will be compared that are available in stock with the minimum stock level, if the values are the same or the value of items available is smaller then that record will show up in this output form.
View or Delete Sales Record
Here you can view all sales that have taken place using the up and down keys, to delete a sale you simply press the ‘d’ key and that record will be deleted.
Return Item from Sales Record
Here you scroll down to the sale which you want to take back and it will delete the record and if the item is still in good condition it will add it back to the stock table.
Check Out
The Check out is the main form used and the most complex which uses the most types of file manipulation. Here you enter Items the customer wants, it will then calculate a total for the customer and print a receipt. It will also subtract items sold from the stock table and put them into the sales table. When entering items it will display the description of the item to validate if the code it correct.
Sample of planned data validation
An Example of where I will use data validation can be taken from when you will enter an Item Code, in the add stock form, when you enter a code, the system will check the entire stock table to see if that Item Code exist if it does you will be given an error message.
Description of record or database structure
The Database structure is mainly two files one which holds the stock details “Stock.dat” and the other which holds the Sales information “Sales.dat”, the structure and formats of these files can be found in the “Definition of data requirements” section. Details can be added to the stock file through the stock options. The Check Out will read items codes display the Name and Price of the items, you enter into it and calculate a total. Then it will subtract the items from the stock table and add them to the sales table.
Sample of Planned data entry
An example of data entered into the add stock form.
Sample of planned valid output
An Example of Data output in the View Edit Delete Stock Form.
File Organisation and Processing
The file organisation used in the database will be a serial organisations, so when a record is added to a file it will add it to the end of the file. Searches will be preformed using a serial search, basically it will go through each record using a repeat loop and an if statement will be used to check for valid results.
Database design including E-R Model
There are be 2 main entities in this system, a one to many relationship
Security and Integrity of Data
Firstly physical access to the computer will be pretty hard since, the end user will always be at the shop, when it is open, and the shop is locked when it is closed. The data that will be stored in this database is just mainly data about stock and sales so methods like encryption are a little too extreme. The data stored in files can really only be made sense out of if read by the database, opening them up using a text editor like notepad will give, just you lots of jumbled data.
Integrity of the data will be mainly maintained by the validation rules present in the database, another way integrity is maintained is most of the complex procedures have been simplified to entering minimal data, for example entering an item into the check out just required the item code, which after entering displays the name to further make sure it is the correct information entered.
System Security
A number of steps will been taken to ensure that the system is secure and maintains the integrity of data.
For security purposes the system will have a password at the start up, this will prevent unauthorised access to the system, the password and system will automatically activate at computer start up, this will be achieved by modifying the computer boot files (autoexec.bat) adding the program path and executable location. In this case like:-
Since with this modification the system password will start instantly on the computer booting, It makes it harder for anyone to access the data of the system in other ways, like notepad, edit, etc.
Another Security feature will be that the password can only be entered 3 times after which the computer will halt (freeze), and the only way to get back is to restart the computer, which again will take you to the password, the freeze process will be achieved by using a simple endless loop like:-
Repeat Until restart;
Since the Boolean variable restart is set to false and will never equal true in this case it will just keep looping. Thus making it extremely hard for the computer to be accessed in any way other then through the system, which will require a password.
Overall Test Strategy
Test Strategy
The test strategy will include:
- Test all input forms, if they accept all the data
- Testing of individual Menu System Options
- Testing of inputting invalid or extreme data
- Check backup and restore features
- Test security features
- Test system by inputting dummy data to simulate real events
- End-user tests it, to see if it meets his requirements
Test Plan
Test Data Being used
Test data set 1: Stock Table
Technical Solution
Technical Solution
Program Computing;
uses crt,dos; {Libraries used}
(*******************************************************************)
(* Variables *)
(*******************************************************************)
Type FiveChar = array[1..5] of char; {type used to store the password}
Type StockDetail = record {Type for Stock Table}
ItemCode,InStock,MinStock:integer;
ItemName:string[20];
Price:real;
end;
Type ItemCodeList = Array[1..18] of integer;
Type SalesDetail = record {Type for Sales Table}
SaleCode:integer;
Sold:ItemCodeList;
Returned:boolean;
Year,Month,Day:word;{store for date}
H,M,S:word; {store for time}
Total:real;
end;
var menu :array[1..5] of string;
b,i,x,y:integer;
status:byte;
access,Return,restart:boolean;
tries:integer;
Screen:char;
(**********************************************************************)
(* PROCEDURES : DRAW BACKGROUNDS AND BOXES *)
(**********************************************************************)
(**********************************************************************)
(* PROCEDURE : BOX *)
(**********************************************************************)
Procedure Box (x1,y1,x2,y2:integer);
begin
for b := y1 to y2 do
begin
gotoxy(x1,b);
begin
for i := x1 to x2 do
write(' '); {fills the box with spaces so that the}
end; {background colour of the box can be changed}
end;
for i := x1 to x2 do {draws lef and right side of box}
begin
gotoxy(i,y1);
write(#205);
gotoxy(i,y2);
write(#205);
end;
for i := y1 to y2 do {draws top and bottom sides of box}
begin
gotoxy(x1,i);
write(#186);
gotoxy(x2,i);
write(#186);
end;
gotoxy(x1,y1); {draws corners for boxes}
write(#201);
gotoxy(x2,y1);
write(#187);
gotoxy(x1,y2);
write(#200);
gotoxy(x2,y2);
write(#188);
end;
(**********************************************************************)
(* PROCEDURE : STOCK TABLE BACKGROUND *)
(**********************************************************************)
Procedure StockBackground;
Begin
textbackground(blue);
clrscr;
gotoxy(20,4);
write('Item Code: ');
textbackground(Cyan);
write (' ');
gotoxy(20,6);
textbackground(blue);
write('Item Name: ');
textbackground(Cyan);
write (' ');
gotoxy(20,8);
textbackground(blue);
write('Price(œ): ');
textbackground(Cyan);
write (' ');
gotoxy(20,10);
textbackground(blue);
write('In Stock: ');
textbackground(Cyan);
write (' ');
gotoxy(10,12);
textbackground(blue);
write('Minimum Stock Level: ');
textbackground(Cyan);
write (' ');
End;
(**********************************************************************)
(* PROCEDURE : SALE TABLE BACKGROUND *)
(**********************************************************************)
Procedure SalesBackground;
Begin
textbackground(blue);
clrscr;
gotoxy(50,4);
write('Sale Code: ');
textbackground(Cyan);
write (' ');
textbackground(blue);
gotoxy(50,6);
write('Date : ');
textbackground(cyan);
write(' ');
gotoxy(50,8);
textbackground(blue);
write('Time : ');
textbackground(cyan);
write(' ');
textbackground(blue);
gotoxy(50,10);
write('Returned: ');
textbackground(cyan);
write(' ');
gotoxy(45,12);
textbackground(blue);
write('Total Price(œ) :');
textbackground(cyan);
write(' ');
End;
(**********************************************************************)
(*PROCEDURE : DRAW BOX IN TABLES FOR MESSAGES*)
(**********************************************************************)
Procedure DrawBoxInfo;
Begin
textbackground(green);
Box(1,20,79,25);
gotoxy(20,22);
End;
(**********************************************************************)
(* PASSWORD SYSTEM *)
(**********************************************************************)
Procedure Warning; {recieve a warning if password typed incorrect}
begin
tries := tries + 1;
textbackground(red);
Box(29,10,56,15);
If tries < 3 then
Begin
gotoxy(34,12);
write('Incorrect Password');
gotoxy(31,13);
write('Press Enter to try again');
repeat until readkey=#13;
End
Else Begin
gotoxy(39,12);
Write ('System Exit');
Repeat Until restart;{this line will freeze computer}
end; {so restart is needed}
end;
Procedure Password;
var f :file of fivechar;
pass :fivechar;
filepass:fivechar;
begin
assign (f,'n:\Database\Password.dat'); {makes f the password file}
reset (f);
read(f,filepass); {reads password into filepass}
if tries < 3 then
Begin
if tries < 2
then
textbackground(blue)
else
textbackground(red);
box(29,10,56,15);
gotoxy(35,12);
writeln ('Enter Password');
gotoxy(35,13);
for i := 1 to 5 do
begin
pass[i] := readkey;
write ('*');{enters an astrisk instead of the actual password}
end;
repeat until readkey=#13; {until Enter keypressed}
if pass = filepass {compares password with entered value}
then access := true
Else Begin {this will give you a warning}
Warning;
Password;
End;
End;
end;
(**********************************************************************)
(* PROCEDURE TO CHANGE PASSWORD *)
(**********************************************************************)
Procedure PasswordChange;
var f :file of fivechar;
filepass,newpass:fivechar;
Begin
status := 6;
clrscr;
tries := 0;
access := false;
password;
if access = true then
begin
assign (f,'n:\Database\Password.dat');
reset (f);
read (f,filepass);
gotoxy(35,12);
write('Enter New Password');
gotoxy(35,13);
write(' ');
gotoxy(35,13);
for i := 1 to 5 do
begin
newpass[i] := readkey;
write ('*');
end;
repeat until readkey=#13;
filepass:=newpass; {assigns entered value to password}
rewrite (f);
write (f,filepass);{writes new password}
close (f);
end;
return := true;
End;
(**********************************************************************)
(* MENU CONTENT *)
(**********************************************************************)
Procedure LoadMainMenu;
Begin
menu[1] := ' .:[ Check Out ]:. ';
menu[2] := ' .:[ Stock Table ]:. ';
menu[3] := ' .:[ Sales Table ]:. ';
menu[4] := ' .:[ Options ]:. ';
menu[5] := ' .:[ Quit ]:. ';
Screen := 'M';
Status := 128;
End;
Procedure LoadStockMenu;
Begin
menu[1] := ' .:[ Add Stock ]:.';
menu[2] := ' .:[ View Edit Delete ]:.';
menu[3] := ' .:[ Search Stock ]:.';
menu[4] := ' .:[View ReOrder Stock]:.';
menu[5] := ' .:[Back To Main Menu ]:. ';
Screen := 'S';
End;
Procedure LoadSalesMenu;
Begin
menu[1] := ' .:[ View or Delete ]:.';
menu[2] := ' .:[ Search Sales ]:.';
menu[3] := ' .:[ Return Item ]:.';
menu[4] := ' .:[ ]:.';
menu[5] := ' .:[Back To Main Menu ]:. ';
Screen := 'T';
End;
Procedure LoadOptionMenu;
Begin
menu[1] := ' .:[ Edit Password ]:. ';
menu[2] := ' .:[ Backup Database ]:. ';
menu[3] := ' .:[ Reset Stock Info]:. ';
menu[4] := ' .:[ Reset Sales Info]:. ';
menu[5] := ' .:[Back To Main Menu]:. ';
Screen := 'O';
Status := 128;
End;
(**********************************************************************)
(* PROCEDURE : TIME AND DATE *)
(**********************************************************************)
Procedure ShowTime;{This interrupt procedure reads and displays the time}
Var H,M,S,SS:Word;
Begin
textbackground(blue);
textcolor(15){bright white};
GetTime(H,M,S,SS);
GotoXY(70,3);
Write(H:2,':',M:2,':',S:2);
Delay(1000);
End;
Procedure ShowDate;{This interrupt procedure reads and displays the date}
Var Year,Month,Day,DayOfWeek:Word;
Begin
textcolor(15);
GetDate(Year,Month,Day,DayOfWeek);
GotoXY(70,2);
Write(Day,'/',Month,'/',Year);
End;
(**********************************************************************)
(* PROCEDURE : Backup Data to Floppy *)
(**********************************************************************)
Procedure Backup;
var f:file of StockDetail;
g:file of SalesDetail;
Begin
Status := 6;
textbackground (blue);
clrscr;
writeln ('Please insert floppy disk in drive');
readkey;
assign (f,'n:\database\stock.dat');
rename (f,'A:\stock.dat');
assign (g,'n:\database\sales.dat');
rename (g,'A:\Sales.dat');
return := true;
end;
(**********************************************************************)
(* PROCEDURE : RESET STOCK TABLE *)
(**********************************************************************)
Procedure ResetStock;
VAR StockRec :StockDetail;
f :file of StockDetail;
done :boolean;
Begin
status := 6;
textbackground(blue);
clrscr;
writeln ('Are You Sure, You wish to reset Stock table?');
writeln ('ALL DATA WILL BE DELETED Y/N');
if readkey = 'y'
then begin
assign (f,'n:\Database\Stock.dat');
rewrite (f); {this will erase all previous data in file}
repeat {or create a new file if it does not exist}
with StockRec do
begin
write ('ItemCode: ');
readln (ItemCode);
if Itemcode = 19 then done:=true
else begin
Write ('Item Name: ');
readln (ItemName);
write ('Price(œ): ');
readln (Price);
write ('In Stock: ');
readln (InStock);
write ('Minimum Stock Level: ');
readln (MinStock);
write (f, StockRec)
end;
end; {with}
until done;
close (f);
end; {if}
Return := true;
End;
(**********************************************************************)
(* PROCEDURE : RESET SALES TABLE *)
(**********************************************************************)
Procedure ResetSales;
VAR SalesRecord :SalesDetail;
g :file of SalesDetail;
done :boolean;
Begin
status := 6;
textbackground(blue);
clrscr;
writeln ('Are You Sure, You wish to reset sales table?');
writeln ('ALL DATA WILL BE DELETED Y/N');
if readkey = 'y'
then begin
assign (g,'n:\Database\Sales.dat');
rewrite (g);
with SalesRecord do
begin
write ('Sales Code: ');
readln (SaleCode);
write ('Enter Date : ');
readln (Day);
write ('Enter Month : ');
readln (Month);
write ('Enter Year : ');
readln (Year);
write (g, SalesRecord);
end; {with}
close (g);
end; {if}
Return := true;
End;
(**********************************************************************)
(* PROCEDURES : ADD RECORD(s) TO STOCK TABLE *)
(**********************************************************************)
Procedure AddRecord;
VAR StockRec :StockDetail;
f :file of StockDetail;
done :boolean;
lastrec:integer;
a:char;
tempname :string[20];
{nested Procedure}
Procedure UniqueItemCode;{procedure will check if item code already exists}
var Temp:integer;
Validation :StockDetail;
g :file of StockDetail;
ExitLoop:boolean;
Begin
Read (Temp);
ExitLoop := false;
assign (g,'n:\Database\Stock.dat');
reset(g);
repeat
Read (g,Validation);
if Validation.ItemCode = Temp
then Begin
textbackground(red);
gotoxy(39,4);
write ('Item Code already Exists');
delay (20000);
textbackground(blue);
gotoxy(39,4);
write (' ');
textbackground(cyan);
reset(g);
gotoxy (31,4);
read (temp);
End
else if eof(g) then begin
StockRec.ItemCode := Temp;
ExitLoop := true;
end;
until ExitLoop;
close (g);
End;
Begin {main part}
status := 6;
assign (f,'n:\Database\Stock.dat');
reset(f);
done := false;
lastrec :=pred(filesize (f));
seek (f,lastrec);
read(f,StockRec);
repeat
StockBackground;
DrawBoxInfo;
write ('Would You like to add another record? y/n');
if readkey = 'n' {#27 is the esqape key}
then done := true
else begin
textbackground(cyan);
gotoxy (31,4);
UniqueItemCode;
gotoxy (31,6);
read (StockRec.ItemName);
gotoxy (31,8);
read (StockRec.Price);
gotoxy (31,10);
read (StockRec.InStock);
gotoxy (31,12);
read (StockRec.MinStock);
DrawBoxInfo;
write ('Would You like to save this record ? y/n');
if readkey = 'y'
then begin
write (f, StockRec);
DrawBoxInfo;
write (' Record Saved!');
delay (20000);
end;
end;
until done;
close (f);
Return := true;
End;
(**********************************************************************)
(* PROCEDURES : VIEW\AMEND\DELETE *)
(**********************************************************************)
Procedure ViewRecord;
VAR StockRec :StockDetail;
f :file of StockDetail;
a,lastrecnum, numofrecs:integer;
Escape:boolean;
key:char;
Procedure ShowRecord; {Nested Procedure}
Begin
inc(a);
read (f,StockRec);
StockBackground;
textbackground(blue);
Box(20,13,52,18);
gotoxy(22,14);
write ('Press e to edit this record');
gotoxy(22,15);
write('Press d to delete this record');
gotoxy(22,16);
write('Press Escape to quit');
DrawBoxInfo;
gotoxy (20,21);
write ('This is Record Number : ',a);
gotoxy (20,22);
write ('Total Number of Records: ',numofrecs);
gotoxy (20,23);
write ('Use Up/Down Keys to Scroll Through Records');
textbackground(cyan);
gotoxy (31,4);
write (StockRec.ItemCode); {Write Item Code}
gotoxy (31,6);
write (StockRec.ItemName);
gotoxy (31,8);
write (StockRec.Price:11:2);
gotoxy (31,10);
write (StockRec.InStock);
gotoxy (31,12);
write (StockRec.MinStock);
End;
Procedure DeleteRecord; {nested procedure}
VAR f_temp : file of StockDetail;
count,recnum : word;
Begin
DrawBoxinfo;
Write ('Are you sure you would like to delete this record? y/n');
if readkey = 'y'
then Begin
recnum := a - 1; {the record number to delete}
reset(f);
assign(f_temp,'n:\database\Stock.tmp');
rewrite(f_temp);
for count := 0 to filesize (f) - 1 do
begin
read(f, StockRec);{read one record from the source file}
if recnum <> count
then write(f_temp, StockRec);
end;
{now all records are copied to the temporary file, except the one that}
{was to be deleted.}
close(f);
erase(f);{delete the original file}
close(f_temp);
rename(f_temp,'n:\database\Stock.dat');{rename temp file to}
{orginal file name}
ViewRecord;
end;
End;
Procedure UniqueItemCode;
var Temp:integer;
Validation :StockDetail;
g :file of StockDetail;
ExitLoop:boolean;
Begin
Read (Temp);
ExitLoop := false;
assign (g,'n:\Database\Stock.dat');
reset(g);
repeat
Read (g,Validation);
if Validation.ItemCode = Temp
then Begin
textbackground(red);
gotoxy(39,4);
write ('Item Code already Exists');
delay (20000);
textbackground(blue);
gotoxy(39,4);
write (' ');
textbackground(cyan);
reset(g);
gotoxy (31,4);
read (temp);
End
else if eof(g) then begin
StockRec.ItemCode := Temp;
ExitLoop := true;
end;
until ExitLoop;
close (g);
End;
Procedure AmendRecord;
Begin
DrawBoxInfo;
write ('Would you like to edit this record? y/n');
if readkey = 'y'
then begin
gotoxy(52,4);
textbackground(red);
write ('Edit Item Code? y/n');
if readkey = 'y'
then begin
gotoxy(31,4);
textbackground(cyan);
UniqueItemCode;
end;
gotoxy(52,6);
textbackground(red);
write ('Edit Item Name? y/n');
if readkey = 'y'
then begin
gotoxy(31,6);
textbackground(cyan);
read (StockRec.ItemName);
end;
gotoxy(52,8);
textbackground(red);
write ('Edit Price? y/n');
if readkey = 'y'
then begin
gotoxy(31,8);
textbackground(cyan);
read (StockRec.Price);
end;
gotoxy(52,10);
textbackground(red);
write ('Edit In Stock? y/n');
if readkey = 'y'
then begin
gotoxy(31,10);
textbackground(cyan);
read (StockRec.InStock);
end;
gotoxy(52,12);
textbackground(red);
write ('Edit Minimum Stock level? y/n');
if readkey = 'y'
then begin
gotoxy(31,12);
textbackground(cyan);
read (StockRec.MinStock);
end;
DrawboxInfo;
write ('Would You like to Save Changes? y/n');
if readkey = 'y'
then begin
seek (f,filepos(f)-1);
write (f,StockRec);
end;
viewrecord;
end;
End;
Begin {main part of procedure ViewRecord}
status:=6;
assign (f,'n:\Database\Stock.dat');
reset (f);
numofrecs := filesize (f); {this gives actual number of rec}
a:=0;
Escape := false;
ShowRecord;
repeat
if keypressed then
case readkey of
#72: begin {#72 being the up button}
if a = 1 then
else
dec(a);
dec(a);
seek (f,a);
ShowRecord;
end;
#80: if eof(f) then else ShowRecord; {#80 being the down button}
#27: Escape := true; {#27 escape}
'd': DeleteRecord;
'e': AmendRecord;
end;
Until Escape;
close (f);
Return := true;
End;
(**********************************************************************)
(* PROCEDURE : Search Stock Table *)
(**********************************************************************)
Procedure StockSearch;
Var code:integer;
f:file of StockDetail;
StockRec:StockDetail;
done:boolean;
Begin
status := 6;
clrscr;
textbackground(blue);
box(29,10,56,15);
gotoxy(30,12);
write ('Enter Item Code to search');
gotoxy(30,13);
Read (code);
assign (f,'n:\Database\Stock.dat');
reset (f);
done := false;
repeat
read(f,StockRec);
if StockRec.Itemcode = code
then Begin
StockBackground;
textbackground(cyan);
gotoxy (31,4);
write (StockRec.ItemCode); {Write Item Code}
gotoxy (31,6);
write (StockRec.ItemName);
gotoxy (31,8);
write (StockRec.Price:11:2);
gotoxy (31,10);
write (StockRec.InStock);
gotoxy (31,12);
write (StockRec.MinStock);
done:=true;
end
else if eof(f)
then begin
gotoxy(30,13);
write('Nothing Found');
repeat until keypressed;
done:=true;
end;
until done;
repeat until keypressed;
close(f);
return := true;
End;
(**********************************************************************)
(* PROCEDURE : REORDER STOCK FOR STOCK TABLE *)
(**********************************************************************)
Procedure Reorder;
var StockRec :StockDetail;
f :file of StockDetail;
a :integer;
Escape,exitloop:boolean;
key:char;
Procedure ShowRecord; {Nested Procedure}
Begin
exitloop := false;
a := 0;
repeat
if eof(f) then begin
reset (f);
inc(a);
if a = 2 then begin
exitloop := true;
StockBackground;
DrawBoxInfo;
writeln ('All stock levels are OK');
write ('Press Escape');
end;
end;
read (f,StockRec);
if StockRec.InStock <= StockRec.MinStock
then begin
StockBackground;
DrawBoxInfo;
gotoxy(8,22);
write('Use Down key to scroll through Items which need Reordering');
textbackground(cyan);
gotoxy (31,4);
write (StockRec.ItemCode); {Write Item Code}
gotoxy (31,6);
write (StockRec.ItemName);
gotoxy (31,8);
write (StockRec.Price:11:2);
gotoxy (31,10);
write (StockRec.InStock);
gotoxy (31,12);
write (StockRec.MinStock);
exitloop := true;
end {end then}
else;
until exitloop;
End;
Begin
status := 6;
assign (f,'n:\Database\Stock.dat');
reset (f);
ShowRecord;
escape := false;
repeat
if keypressed then
case readkey of
#80: if eof(f) then begin
reset (f);
ShowRecord;
end
else ShowRecord; {#80 being the down key}
#27: Escape := true; {#27 escape}
end;
Until Escape;
return:=true;
End;
(**********************************************************************)
(*PROCEDURE : VIEW OR DELETE RECORD FROM SALES TABLE *)
(**********************************************************************)
Procedure ViewSalesRecord;
VAR nomerec :SalesDetail;
StockRec :StockDetail;
f :file of StockDetail;
g :file of SalesDetail;
a,lastrecnum, numofrecs:integer;
Escape,endrepeat:boolean;
key:char;
x,y:integer;{used store cursor locations}
count,store:integer;
Procedure ShowStock;
Begin
assign (f,'n:\database\Stock.dat');
endrepeat:=false;
i := 0;
repeat
inc(i);
reset(f);
read(f,StockRec);
repeat
store := nomerec.sold[i];
if store = StockRec.ItemCode
then begin
writeln (StockRec.ItemName,' ',StockRec.Price:11:2);
endrepeat := true;
end
else if eof(f)
then endrepeat := true
else read(f,StockRec);
until endrepeat;
until i = 18;
close(f);
End;
Procedure ShowRecord; {Nested Procedure}
Begin
inc(a);
read (g,nomerec);
SalesBackground;
textbackground(blue);
Box(45,13,77,18);
gotoxy(50,16);
write('Press Escape to quit');
DrawBoxInfo;
gotoxy (20,21);
write ('This is Record Number : ',a);
gotoxy (20,22);
write ('Total Number of Records: ',numofrecs);
gotoxy (20,23);
write ('Use Up/Down Keys to Scroll Through Records');
textbackground(cyan);
gotoxy (61,4);
write (nomerec.SaleCode); {Write Item Code}
gotoxy (61,6);
write (nomerec.Day,'/',nomerec.Month,'/',nomerec.Year);
gotoxy (61,8);
write (nomerec.H,':',nomerec.M,':',nomerec.S);
gotoxy (61,10);
write (nomerec.Returned);
gotoxy (61,12);
write (nomerec.Total:11:2);
gotoxy (2,2);
ShowStock;
End;
Procedure DeleteRecord;{nested Procedure}
VAR g_temp : file of SalesDetail;
count,recnum : word;
Begin
DrawBoxinfo;
Write ('Are you sure you would like to delete this record? y/n');
if readkey = 'y'
then Begin
recnum := a - 1; {the record number to delete}
reset(g);
assign(g_temp,'n:\database\Sales.tmp');
rewrite(g_temp);
for count := 0 to filesize (g) - 1 do
begin
read(g, nomerec);{read one record from the source file}
if recnum <> count
then write(g_temp, nomerec);
end; {now all records are copied to the temporary file,}
{except the one that was to be deleted.}
close(g);
erase(g);{delete the original file}
close(g_temp);
rename(g_temp,'n:\database\Sales.dat');{rename temp file to}
{orginal file name}
ViewRecord;
end;
End;
Begin {main part of procedure ViewRecord}
status:=6;
assign (g,'n:\Database\Sales.dat');
reset (g);
numofrecs := filesize (g); {this gives actual number of rec}
a:=0;
Escape := false;
ShowRecord;
repeat
if keypressed then
case readkey of
#72: begin {#72 being the up button}
if a = 1 then
else
dec(a);
dec(a);
seek (g,a);
ShowRecord;
end;
#80: if eof(g) then else ShowRecord; {#80 being the down button}
#27: Escape := true; {#27 escape}
'd': DeleteRecord;
end;
Until Escape;
close (g);
Return := true;
End;
(**********************************************************************)
(* PROCEDURE : CHECK OUT *)
(**********************************************************************)
Procedure CheckOut;
var count,code,endrepeat,lastrec,store:integer;
total:Real;
StockRec:StockDetail;
SalesRec:SalesDetail;
f:file of StockDetail;
g:file of SalesDetail;
done:boolean;
storage:ItemCodeList;
Procedure AddItem;
Begin
assign (f,'n:\Database\Stock.dat');
endrepeat := 0;
For i := 1 to 18 do
Storage[i] := 0;
x := 2;
y := 2;
total :=0;
done := false;
repeat
begin
reset(f);
DrawBoxInfo;
write ('Please enter Item Code ');
read (code);
repeat
read(f,StockRec);
if StockRec.ItemCode = code
then Begin
inc(endrepeat);
total:= total + StockRec.Price;
gotoxy(x,y);
write(StockRec.ItemName,' ','œ',StockRec.Price:11:2);
store := StockRec.ItemCode;
storage[endrepeat] := store;
inc(y);
done:=true;
end
else if eof(f)
then begin
DrawBoxInfo;
write('Error, Not Found');
delay (20000);
readkey;
done := true;
end;
until done;
DrawBoxInfo;
write ('Any more Items? y/n');
if readkey = 'y'
then done := false
else Begin
endrepeat := 18;
end;
end;
until endrepeat = 18;
end;
Procedure SubtractStock;
Begin
i := 0;
For i := 1 to 18 do
begin
store := storage[i];
if store <> 0
then begin
done := false;
reset(f);
count:=0;
repeat
read(f,StockRec);
inc(count);
if store = StockRec.ItemCode
then begin
dec(StockRec.InStock);
seek(f,count-1);
write(f,StockRec);
done := true;
end
else;
until done;
end;
end;
end;
Procedure SaveSale;
var Year,Month,Day,DayOfWeek:Word;
H,M,S,SS:Word;
Begin
assign (g,'n:\Database\Sales.dat');
reset (g);
lastrec :=pred(filesize (g));
seek (g,lastrec);
read(g,SalesRec);
GetDate (Year,Month,Day,DayOfWeek);
SalesRec.Year := Year;
SalesRec.Month := Month;
SalesRec.Day := Day;
GetTime(H,M,S,SS);
SalesRec.H := H;
SalesRec.M := M;
SalesRec.S := S;
SalesRec.Returned := false;
SalesRec.SaleCode := SalesRec.SaleCode + 1;
SalesRec.Sold := storage;
SalesRec.Total := total;
write (g,SalesRec);
close(f);
close(g);
End;
Begin {Main Part of Check Out}
status :=6;
clrscr;
AddItem;
textbackground(blue);
box(60,15,79,19);
gotoxy(64,16);
write('Total');
gotoxy(64,17);
write('œ',total:11:2);
DrawBoxInfo;
writeln ('Finalise Order? y/n');
if readkey = 'y'
then begin
SubtractStock;
SaveSale;
DrawBoxInfo;
write('Would You Like to Print Recipt? y/n');
end;
repeat until readkey = #13;
return := true;
End;
(**********************************************************************)
(* PROCEDURE : Graphical User Interface *)
(**********************************************************************)
Procedure GUI;
Begin
textcolor(yellow);
textbackground(blue);
box(2,1,79,5);
gotoxy(25,3);
write('Machine Shack Management System');
gotoxy(65,2);
write('Date:');
gotoxy(65,3);
write('Time:');
textbackground(red);
textcolor(yellow);
box(2,6,79,25);
LoadMainMenu;
End;
(**********************************************************************)
(* PROCEDURE : WRITE MENU WILL READ MENU *)
(**********************************************************************)
Procedure WriteMenu;
var yofmenu:byte;
Begin
yofmenu:=8;
textcolor(yellow);
for i:=1 to 5 do
Begin
gotoxy(30,yofmenu);
write(menu[i]);
yofmenu := yofmenu + 1;
status := 128;
End;
End;
(**********************************************************************)
(* PROCEDURE : WHERE YOUR SELECTION WILL TAKE YOU *)
(**********************************************************************)
Procedure MenuChoice;
Begin
if status=1 then if Screen = 'M' then CheckOut;
if status=1 then if Screen = 'S' then AddRecord;
if status=1 then if Screen = 'T' then ViewSalesRecord;
if status=1 then if Screen = 'O' then PasswordChange;
if status=2 then if Screen = 'M' then Begin
LoadStockMenu;
WriteMenu;
End;
if status=2 then if Screen = 'S' then ViewRecord;
if status=2 then if Screen = 'T' then;
if status=2 then if Screen = 'O' then Backup;
if status=3 then if Screen = 'M' then Begin;
LoadSalesMenu;
WriteMenu;
End;
if status=3 then if Screen = 'S' then StockSearch;
if status=3 then if Screen = 'T' then;
if status=3 then if Screen = 'O' then ResetStock;
if status=4 then if Screen = 'M' then Begin
LoadOptionMenu;
WriteMenu;
End;
if status=4 then if Screen = 'S' then Reorder;
if status=4 then if Screen = 'O' then ResetSales;
if status=5 then if Screen = 'M' then status := 6;
if status=5 then if Screen <> 'M' then Begin
LoadMainMenu;
WriteMenu;
End;
End;
(**********************************************************************)
(* PROCEDURE : MENU SCROLLING PROCEDURE *)
(**********************************************************************)
Procedure MenuSystem;
Var highlight:byte;
curchoice:byte;
yofmenu,xofmenu:byte;
Begin
xofmenu:=30;
curchoice:=1;
yofmenu:=13;
status:=128;
repeat
ShowTime;
ShowDate;
highlight := curchoice + yofmenu - 6;
gotoxy(xofmenu,highlight);
textbackground(green);
write(menu[curchoice]);
textbackground(Red);
textcolor(yellow);
if keypressed then
case readkey of
#72: if curchoice>1 then begin {#72 being the up button}
gotoxy(xofmenu,highlight);
write(menu[curchoice]);
dec(curchoice);
end;
#80: if curchoice<5 then begin {#80 bein the down button}
gotoxy(xofmenu,highlight);
write(menu[curchoice]);
inc(curchoice);
end;
#27: status:=5; {#27 escape}
#13: status:=curchoice; {#13 enter}
end;
MenuChoice;
until status=6;
End;
(**********************************************************************)
(* PROGRAM : MAIN BODY *)
(**********************************************************************)
Begin
textbackground(black);
textcolor(white);
clrscr;
access := false;
restart := false;
tries := 0;
password;
if access = true {GRANT ACCESS IF PASSWORD CORRECT}
then
begin
Repeat {THIS LOOP WILL RETURN YOU TO THE MAIN MENU}
Return := false;
textbackground(black);
clrscr;
GUI;
WriteMenu;
MenuSystem;
Until Return = false;
end;
End.
System Testing
System Testing
A Test Plan, Test Data and expected results for typical, erroneous and extreme data has been mentioned at the end of design.
Test 1
Auto Boot Feature runs perfectly and brings up the password screen
Test 2
password Screen
Password box only accepts ‘hello’
Test 3
All menu Options work fine and bring up the correct selections
Main Menu
Test 4
All data sets from data set 1 enter correctly and which incident
Add Item Menu
Test 5
Only accepts Unique Item Code and gives error message if a item code is entered which already exists
Add Item Menu, with error message
Test 6
View Feature Runs Properly and shows all records that where entered
View Edit Delete Menu
Test 7
Third data set was edited successfully without error.
View Edit Delete Menu with error message
Test 8
8th dataset was deleted success fully leaving 9 records in the stock table.
View Edit Delete Screen
Test 9
Check out give correct total
CheckOut Screen
Test 10
Password change feature changes password correctly and when the system is reset it accepts the new password and not the old one only.
Enter New Password Screen
Test 11
Exit feature works correctly and the database returns to MS-DOS as expected.
Dos
Test 12
Extremely large number entered into add record, Item Code field but the program did not crash
Add Item Menu with large number entered
it simply accepted the value, but when I viewed it in the view screen it came up as a 3 digit number
View Edit Delete Menu
This is probably due to an overflow.
Test 13
Entering a character in a numerical field causes the program to crash
Program Crash
Test 14
Entering more that 20 characters in the Name Description field simply cases the program to accept the first 20 characters entered.
Add Edit View Menu
System Maintenance
System Maintenance
Summary of the features of the package used
The package that was used to create the system is turbo pascal. Two standard libraries were used the CRT unit and the DOS unit, for this system mainly the CRT unit was used, the only feature the dos unit was used for is to get the date and time.
Global Variables
Type FiveChar = array[1..5] of char;
This is a file character array which holds the password when read from password.dat
Type StockDetail = record {Type for Stock Table}
ItemCode,InStock,MinStock:integer;
ItemName:string[20];
Price:real;
end;
This is the Variable Type used to access the stock table file stock.dat
Type List = array[1..18] of integer;
Type SalesDetail = record {Type for Sales Table}
SaleCode:integer;
Sold:List;
Returned:boolean;
Year,Month,Day:word;
end;
This is the Variable Type used to access the sales table file sales.dat
b,i,x,y:integer; These are various integers used to hold temporary data through out the program
status:byte; This is used in the main menu where status := 6 closes the main menu and status 1 takes it to the main menu
access,Return,restart:boolean; Used for various loops thorough out the program
tries:integer; Used to store the amount of time you have entered the password
Screen:char; Used to Know what screen your on M being the main menu, S the stock table menu, T the sales table menu and O the options menu
Procedures
Box: this is used to create a box
Password: This is made up of two procedures which are used to run the password.
PasswordChange: This is used to change the password
LoadMainMenu: This is used to load what menu will be loaded
ShowTime: This will get the Time, and show it on screen
ShowDate: This will get the Date, and show it on screen
Backup: This is used to backup the database to a floppy disk
Reset Stock/Sales: This is used to create a new stock/sales file, or delete or previous records and start a new file.
AddRecord: Used to add a record to stock table
View Amend Delete: This is used to view, edit or delete records in the stock table
Stock Search: Used to search stock table
Reorder: Used to view items which need reordering
ViewSalesRecord: used to view sales records
DeleteRecord: used to delete a sales record
Checkout: will add up to give a total, subtract from stock and add sale record
MenuChoice: This will decide what an option does in the menu
MenuSystem: Used to make the scrolling feature in the menu system work
User Manual
User Manual
Introduction
The software is designed to keep track off all stock and sales, which at the same time has a check out feature that produces a receipt and total price of items to be sold. It has been designed to run on a MS-DOS system.
Installation
The system has been designed so that it will start automatically when the computer boots, if not you will have to add the path to the program manually to the autoexec.bat file located at the root of the c:\
Security and Password
Once the system has been installed successfully you will be taken to password screen whenever your system boots
The password when the system is installed is “hello”. It is strictly recommended you change you password as soon as possible. (password change is explained later on in the manual). Remember you will only get 3 attempt to enter the password correctly after which if password is still incorrect the system will lock, you will have to restart the system to re-enter the password again.
Main Menu
Once the password has been correctly entered you will be taken to the main menu, here you can use the menu system to get to any part of the system.
Use the up and down keys to move the highlight bar to highlight different options once you have highlighted the desired option you simply press enter to select it.
Stock Table
Selecting the Stock Table Option on the main menu will take you to the Stock Table Menu.
Adding Stock
Once you select the Add Stock Option you will be taken to the add stock form here you simply enter the stock details (remember you will have to enter a unique Item code which is not in use, else you will get a prompt telling you its already in use).
You simply enter a detail and press enter to move to the next option, if you make an error, when you reach the end and are prompted do you want to save simply press ‘n’ else press ‘y’ to save the record.
View, Edit or Delete Stock
Selecting View Edit Delete on the Stock Table Menu will take you to the menu where you can view files which are in the stock table. Scroll through records by using the up and down keys.
Pressing ‘e’ will allow you to edit the current record on display and pressing delete will delete the record on display, press escape will take you back to the main menu.
Search Stock Table
Select the Search Option on the Stock Table Menu and it will bring up a box asking you to enter Item Code.
Entering Item Code will take you to the record in Stock Table with that Item Code.
View Stock Needing Reordering
Selecting View Reorder Stock on the Stock Table Menu, will take you to the area where you can scroll through Stock Records which need reordering if there are no items Needing reordering you will get a message saying ‘No Items Need Reordering’.
Check Out
Selecting the check out option will take you to the check out menu it will prompt you to enter an item code
Changing your password
You will have to go to the change Password option in the options menu, its pretty straight forward, you will be prompted to enter your current password first if correct you can enter your new Passoword.
Backing up your database
You will have to go to the backup option in the options menu, insert a formatted floppy disk into the system when prompted and your database will be copied to your floppy.
Restoring your database
Simply copy files back from the floppy disk to your program folder and overwrite and files with the same name.
Troubleshooting
Program Crashes?
There are a number of Reasons why this will happen but the main reasons would :-
- You have entered a character in a numerical field
- You have deleted or manually modified the stock.dat file or the sales.dat file, (to fix this you have to reset your database)
- You have entered the password incorrect 3 times, (you will have to simply restart your computer)
Error Messages
The “Item Code already Exists” Error message will come up when you enter an item code which already exists, to continue you must enter an item code which does not exist in the stock table.
Appraisal
Appraisal
Project performance against initial objectives:
The following list shows what areas of the initial objectives where successful and what areas where unsuccessful.
- Posse the ability to store details about stock that is available.
- Log every sale that is made.
- Have the capability to identify items using a code.
- A method of alerting when certain type of stock is running low and needs reordering.
- Allow items which have been sold to be returned and re-added to the stock if possible.
- Produce a receipt after every sale.
- At the end of every week the sales can be backed up on an external source.
- System must be easy to use and have a clean interface.
- Be hard if not impossible to make changes that will cause the system to not function or cause any type disruption.
- Have a secure protection system so no one except Mr Robertson can access the system.
- Be able to run on basic computer hardware.
As you can see from the list of objectives only one point was unsuccessful implemented which was printing a receipt through the system. The main reason for this is that I did not have enough time because I had to spend more time on other parts of the system then expected and I did not get round to this part in time. This objective would have been a little tricky to implement as it would require an external library and printer drivers to support it.
Possible extensions and improvements to the system
When evaluating the system I created there is plenty of room for improvement and possibilities of extending capabilities however the system is adequate for the purposes it was designed for. Possible extensions that can be added to improve/enhance the system include
- Allow user to sort files in alphabetical order
This would require a binary search would have advantages over a sequential search most importantly the speed at which records can be found.
Instead of typing in a Item code each time, the items could just be scanned for a bar code to make data entry faster.
This would make navigating the system even easier.
- Allow password length to be variable
In this database since the password was held in an array it could only be a certain length in this case 5 characters. Making password a variable length would give it more security.
User Feedback
The System was given to Mr. Robertson who decided to use it as a test for one day, after his test, he concluded:-
- The System was a bit awkward to use at first when compared to his traditional method, but was easy and straight forward.
- He had to do less work then he normally would have to do.
- System did crash once, when he accidentally entered characters in an integer field.
Finally Mr. Robertson said that overall he was happy with the system, and that after a few modifications to prevent the crashes, he was happy to use it as his primary business tool.
Final evaluation
The system which has been created here will nonetheless help Mr Robertson, as it will be much faster then the manual way he use to run his business first. We looking at the system as a whole I think it was pretty successful and it meets the needs of the prospective users pretty much, however if I spent more time on developing it, a more efficient and better system could have been created.