You are on page 1of 37

BTEC HNC YEAR 2

PROGRAMMING
ASSIGNMENT No 2
By David Koncewicz
HCCA4203
CONTENTS

INTRODUCTION ................................ Page 1


SUMMARY

USING THE PROGRAM .......................... Page 2

PSEUDO CODE ................................. Page 3

THE PROJECT FILES ........................ Page 4

TESTING / PROBLEMS ...................... Page 5

FILE PRINTOUT RESULTS ...................... Page 6

CONCLUSION .................................... Page 7


BIBLIOGRAPHY
APPENDIX (the code listing)
Programming assignment 2 - HCCA4203 Page 1.

INTRODUCTION
This report gives a brief description on the construction of the program ‘Wibbly Wobbly
Stock System’ that I have w ritten using the ‘C’ language. The program allow s a user to input
data or load data from a file called ‘Toydata.dta’. A user can then add a new product, add a
stock item, remove a stock item or delete a w hole record containing the toy product details.
Tw o linked list are used, one for the toydata, and one for the transactions i.e. adding a stock
item etc...

The program w as w ritten using the Borland v2 IDE C++ compiler, on a 486 processor, 12mb
machine. See appendix for the code listing.

SUMMARY
The program could have been w ritten using a tree structure as opposed to the linked list that I
used, as this seems to be a better method of storing, ordering and retrieving data, how ever,
as this is a small project in comparison, the list seems to w ork quite w ell.

I could have w ritten the program to make the functions more general, but time constraints and
lack of know ledge at the time prevented this.
Programming assignment 2 - HCCA4203 Page 2.

USING THE PROGRAM


When the program is executed, the main menu is displayed. There are six options to choose
from:

1. [L] Loads the toydata (main) file.


2. [S] Gives a sub menu choice to save toy data, transaction, re-order list files.
3. [V] Gives a sub choice to view on screen, the transactions and inventory.
4. [T] Displays a few statistics such as the amount of records stored.
5. [E] Gives sub choices to add a product, add/remove a stock and delete a record.
6. [X] Exits the program.

The program is quite self explanatory, and should be quite easy to navigate. When view ing
the inventory on screen, any products that need reordering are show n in red text. There are
pop-up menus to display messages, to help if any errors occur. See Fig 1 for database
w indow .

Fig 1. Screen menu area.

Wibbly wobbly stock system

Status line/prompts

Menus and area for viewing inventory

Bottom of menu area is also used for messages and prompts/input


Programming assignment 2 - HCCA4203 Page 3.

PSEUDO CODE
Loading the file

If able to locate and load file.


while not end of file
Read line product code
Read line description
Read line stock, reorder level and price
create a node and assign data

Create a node and the data assign data

if no existing nodes
If memory available
create first node and use as a dummy first node
make pointer to last = null
make pointer to next = null

If memory available
create another node

Make pointer last point to first dummy node


Make pointer next point to the first dummy nodes next
Assign the data to node variables

Adding a new product

While user makes a valid input and wishes to continue


Input the product code, description, stock, reorder level & price

(insert sort)
while node product code < next node product code and node not reached end
node = node next

if product code user input is not already used


create a node and assign data

Create transaction node

If no existing node
If memory available
create first node
make pointer to next = null
else
If memory available
create another node

make new node pointer to next point to current node next


make current pointer next point to new pointer
Programming assignment 2 - HCCA4203 Page 4.

assign the transaction data to node variables


make current node pointer static in order insert next new node.
Programming assignment 2 - HCCA4203 Page 5.

THE PROJECT FILES


To help understand the following, it is suggested tha t you first run the program.

The stock system program is divided into eight files:

1.RECORD.H
2.WIBMAIN.CPP
3.WIBMENU.CPP
4.FILEHAND.CPP
5.NODES.CPP
6.NEWPROD.CPP
7.EDITREC.CPP
8.PRINTINV.CPP

These file are grouped w ithin the project file name WIB001.PRJ, and are described as
follow s:

 RECORD.H contains all the function prototypes, constants, enums and global variables
declarations (see RECORD.H for description and use of variables).

 WIBMAIN.CPP contains the user selection routines for adding, removing, saving files etc.
The global variables are also defined here. These global variables are used as temporary
storage betw een file reading and user input before assigning the data to a node.

 WIBMENU.CPP contains most of the screen user options, pop-up box, header and footer
text. I found by doing this, made it easier to co-ordinate the w indow positions, colours and
text. Functions in the other files also contain text, but most of this text is passed to
functions w ithin this file that do the alignment such as the header and footer text. I
created a function called CtrTxt, that centres the text in relation to the main assigned
screen area.

 FILEHAND.CPP as you might have guessed, contains all the functions for loading and
saving the toydata, transaction and re-order files. The files, w hen printed, show the
appropriate headings and footers etc...

 NODES.CPP contains the functions involved in creating, adding and deleting the nodes. It
also has tw o functions for adding the data to the toy and transaction nodes.

 NEWPROD allow s the user to create a new product. After all the details such as the
product cod, description etc... have been entered, the user has a choice to save the
record or exit the function. The product code can be a combination of numbers or letters,
and w hen entered, are converted to capitals w here appropriate. If the code is less than
six digits, the remainder is filled w ith appending 0s, not necessary, but makes it look a bit
tidier w hen view ing the records. The stock digits have been restricted ( see RECORD.H
constants), this w as mainly for cosmetic purposes, but also to help prevent an overflow
situation should a user fall a sleep w ith their finger on the numeric key w hile inputting!!!.
Programming assignment 2 - HCCA4203 Page 6.

 EDITREC.CPP contains the functions used to enable the user to add, remove stock and
delete a record. The inputs the product code (which can be a combination of letters or
numbers) and match it w ith the corresponding ‘code in the node ‘, this is then passed to
the required function determined by an enum ID (see code RECORD.H) passed by the
variable ‘flag’ form the selected option w ithin WIBMAIN.CPP. Warning messages are give if
a user tries to remove more than in stock. It also w arns is a re-order is required

 PRINTINV.CPP contains functions for printing the data on screen. It prints a max of n
lines at a time. When max n lines (full page) has been reached, the screen is halted,
giving the user a chance to exit or continue. This also occurs if the end of the linked list is
reached (otherwise viewing a page < max n would not be possible). When the list
reaches the end the pointer to the list is re-initialised to list start again, thus allow ing a
continuous loop of the data.

TESTING / PROBLEMS
I had to include an if statement in the save toydata function that prints the \n character, this
w as because I found that the extra line that w as created by placing in w ithin the same fprintf
function that prints the actual data, caused the last record to be duplicated w hen re-loading.

I also had to place the routine of creating the head node, w ithin the function that inserts each
node.
This w as because on terminating the program, a ‘null pointer assignment’ message w as
being generated w hich did not seem ‘safe’. The reason w hy I mention this is because by
placing the head node identifier w ithin this function, makes it less general, but as most of the
functions how ever, are specific to this program anyw ay, It does not make much difference.

Testing w as done mainly by inputting data and view ing it using the IDEs w atch and debug
facilities.

Letters w ere input w here numbers expected to test bad input w as not being passed to the
nodes.

When adding to a stock value, I found a negative number w as resulting due to the int signed
value being change by overflow . This prompted me to change from int to long int. Although I
restricted the number of digits that can be input, adding stock items could still have produce
this error.
Programming assignment 2 - HCCA4203 Page 7.

FILE PRINTOUT RESULTS


Printout of the toy data main file (TOYDATA.DTA)

1000001 1 1 1.00
120345Meccano Master Set 10 2 49.99
120346Scalectric Racers 10 2 69.99
120350P ower Rangers Set 10 5 29.99
120355Junior Monopoly 12 5 12.99
120360Junior Master Chef 10 3 17.99
120365Hornby Train Set 12 5 64.99
120368Chemistry Set 5 2 24.99
120370Cry Baby Doll 10 5 19.99
120380Action Man Set 5 5 16.99
120385Lego Set 10 5 24.99
120386Dumper Truck 5 2 19.99
120387Junior Artist Set 5 2 34.99
120390Mini Cricket Set 8 2 26.99
120400Steve Davis Snooker 7 2 44.99
120410Sooty and Sweep 10 2 12.99
120411Barbie Doll Set 8 5 17.99
120412Junior Drum Kit 5 2 39.99
120420Warrior Battle Set 10 2 12.99
120440P aint by Numbers 6 2 12.99
120445Mini Keyboard 8 2 24.99
120446Junior Golf Set 6 2 69.99
120460Cowboy Suit 1 2 0.00

Printout or the transaction report (TRANS.RPT)

Transaction File

Code Transaction Units Date Time

120355 Added to stock 2 Sat Jun 01 16:50

Total transactions = 1

Printout or the re-order report (REORDER.RPT)

Reorder List
Code Description Stock O/L P rice
100000 1 1 1 2 1.00
120380 Action Man Set 5 5 16.99
120460 Cowboy Suit 1 2 0.00
Programming assignment 2 - HCCA4203 Page 8.

CONCLUSION
The program could best be implemented using a tree structure, but to lack of time, prevented
this as I w as not sure as to how to go about this at the time, how ever, as this is a small
project in comparison, the list seems quite sufficient.

The programs functions could also have be made more ‘general’, but again, due to time
constraints and lack of know ledge at the time, I found I w as unable to achieve this for most of
the functions. The use of more type casting etc. w ould have aided this.

BIBLIOGRAPHY
Comprehensive C - By David Spuler

Illustrating C - By Donald Alcock


Programming assignment 2 - HCCA4203 Page 9.

APPENDIX
The follow ing pages contain the code listing.
RECORD.H

// filename RECORD.H - D. KONCEWICZ 1/4/96


/***************************************************************************
***
The declarations in this header file are used by two or more files.
Constants & enums will be in block caps, globals in 'semi block caps'.
****************************************************************************
**/

const int DESSIZE = 20; // Max product description chars etc..


const int CODSIZE = 6; // Max product code chars etc..
const int STKDIGIT = 5; // max I/P stock & level digit length
const int PRIDIGIT = 6; // max I/P price digit length
// restricted for cosmetic purposes only!

const char TRANSFILE[] = {"Trans.rpt"}; // Transaction save filename


const char REORDFILE[] = {"Reorder.rpt"}; // Re-order "" ""

/* Const - avoid pre-processor, someone told me these worked more


efficiently
than defines? */

//--------------------------------------------------------------------------
---
// The #defines

// Used for code and description I/P - see filename NEWPROD.CPP &
EDITREC.CPP
#define APENDZEROS(co) (strncat(co, "000000", ( (CODSIZE) -strlen(co))))
#define CAPSTR(s) {for (int i = 0; s[i] != NULL ; i++) s[i] =
toupper(s[i]);}
//--------------------------------------------------------------------------
---
// The enums.

/* Used for adding stock, removing stock, new product & delete product
-directs
func edit_reccord (see EDITREC.CPP) to appropriate func, also used for a
transaction type */
typedef enum { NEWPROD, ADDSTOK, REMSTOK, DELPROD } flag;

//--------------------------------------------------------------------------
---
// The structures.

/* Holds required data in form of a linked list - see filename NODES.CPP


for list creation, deletion etc.. */

Page 1/3
RECORD.H

typedef struct rec_nod{


// The toydata node

char code[CODSIZE+1]; // Product code


char desc[DESSIZE+1]; // "" description
long stock; // stock level
long level; // re-order level
float price;
struct rec_nod *next; // Next in list
struct rec_nod *last; // Last "" ""

}*rec_type;

typedef struct tr_nod{


// The transaction node

flag trtype; // See 'The enums'


char prodcod[CODSIZE+1];
long units;
char time[16]; // The data and time!
struct tr_nod *next;

}*tr_type;

//--------------------------------------------------------------------------
---
// The function prototypes.

/// Defined in filename NODES.CPP


rec_type mak_rec_nod(rec_type); // Create toydata node
tr_type mak_TR_nod( void ); // "" transaction node
rec_type del_rec_nod(rec_type); // Delete toydata node

// Assign data to toydata & transaction nodes


rec_type ass_rec_dat(rec_type, char*, char*, long, long, float);
void ass_TR_dat(tr_type, flag, char*, long );

// Defined in filename FILEHAND.CPP


void load_fil(char *); // Load toydata file
void save_rec_fil( void ); // Save toydata file
void save_TR_fil( void ); // "" transaction file
void save_reor_fil( void ); // "" re-order report

// Defined in filename PRINTSCR.CPP


void prt_TR_scr(void ); // Print transaction screen
void prt_prod_scr( void ); // "" product screen
void prt_stats_scr(void); // "" statistics

Page 2/3
RECORD.H

// Defined in NEWPROD.CPP
void add_new_prod( void ); // User add a new product

// Defined in EDITREC.CPP
void edit_record(flag mode); // User add/remove stock etc..

// Defined in filename MIBMENU.CPP - screen menu text etc..


void MainTxt( void ); // Start-up main menu
void ClrWind( void ); // Clear menu area
void ItemScr( void ); // For I/P new product
void ViewTrScr(void ); // For viewing transactions
void SaveOptScr( void ); // Sub menu choice save files
void ViewOptScr( void); // "" "" "" view data
void EditOptScr( void); // "" "" "" edit
records
void MsgBox(char *msg); // Pop-up message box
void HeadTxt(char *msg); // Header ""
void FootTxt(char *msg); // Footer ""

//--------------------------------------------------------------------------
---
// The global variables - defined in WIBMAIN.CPP.

extern char *DatFile; // Hold data file name passed


by argv
extern rec_type Dummy1stNod; // Head pointer to toydata list
extern tr_type FirstTR; // "" "" to transaction
list

/* Assigned to, before passing on to node, when for example, reading in from
file - used in files FILEHAND.CPP, NODES.CPP & NEWPROD.CPP */
extern char Buff[]; // Temp buffer for cgets I/P
extern char Opt; // Hold user I/P option
extern char Cod[]; // Product code
extern char Des[]; // Description
extern long Stk; // Stock
extern long Lev; // Re-order level
extern float Pri; // Price
// end file

Page 3/3
WIBMAIN.CPP

// file WIBMAIN.CPP/WIB-000.PRJ - D. KONCEWICZ 1/4/96

/***************************************************************************
***
Program Wibly Wobbly Stock Control system.
gives a user the following choices (see also filename WIBMENU.CPP):

A new product to be inserted,


A component to be deleted,
Adding of stock,
Removal of stock,
Printing an inventory.

The program then performs the listed tasks

The function prototypes and their locations can be found in RECORD.H


where the structures are also defined.

This file contains the main menu options and sub options
/***************************************************************************
*/

#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <dos.h> // For delay
#include "record.h"

//--------------------------------------------------------------------------
---
/* Global - used for assignment before passing on to struct vars.
for example reading in and writing to the files */

char *DatFile = {"dummy.fil"}; // The main toy data file


char Opt; // Assign user a
option
char Buff[DESSIZE+3]; // Temp buffer for I/P
cgets
char Cod[CODSIZE+1]; // Product code
char Des[DESSIZE+1]; // Description
long Stk; // stock
long Lev; // Re-order level
float Pri; // Unit price

//--------------------------------------------------------------------------
---
// Pointers to head nodes for transactions and toydata lists

Page 1/4
WIBMAIN.CPP

tr_type FirstTR = NULL;


rec_type Dummy1stNod = NULL;

//--------------------------------------------------------------------------
---

void start_scr(); // Call start up screen


void sub_choice_edit( void ); // Sub option menues
void sub_choice_save_fil( void );
void sub_choice_view( void );

void main(int argc, char *argv[]){ // Also takes filename from


command
/***************************************************************************
***
User select required func. Delay retains messages on screen. Char 'E'
terminates program. See filename MAINMENU.CPP most screen text etc.
****************************************************************************
**/

start_scr(); // Introduction screen

for (; Opt != 'X';){

MainTxt(); // See filename


MAINMENU.CPP
HeadTxt("Please select an option:");
_setcursortype(_NOCURSOR);

switch ((Opt = toupper(getch()))){

case 'L' : load_fil(argv[1]); break;


case 'S' : sub_choice_save_fil(); break;
case 'V' : sub_choice_view(); break;
case 'E' : sub_choice_edit() ; break;
case 'T' : prt_stats_scr(); break;
}
}

MsgBox("Thank you for trying WibWob Stock System"); delay(1500);


window(1,1,80,25); textbackground(BLACK);
clrscr(); _setcursortype(_NORMALCURSOR);

argc = argc; // stop warning message

Page 2/4
WIBMAIN.CPP

};

void sub_choice_edit( void ){


/***************************************************************************
***
Options to add, remove stock etc..
See filename EDITREC.CPP for edit_record()
See filename NEWPROD.CPP for add_new_prod()
****************************************************************************
**/

// Sub menu text - see filename MAINMENU.CPP


EditOptScr();

switch(toupper((Opt = getch()))){

case 'N': add_new_prod(); break;// Add a new product


case 'A': edit_record(ADDSTOK); break;// Add to stock
case 'R': edit_record(REMSTOK); break;// Remove from stock
case 'D': edit_record(DELPROD); break;// Delete a record ; break;
}
};

void sub_choice_save_fil(){
/***************************************************************************
***
Options to save a file type. See filename FILEHAND.CPP
****************************************************************************
**/

if (Dummy1stNod != NULL){ // Not if list empty


// Sub menu text - see filename MAINMENU.CPP
SaveOptScr();

switch(toupper((Opt = getch()))){

case 'R': save_rec_fil() ; break; // Save toy data


case 'O': save_reor_fil(); break; // Save reorder file
case 'T': save_TR_fil() ; break; // Save transaction file
}
}
else{
MsgBox("Error: NO records to save!");delay(1500);
}
};

void sub_choice_view( void ){

Page 3/4
WIBMAIN.CPP

/***************************************************************************
***
Options view a list type - See filename PRINTSCR.CPP
****************************************************************************
**/

if (Dummy1stNod != NULL){ // Not if list empty

// Sub menu text - see filename MAINMENU.CPP


ViewOptScr();

switch(toupper((Opt = getch()))){

case 'R': prt_prod_scr(); break; // Display toy data on screen


case 'T': prt_TR_scr() ; break; // Display transactions on
screen
}
}
else{
MsgBox("Error: NO Records to view!");delay(1500);
}
};
//End file

Page 4/4
WIBMENU.CPP

Wibbly Wobbly

Page 1/1
FILEHAND.CPP

// file FILEHAND.CPP - D. KONCEWICZ 1/4/96

#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include "record.h"

void load_fil(char * argvname){


/***************************************************************************
***
Load the main toy data file.
****************************************************************************
**/

if (Dummy1stNod == NULL){ // Not if data already in


memory

if (argvname != NULL) // If command file name


passed
DatFile = argvname;

FILE *stream; fflush(stream);

// Open read only


if ( (stream = fopen(DatFile,"r")) != NULL ){

rec_type ptr = Dummy1stNod;

while( !feof(stream) ){

fgets(Cod, CODSIZE+1, stream); // Read code of 6 char's


spaces
fgets(Des, DESSIZE+1, stream); // Read description 20
char's +spcs
fscanf(stream, "%ld%ld%f", &Stk,// Read stock, reorder lev
& price
&Lev,
&Pri);
fgetc(stream);
ptr = ass_rec_dat(mak_rec_nod(ptr), Cod, Des, Stk, Lev,
Pri);
}
MsgBox("File successfully loaded");
}
else{
MsgBox(strerror(errno)); // The standard error
message

Page 1/4
FILEHAND.CPP

clearerr(stream);
}

fclose(stream); delay(1500);
}
else
MsgBox("Error: File/Data already loaded!");delay(1500);
};

void save_rec_fil( void ){


/***************************************************************************
***
Save the toy data file. The if cput(' ') avoids an extra line at eof,
which
causes duplicated last node on re-load !!.
****************************************************************************
**/

rec_type ptr = Dummy1stNod->next; // Assign first in list

FILE *stream = fopen(DatFile, "w+t"); // Open a file for update


fflush(stream);

while (ptr != NULL ){


fprintf(stream, "%-*s%-*s%-2ld %-2ld %-2.2f", CODSIZE, ptr->code,

DESSIZE, ptr->desc,

ptr->stock,

ptr->level,

ptr->price);
ptr = ptr->next;

if( ptr != NULL) // Avoid extra line


at eof
putc('\n', stream);
}
fclose(stream);

};

void save_reor_fil( void ){


/***************************************************************************
***

Page 2/4
FILEHAND.CPP

Save the re-order list.


****************************************************************************
**/

rec_type ptr = Dummy1stNod->next;

FILE *stream = fopen(REORDFILE, "w+t"); // Open a file for update


fflush(stream);

fputs("Reorder List\n", stream);


fputs("Code Description Stock O/L Price\n", stream);

while (ptr != NULL ){

if(ptr->stock <= ptr->level){ // shows reorder level in red


fprintf(stream, "%-*s %-*s %-*ld %-*ld %-2.2f\n", CODSIZE,
ptr->code,

DESSIZE, ptr->desc,

STKDIGIT, ptr->stock,

STKDIGIT, ptr->level,

ptr->price);
}
ptr = ptr->next;
}
fclose(stream);
};

void save_TR_fil( void ){


/***************************************************************************
***
Save transaction file, prints the appropriate transaction depending on the
assigned enum in var prodcodes within the transaction node.
****************************************************************************
**/

if (FirstTR != NULL){

tr_type ptr = FirstTR;


long tcount = 0;
// Open a file
for update
FILE *stream = fopen(TRANSFILE, "w+t");
fflush(stream);

Page 3/4
FILEHAND.CPP

fputs("Transaction File\n\n" ,stream);


fputs("Code Transaction Units Date Time\n\n"
,stream);

while (ptr != NULL ){

fputs(ptr->prodcod, stream);

switch(ptr->trtype){

case NEWPROD : fputs(" New product ", stream);break;


case ADDSTOK : fputs(" Added to stock ", stream);break;
case REMSTOK : fputs(" Removed stock ", stream);break;
case DELPROD : fputs(" Deleted Comp. ", stream);break;
}

fprintf(stream, "%-*ld %.16s\n", STKDIGIT, ptr->units,

ptr->time);
ptr = ptr->next; tcount++;
}

fprintf(stream, "\nTotal transactions = %-ld", tcount);


fclose(stream);
}
};
// end file

Page 4/4
NODES.CPP

// file NODES.CPP - D. KONCEWICZ 1/4/96

#include <stdlib.h>
#include <string.h>
#include <time.h> // For transaction time
#include "record.h"

void *new_node(int size){


/***************************************************************************
***
Creates a new node. This was tested by reducing the heap size to 4k within
the Borland IDE, and then reloading the file - appending to list several
times.
****************************************************************************
**/

void * memoptr;
// Test for available memory
if(! (memoptr = malloc(size)) ){
MsgBox(strerror(errno));
exit (-1);
}
return memoptr;
};

rec_type mak_rec_nod(rec_type curptr){


/***************************************************************************
***
Add to the toydata link list. Insert node after.
****************************************************************************
**/

rec_type newptr;

// Create dummy head node for the list


if (Dummy1stNod == NULL){ // New node
newptr = (rec_type) new_node(sizeof(rec_nod));
Dummy1stNod = curptr = newptr;
Dummy1stNod->next = Dummy1stNod->last = NULL;
}
// New node
newptr = (rec_type) new_node(sizeof(rec_nod));
newptr->next = curptr->next; // New ptr now also points to
current's next
newptr->last = curptr ; // New ptr placed in front of current
curptr->next = newptr ; // Current now last, points to new ptr

Page 1/3
NODES.CPP

return (newptr);
};

rec_type del_rec_nod(rec_type curptr){


/***************************************************************************
***
Delete a node in link list. The pointer to be deleted is passed, the node
Before and the node after are joined before the passed pointer is deleted.
****************************************************************************
**/

// Join last and next node


curptr->last->next = curptr->next;
// Next node points to the
previous node
curptr->next->last = curptr->last;

free(curptr);

return (curptr = NULL); // Clear uninitialised ptr.


};

tr_type mak_TR_nod( void ){


/***************************************************************************
***
Creates the transaction link list. A static var is used to keep current
Pointer position each time the fuct is entered, allowing a transaction
To be inserted into correct next position in list (saves a bit of code).
****************************************************************************
**/

tr_type newptr;
static tr_type curptr; // Current pointer position save on exit

if (FirstTR == NULL){ // Create the headnode


FirstTR = newptr = (tr_type) new_node(sizeof(tr_nod));
FirstTR->next = NULL;
}
else{ // New node
newptr = (tr_type) new_node(sizeof(tr_nod));

newptr->next = curptr->next;// New ptr now also points to current's


next
curptr->next = newptr ; // Current now last, points to new ptr
}
// Save pointer position in static ready for next insert

Page 2/3
NODES.CPP

return (curptr = newptr);

};

rec_type ass_rec_dat
(rec_type ptr, char *co, char *de, long st, long lv,
float pr){
/***************************************************************************
***
Assign the I/P toy data to the new node.
****************************************************************************
**/

strcpy(ptr->code, co);
strcpy(ptr->desc, de);
ptr->stock = st;
ptr->level = lv;
ptr->price= pr;
return ptr;
};

void ass_TR_dat(tr_type ptr, flag tr, char *co, long unit){


/***************************************************************************
***
Assign the I/P transaction data to the new node
Assigns the data and time to new transaction.
****************************************************************************
**/

time_t t; // The time!


t = time(NULL);
time(&t);

ptr->trtype = tr;
strcpy(ptr->prodcod, co);
ptr->units = unit;
strncpy(ptr->time, ctime(&t),16);

};
// end file

Page 3/3
NEWPROD.CPP

// file NEWPROD.CPP - D. KONCEWICZ 1/4/96

#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <dos.h>
#include "record.h"

void insert_sort( void );

void add_new_prod( void ){


/***************************************************************************
***
User inputs each field consecutively. Option at and of loop gives user a
chance to save, redo or save/exit. Stings are copied from I/P buffer to
global vars and when necessary, converted to correct format using
sscanf.
The fuct exits if a null string I/P on any of the fields. The global
vars
Cod, Desc, Stk, Lev & Pri are used as intemidiate storage before passing
to func insert_sort. This func sorts the data in code order after which
two nodes are created, one for the record and one for the transaction
see NODES.CPP insert_data_node().
****************************************************************************
**/
#ifdef TEST
//cputs("test new_product\r\n");
#endif

for(;;){

FootTxt("[RTN]=exit (no string)");


HeadTxt("ENTER NEW PRODUCT DETAILS");
ItemScr();
_setcursortype(_NORMALCURSOR);
fflush(stdin);

// There's space for 6 characters plus the NULL terminator


Buff[0] = CODSIZE+1; // Allow I/P of codesize
string only
// Null or bad I/P
string will exit func
if (sscanf(cgets(Buff),"%s", Cod) >= 1){

CAPSTR(Cod); APENDZEROS(Cod); // Change into caps,append


leading 0s

Page 1/3
NEWPROD.CPP

// see RECORD.H
defines */

// Buffer for 20 characters plus the NULL terminator


cputs("\r\n\n"); // Moves cursor down to
match field text
Buff[0] = DESSIZE+1;
// Strlen check for
NULL I/P
if (*strcpy(Des, cgets(Buff)) != NULL){

cputs("\r\n\n");
Buff[0] = STKDIGIT+1;
// Convert to long and
assign
if (sscanf(cgets(Buff),"%ld", &Stk) >= 1){

cputs("\r\n\n");
Buff[0] = STKDIGIT+1;
// Convert to long and
assign
if (sscanf(cgets(Buff),"%ld", &Lev) >= 1){

cputs("\r\n\n");
Buff[0] = PRIDIGIT+1;
// Convert to float and
assign
if (sscanf(cgets(Buff),"%f", &Pri) >= 1){

_setcursortype(_NOCURSOR);
FootTxt("");
HeadTxt("[RTN]=next [ANY]=redo [ESC]=exit");
Opt = getche();
// save if user requires
if (Opt == 27 || Opt == 13){
HeadTxt("Save this record [ESC]=cancel?");
// Create node & insert
(code order)
if ((getch()) != 27){
insert_sort();
break;
}
else
break; // Just break
}
}else break;
}else break;

Page 2/3
NEWPROD.CPP

}else break; // Exit func if null or bad


input // Strlen check for
NULL I/P
}else break;
}else break;
}// End for loop
};

void insert_sort(void){
/***************************************************************************
***
Inserts a node in ascending code order. loops through list break when next
highest number found or last node reached. Node is inserted between
highest
and lowest (obviously) - see NODES.CPP mak_rec_nod(). The data is passed
via parameters using global vars Cod, Desc, Stk, Lev & Pri for I/P
****************************************************************************
**/

int compcode = 1; // Check for duplicate code


number
rec_type ptr = Dummy1stNod;

while (ptr->next != NULL ){ // Until last node


// Next higher found
if ((compcode = strcmp(Cod, ptr->next->code)) <= 0 )
break;

ptr = ptr->next;
}

if (compcode == 0){ // Check for a 'code'


duplication
MsgBox("Error: Duplicated Code"); delay(1500);
}
else{
// Create node and assign data, create also, a transaction node &
data.
ass_rec_dat( mak_rec_nod(ptr), Cod, Des, Stk, Lev, Pri);
ass_TR_dat( mak_TR_nod(), NEWPROD, Cod, Stk);
}
};
// end file

Page 3/3
EDITREC.CPP

// file EDITREC.CPP - D. KONCEWICZ 1/4/96


#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include "record.h"

void prt_result(rec_type p); // print selected record on


screen
void add_stock( rec_type ); // Add stock items
void rem_stock( rec_type ); // remove stck items
void del_prod( rec_type ); // delete node

void edit_record(flag mode){


/***************************************************************************
***
This func gets code I/P from user, while loops until code match found or
end of list reached, if end of list reached and no match, a messege
states
this, if match, break from while loop (ptr at current position), and
pass
for amendment of stock level, delete a node, remove from the stock. The
apropiate function is determined by the global enum passsed via var
mode.
Before exit of func a transaction node is created (if edit successful).
****************************************************************************
**/

if (Dummy1stNod != NULL){ // Only if data in memory

HeadTxt("Please enter the product code");

for(;;){

rec_type ptr = Dummy1stNod;

FootTxt("[RTN]=Exit (no string)");


ItemScr();
_setcursortype(_SOLIDCURSOR);

fflush(stdin);
Buff[0] = CODSIZE+1;

if (sscanf(cgets(Buff),"%s", Cod) >= 1){

Page 1/4
EDITREC.CPP

CAPSTR(Cod); APENDZEROS(Cod); // See RECORD.H #defines

// Match code with link


node
while (ptr != NULL && strcmp(ptr->code, Cod) != 0)
ptr = ptr->next;

if (ptr != NULL){ // Ignore switch if no code


match

// Display selected record on screen

ItemScr();prt_result(ptr);
_setcursortype(_SOLIDCURSOR);

// pass to Add stock, Remove component or Delete a


record
switch(mode){

case ADDSTOK : add_stock(ptr); break;


case REMSTOK : rem_stock(ptr); break;
case DELPROD : del_prod(ptr); break;
}
// Add to transaction
list
ass_TR_dat(mak_TR_nod(), mode, Cod, Stk);

}
else{ MsgBox("No matching code");delay(500);
prt_prod_scr(); HeadTxt("Please enter the product
code");

}
}else break;

}// end for


}
else{ MsgBox("Error: NO existing records!");delay(1000); }
};

void add_stock(rec_type ptr){


/***************************************************************************
***
Add stock item to record.
****************************************************************************
**/

Page 2/4
EDITREC.CPP

HeadTxt("ADD UNITS");
FootTxt("Specify unit amount to add:");
Buff[0] = STKDIGIT+1;

if (sscanf(cgets(Buff),"%ld", &Stk) >= 1){

ptr->stock +=Stk; // Update node stock var


// Display update on
screen
prt_result(ptr);
FootTxt("Units added, press anykey..."); getch();
}
};

void rem_stock(rec_type ptr){


/***************************************************************************
***
Remove stock item from record. Warnings given if removing more stock than
exist or if stack falls below re-order level.
****************************************************************************
**/

HeadTxt("REMOVE UNITS");
FootTxt("Specify unit amount to remove:");
Buff[0] = STKDIGIT+1;

if (sscanf(cgets(Buff),"%ld", &Stk) >= 1){

if ( ptr->stock - Stk > 0){

ptr->stock -=Stk; // Update node stock var

if (ptr->stock <= ptr->level){


MsgBox("Re- Order this stock item");delay(1500);
}
// Display update on
screen
prt_result(ptr);
FootTxt("Units removed, press anykey..."); getch();

}
else{
MsgBox("Cannot remove more stock than exist!");delay(1500);
}
}
};

Page 3/4
EDITREC.CPP

void del_prod(rec_type ptr){


/***************************************************************************
***
Delete a arecord.
****************************************************************************
**/
_setcursortype(_NOCURSOR); ItemScr();
HeadTxt("DELETE PRODUCT");
HeadTxt("Delete this record [Y]");
if( (Opt = toupper(getch()) ) == 'Y'){
Stk = ptr->stock;
// Pass for deletion see filename NODES.CPP
ptr = del_rec_nod(ptr); // Null is returned to this ptr
FootTxt("Deleted, press anykey..."); getch();
}
};

void prt_result(rec_type p){


/***************************************************************************
***
Display selected record on screen. Used again to show update.
****************************************************************************
**/

_setcursortype(_NOCURSOR); ItemScr();
cprintf("%-*s\r\n\n%-*s\r\n\n%-*ld\r\n\n%-*ld\r\n\n%-*.2f",

CODSIZE, p->code,
DESSIZE, p->desc,
STKDIGIT, p->stock,
STKDIGIT, p->level,
PRIDIGIT, p->price);
};
// end file

Page 4/4
PRINTSCR.CPP

// filename PRINTINV.CPP - D. KONCEWICZ 1/4/96

#include <conio.h>
#include <string.h>
#include "record.h"

/***************************************************************************
***
Prints the stock list on screen, MAXLINES at a time. Displayed with
heading
all within main boarder see WIBMENU.CPP

This function loops through the list displaying a page of MAXLINES


at a time. When it reaches the end of the list ptr, it is re-inio
to first in list again, thus repeating the list from start.

The data text colour is white, unless a reorder is required, in this


case
it is printed in red.
****************************************************************************
**/

const int MAXLINES = 10; // Limit lines printed on screen

void prt_prod_scr( void ){

FootTxt("Products/Order List(red) [Any]=next [ESC]=exit");


HeadTxt("Code Description Stock O/L Price ");

ClrWind(); // Create area for list


// see file MIBMENU.CPP
int lines = 1;//

for (rec_type ptr = Dummy1stNod->next ;; ){

// Full page or last records in list


if (lines > MAXLINES || ptr == NULL){

if ((Opt = getch()) != 27){


lines = 1; clrscr();

// Last page of list, then back to first page again


if (ptr == NULL)
ptr = Dummy1stNod->next;
}
else
break; // Else Esc to exit

Page 1/4
PRINTSCR.CPP

}
else{
if(ptr->stock <= ptr->level) // Shows reorder level in red
textcolor(LIGHTRED); // Else in white
else
textcolor(WHITE);

cprintf("%-*s %-*s %-*ld %-*ld œ%-*.2f\r\n", CODSIZE,


ptr->code,

DESSIZE, ptr->desc,

STKDIGIT, ptr->stock,

STKDIGIT, ptr->level,

PRIDIGIT, ptr->price);
ptr = ptr->next; lines++;
}
}
};

void prt_TR_scr( void ){


/***************************************************************************
***
Display the transactions made (similar to func prt_prod_scr), print
transactions depending on assign enum to node
****************************************************************************
**/

int lines = 1;//

FootTxt("Transactions List [ESC]=exit");


HeadTxt("Prod Description Units Date Time");
ClrWind();

for (tr_type ptr = FirstTR ;;){

if (lines > MAXLINES || ptr == NULL){

if ((Opt = getch()) != 27){

lines = 1;
clrscr();

if (ptr == NULL)
ptr = FirstTR;

Page 2/4
PRINTSCR.CPP

}
else
break;
}
else{
cprintf(" %-*s", CODSIZE, ptr->prodcod);

switch(ptr->trtype){

case NEWPROD : cputs(" New product ");break;


case ADDSTOK : cputs(" Added to stock ");break;
case REMSTOK : cputs(" Removed stock ");break;
case DELPROD : cputs(" Deleted Comp. ");break;
}

cprintf("%-*ld %.16s\r\n", STKDIGIT, ptr->units,


ptr->time);
ptr = ptr->next; lines++;
}
}
};

void prt_stats_scr(){

/***************************************************************************
***
Prints on screen statistic info, the total records in memory, amount of
re-orders required to bring one above re-order levels, total transactions
and total inventory value.
****************************************************************************
**/

long totrec, tottrn, calreor;


float totval;
// Vars for record, transaction, reorder & total cost.
totrec = tottrn = calreor = totval= 0;

HeadTxt("Statistics"); FootTxt("[ESC]=exit"); ClrWind();

// Count records & total up inventory £val


for (rec_type rptr = Dummy1stNod->next; rptr != NULL ; rptr =
rptr->next){
totval+= rptr->price * rptr->stock; totrec++;

// Count re-orders
required
if (rptr->stock <= rptr->level){

Page 3/4
PRINTSCR.CPP

calreor+= (rptr->level - rptr->stock)+1;


}
}
// Total up transactions
for (tr_type tptr = FirstTR; tptr != NULL; tptr = tptr->next){
tottrn++;
}

cprintf("\r\n\n Total records %ld (residing in memory)", totrec);


cprintf("\r\n\n The inventory value is œ%-2.2f in total", totval);
cprintf("\r\n\n At least %ld products need to be re-ordered",calreor);
cprintf("\r\n\n A total of %ld transactions are recorded", tottrn);

for (; getch() != 27;); // Hold screen


};
// end file

Page 4/4

You might also like