Code:
/*------------------------------------------------------
StockChk.C
--------------------------------------------------------
*/
// Date Change
//
// 06/09/99 Updated for multiple lookups per product code.
// Upload file renamed to HHTINPUT.CSV
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
typedef unsigned char bool;
#define true (unsigned char)'\xFF'
#define false (unsigned char)'\0'
#define LCD 0x10
#define BS 8
#define CR 0x0D
#define ENTER 13
#define BELL 7
#define SPACE 0x20
#define F1 (unsigned char) 0x86 // F1 key
#define F2 (unsigned char) 0x87 // F2 key
#define F3 (unsigned char) 0x88 // F3 key
#define F4 (unsigned char) 0x89 // F4 key
#define EXIT (unsigned char) 0x84 // EXIT key
#define ALPHA 0
#define NUMERIC 1
#define ALPHANUMERIC 2
#define INTEGER 3
#define UNKNOWN 0
#define STOCKCHECK 1
#define PRICECHECK 2
#define GOODSIN 3
#define ORDERCREATE 4
#define STATE_LOOKUP 0
#define STATE_FOUND 1
#define STATE_PACKCOUNT 3
#define STATE_PRICECHECK 10
#define STATE_SAVEDATA 98
#define STATE_EXIT 99
#define _O_BINARY 0x8000 // AB
#define _O_RDONLY 0x0000 // AB
#pragma pack(1)
typedef unsigned char UCHAR;
typedef struct header
{
char Stock;
char Price;
char Goods;
char Order;
char Data[12];
} HEADER;
typedef struct dat
{
char StockCode[8];
char Description[30];
float UnitPrice;
int UnitOfSale;
double UnitCount;
int PackCount;
float PriceChk;
int OrderQty;
} DATAREC;
typedef struct idx
{
char BarCode[13];
long RecPtr;
} IDXREC;
bool CheckKeypad(int len_limit);
bool CheckScanner(int col, int row, int len_limit);
bool ChkHeader(void);
void EnableScanner(int type);
bool FindBarCode(void);
void GetData(int col,int row,int len);
void getData(IDXREC *IdxRec);
bool getIndex(long index);
bool GetKeypad(int x, int y, int len_limit, int mode, char defaultstr[16]);
void InitScanner(void);
void LookUp(void);
void Menu(void);
void Message(char *String);
void PowerSave(void);
bool SetProgMode(void);
void Show(int x, int y, char *String);
void ShowHeading(void);
int StateLookup(void);
int StateFound(void);
int StatePackCount(void);
int StatePriceCheck(void);
int StateSaveData(void);
int ValidKey(char c, int mode);
void cls(void);
void gotoxy(int col, int row);
void setfont(int mode);
int disk_space(void);
void error_beep(void);
char STR_INPUT[40];
int CUR_COL, CUR_ROW;
int SCAN_ORIGIN;
int YY,MM,DD,HH,MIN;
union REGS inregs,outregs,regs;
struct SREGS segregs;
HEADER HeaderRec;
DATAREC DataRec;
IDXREC IdxRec;
int hIndex;
int hData;
char DataFileName[] = "HHT.DAT";
char IndexFileName[] = "HHTIDX.DAT";
char HeaderFileName[] = "HEADER.DAT";
char UploadFile[] = "HHTINPUT.CSV";
static int ProgMode;
static long NumRecs;
static long DatPtr;
bool multiple;
char UoSStr[10];
char PriceStr[10];
char DescStr[32];
//------------------------------------------------------------------------------
//
// Main entry point for hand held terminal program.
//
//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
InitScanner();
for (;;)
{
if (!SetProgMode())
{
return 0;
}
if (!ChkHeader())
{
Message("Not Available\nwith this\ndata file");
continue;
}
if (disk_space() < 2)
{
Message("DISK FULL!");
}
else
{
LookUp();
}
}
return 0;
}
//------------------------------------------------------------------------------
//
// Main stock code search routine
//
//------------------------------------------------------------------------------
void LookUp(void)
{
int state = STATE_LOOKUP;
for (;;)
{
switch(state)
{
case STATE_LOOKUP: // Look up bar code
state = StateLookup();
break;
case STATE_FOUND: // found it;
state = StateFound();
break;
case STATE_PACKCOUNT: // Pack count
state = StatePackCount();
break;
case STATE_PRICECHECK: // Price Check;
state = StatePriceCheck();
break;
case STATE_SAVEDATA: // Save data
state = StateSaveData();
break;
case STATE_EXIT: // Exit
return;
}
}
}
//------------------------------------------------------------------------------
//
// StateLookup - LookUp state processor for level 0
//
//------------------------------------------------------------------------------
int StateLookup(void)
{
bool add = false;
ShowHeading();
Show(0, 1, "Scan Code: ");
GetData(0,2,13);
if ((unsigned char)STR_INPUT[0] == EXIT || !strcmp(STR_INPUT,"END"))
{
return STATE_EXIT;
}
if (!strcmp(HeaderRec.Data,"NODATA"))
{
add = true;
}
else
{
if (FindBarCode())
{
memset(DescStr, 0, sizeof(DescStr));
strncpy(DescStr,DataRec.Description,30);
Show(0, 5, " ");
Show(0, 6, " ");
Show(0, 6, DescStr);
}
else
{
error_beep();
Show(0, 5, " Code NOT ");
Show(0, 6, " Recognised ");
Show(0, 7, "Add it[1=Y/0=N]");
while(!add)
{
switch(getch())
{
case '1':
add = true;
Show(0, 5, " ");
Show(0, 6, " ");
Show(0, 7, "Code Added ");
break;
case '0':
Show(0, 5, " ");
Show(0, 6, " ");
Show(0, 7, " ");
return 0;
}
}
}
}
if (add)
{
memset(&DataRec,0,sizeof(DataRec));
// strncpy(DataRec.StockCode, STR_INPUT, 13);
strncpy(IdxRec.BarCode, STR_INPUT, 13);
strncpy(DataRec.StockCode, "NONE", 8);
DataRec.Description[0] = '\0';
DataRec.UnitPrice = -90;
DataRec.UnitOfSale = -1;
DataRec.UnitCount = -99;
DataRec.PackCount = -99;
DataRec.PriceChk = 0;
DataRec.OrderQty = 0;
Show(0, 6, DataRec.StockCode);
}
if (ProgMode == PRICECHECK)
return STATE_PRICECHECK;
return STATE_FOUND;
}
//------------------------------------------------------------------------------
//
// StateFound - Enter units of found or added product
//
//------------------------------------------------------------------------------
int StateFound(void)
{
double Qty;
int iQty;
switch(DataRec.UnitOfSale)
{
case 0:
strcpy(UoSStr,"Value");
break;
case 2:
strcpy(UoSStr,"Length");
break;
case 3:
strcpy(UoSStr,"Weight");
break;
case 4:
strcpy(UoSStr,"Volume");
break;
default:
strcpy(UoSStr,"Quantity");
break;
}
if (ProgMode == ORDERCREATE)
strcpy(UoSStr,"Quantity");
Show(0, 3, " ");
gotoxy(0,3);
printf("%-s:",UoSStr);
if (DataRec.UnitOfSale == 7)
{
Show(0, 5, "F2 for Pack ");
}
GetKeypad(0,4,8,NUMERIC,"1");
if ((unsigned char)STR_INPUT[0] == F2)
{
if (DataRec.UnitOfSale != 7)
{
error_beep();
Show(0, 5, "Pack qty NOT ");
Show(0, 6, "allowed ");
return STATE_FOUND;
}
else
{
return STATE_PACKCOUNT;
}
}
switch (ProgMode)
{
case ORDERCREATE:
DataRec.OrderQty = atoi(STR_INPUT);
break;
case GOODSIN:
iQty = atoi(STR_INPUT);
DataRec.OrderQty += iQty;
break;
case STOCKCHECK:
Qty = atof(STR_INPUT);
if (DataRec.UnitCount == (double) -99)
DataRec.UnitCount = Qty;
else
DataRec.UnitCount += Qty;
break;
}
return STATE_SAVEDATA;
}
//------------------------------------------------------------------------------
//
// State3 - Lookup state 3 processor
//
//------------------------------------------------------------------------------
int StatePackCount(void)
{
gotoxy(0,5);
printf("F2 for %-8s",UoSStr);
Show(0, 3, "Pack Count: ");
GetKeypad(0,4,6,INTEGER,"1");
if ((unsigned char)STR_INPUT[0] == F2)
{
return STATE_FOUND;
}
if (DataRec.PackCount == (double) -99)
DataRec.PackCount = atoi(STR_INPUT);
else
DataRec.PackCount += atoi(STR_INPUT);
return STATE_SAVEDATA;
}
//------------------------------------------------------------------------------
//
// State10 - Lookup state 10 processor
//
//------------------------------------------------------------------------------
int StatePriceCheck(void)
{
Show(0, 3, "Unit Price:");
gotoxy(0,4);
sprintf(PriceStr,"%1.2f",DataRec.UnitPrice);
GetKeypad(0,4,8,NUMERIC,PriceStr);
DataRec.PriceChk = (float) atof(STR_INPUT);
return STATE_SAVEDATA;
}
//------------------------------------------------------------------------------
//
// State98 - Write a recrd to the upload file
//
//------------------------------------------------------------------------------
int StateSaveData(void)
{
FILE *fadded;
if ((fadded = fopen(UploadFile,"a")) == NULL)
{
Show(0, 6, "Can't open\nUpload File");
getch();
return STATE_EXIT;
}
if (DataRec.UnitCount == (int) (DataRec.UnitCount))
sprintf(PriceStr,"%.0f",DataRec.UnitCount);
else
sprintf(PriceStr,"%.2f",DataRec.UnitCount);
//=====================================
if (DataRec.StockCode != "NONE ")
{
fprintf(fadded,"\"%s\",\"%s\",%1.2f,%d,%s,%d,%1.2f,%d\n",
DataRec.StockCode,
DataRec.Description, DataRec.UnitPrice,
DataRec.UnitOfSale, PriceStr,
DataRec.PackCount, DataRec.PriceChk,
DataRec.OrderQty);
}
else
{
fprintf(fadded,"\"%s\",\"%s\",%1.2f,%d,%s,%d,%1.2f,%d\n",
IdxRec.BarCode,
DataRec.Description, DataRec.UnitPrice,
DataRec.UnitOfSale, PriceStr,
DataRec.PackCount, DataRec.PriceChk,
DataRec.OrderQty);
}
fclose(fadded);
return STATE_LOOKUP;
}
//------------------------------------------------------------------------------
//
// Search HHTIDX.DAT for a matching bar code
//
//------------------------------------------------------------------------------
bool FindBarCode(void)
{
char BarCode[13];
long vLow, vHigh, vPtr;
bool found = false;
int ret;
long index;
long indexLow;
long indexHigh;
bool done;
UCHAR c;
memset (BarCode, 0, sizeof(BarCode));
strncpy(BarCode,STR_INPUT,13);
hIndex = open(IndexFileName, _O_RDONLY|_O_BINARY);
vHigh = _filelength(hIndex);
if (vHigh == 0l)
{
close(hIndex);
return false;
}
vHigh = (long) (vHigh / (int) sizeof(IdxRec));
vLow = 0;
vHigh--;
indexHigh = vHigh;
for (;;)
{
vPtr = (long) ((vHigh + vLow) / 2);
if (!getIndex(vPtr))
{
break;
}
ret = strncmp(IdxRec.BarCode,BarCode,13);
if (!ret)
{
found = true;
break;
}
if (vLow == vHigh)
{
break;
}
if (ret < 0)
{
if (vLow == (vHigh - 1))
vLow++;
else
vLow = vPtr;
}
else
vHigh = vPtr;
}
if (found)
{
hData = open ("HHT.DAT", _O_RDONLY|_O_BINARY);
done = false;
index = vPtr;
while(index > 0 && !done)
{
index--;
if (!getIndex(index))
{
done = true;
}
else
{
if (memcmp(BarCode, IdxRec.BarCode, 13) != 0)
{
index++;
done = true;
}
}
}
indexLow = index;
if (index < indexHigh)
{
getIndex(index+1);
if (memcmp(BarCode, IdxRec.BarCode, 13) == 0)
{
error_beep();
Show(0, 5, "Multiple lookup");
hData = open ("HHT.DAT", _O_RDONLY|_O_BINARY);
do
{
getIndex(index);
if (memcmp(BarCode, IdxRec.BarCode, 13) != 0)
{
error_beep();
index = indexLow;
getIndex(index);
}
getData(&IdxRec);
memset(DescStr, 0, sizeof(DescStr));
strncpy(DescStr,DataRec.Description,30);
Show(0, 6, " ");
Show(0, 6, DescStr);
do
{
c = getch();
} while (c != F1 && c != ENTER && c != F2);
if (c == F2)
{
index++;
if (index > indexHigh)
{
error_beep();
index = indexLow;
}
}
} while(c != ENTER && c != F1);
if (c == F1)
{
found = false;
}
}
}
if (found)
{
getIndex(index);
getData(&IdxRec);
}
close(hData);
}
close(hIndex);
return found;
}
void getData(IDXREC *IdxRec)
{
long vPtr;
vPtr = (long) (IdxRec->RecPtr * sizeof(DataRec));
lseek(hData,vPtr,0);
read(hData,&DataRec,sizeof(DataRec));
}
bool getIndex(long index)
{
lseek(hIndex,(long)(index * sizeof(IdxRec)),0);
if (read(hIndex,&IdxRec,sizeof(IdxRec)) != sizeof(IdxRec))
{
error_beep();
Show (0, 4, "read failure");
return false;
}
return true;
}
bool GetKeypad(int x, int y, int len_limit, int mode, char defaultstr[16])
{
int c,offset=0,COMPLETE=0;
memset(STR_INPUT,0,sizeof(STR_INPUT));
strcpy(STR_INPUT,defaultstr);
Show(x, y, defaultstr);
for (c = strlen(defaultstr); c < len_limit; c++)
putchar('_');
CUR_COL = x + offset;
CUR_ROW = y;
gotoxy(CUR_COL,CUR_ROW);
while (!COMPLETE)
{
switch(c=getch())
{
case BS:
if (offset==0) // back space
error_beep();
else
{
offset--;
CUR_COL--;
gotoxy(CUR_COL,CUR_ROW);
putchar('_');
gotoxy(CUR_COL,CUR_ROW);
}
break;
case ENTER:
COMPLETE=1;
break;
case EXIT :
case F1:
case F2:
case F3:
case F4:
COMPLETE= 1;
STR_INPUT[0] = c;
offset=1;
break;
default:
if (offset==len_limit)
break;
if (ValidKey((char)c, mode))
{
STR_INPUT[offset]=c;
gotoxy(CUR_COL,CUR_ROW);
putchar(c);
offset++;
CUR_COL++;
}
else
error_beep();;
break;
} // switch (c=getch())
} // while (!COMPELET)
// STR_INPUT[offset]='\0'; // string delimiter
return(1);
}
//------------------------------------------------------------------------------
//
// GetData - Input data from keyboard or barcode
//
//------------------------------------------------------------------------------
void GetData(int col,int row,int len)
{
int v_i;
EnableScanner(SCAN_ORIGIN);
CUR_COL=col;
CUR_ROW=row;
gotoxy(CUR_COL, CUR_ROW);
for (v_i = 0; v_i < len; v_i++)
putchar('_');
gotoxy(CUR_COL, CUR_ROW);
PowerSave();
while(!CheckScanner(col,row,len) && !CheckKeypad(len))
{
PowerSave();
}
EnableScanner(0);
}
//------------------------------------------------------------------------------
//
// CheckScanner - Check for pending scanner data
//
//------------------------------------------------------------------------------
bool CheckScanner(int col, int row, int len_limit)
{
char str_bar[32];
inregs.x.dx=(int)str_bar;
segread(&segregs);
inregs.h.ah=0x50;
intdosx(&inregs,&outregs,&segregs);
if (outregs.h.al==0)
{
if (strlen(str_bar) > (unsigned int)len_limit)
error_beep();
else
{
if (strlen(str_bar) == 14)
strcpy(STR_INPUT,&str_bar[1]);
else
strcpy(STR_INPUT,str_bar);
gotoxy(col,row);
printf("%s",STR_INPUT);
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
//
// CheckKeypad - Get keyboard input
//
//------------------------------------------------------------------------------
bool CheckKeypad(int len_limit)
{
int c,offset=0,COMPLETE=0;
int saveX, saveY;
if (kbhit()==0) // check first key pressing
return false;
saveX = CUR_COL;
saveY = CUR_ROW;
while(!COMPLETE)
{
switch(c=getch())
{
case BS:
if (offset==0) // back space
error_beep();
else
{
offset--;
CUR_COL--;
gotoxy(CUR_COL,CUR_ROW);
putchar('_');
gotoxy(CUR_COL,CUR_ROW);
}
break;
case ENTER:
COMPLETE=1;
break;
case EXIT :
case F1:
case F2:
case F3:
case F4:
COMPLETE= 1;
STR_INPUT[0] = c;
offset=1;
break;
default:
if ( (c>='0' && c<='9') || (c>='A' && c<='Z') ||
(c>='a' && c<='z') )
{
STR_INPUT[offset]=c;
gotoxy(CUR_COL,CUR_ROW);
putchar(c);
offset++;
CUR_COL++;
if (offset==len_limit)
COMPLETE=1;
}
else
error_beep();
break;
} // switch (c=getch())
} // while (!COMPELET)
STR_INPUT[offset]='\0'; // string delimiter
if (strlen(STR_INPUT) == 14)
{
for (c = 0; STR_INPUT[c]; c++)
STR_INPUT[c] = STR_INPUT[c+1];
gotoxy(saveX,saveY);
printf("%-14s",STR_INPUT);
}
return true;
}
int ValidKey(char c, int mode)
{
switch (mode)
{
case ALPHA:
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
return 1;
else
return 0;
case NUMERIC:
if (c == '.')
return 1;
// Fall through
case INTEGER:
if (c >= '0' && c <='9')
return 1;
else
return 0;
case ALPHANUMERIC:
if ((c == '.') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
return 1;
else
return 0;
}
}
//------------------------------------------------------------------------------
//
// Display the amount of space left on the RAM disk
//
//------------------------------------------------------------------------------
void display_space(void)
{
int space;
regs.h.ah=0x36;
regs.h.al=0;
intdos(®s,®s);
space = (int) regs.x.bx;
cls();
gotoxy(0,4);
printf("Available RAM Disk \nSpace %dKb",disk_space());
getch();
}
/*--------------------- get_time ----------------*/
void get_time()
{
inregs.h.ah=0x2A;
intdos(&inregs,&outregs);
YY=outregs.x.cx;
MM=outregs.h.dh;
DD=outregs.h.dl;
inregs.h.ah=0x2C;
intdos(&inregs,&outregs);
HH=outregs.h.ch;
MIN=outregs.h.cl;
}
//------------------------------------------------------------------------------
//
// Check that the data header record is valid for the program mode selected.
//
//------------------------------------------------------------------------------
bool ChkHeader(void)
{
int fin;
if ((fin = open(HeaderFileName,_O_RDONLY|_O_BINARY)) == -1)
{
Message("Cannot Open\nHeader File");
exit(1);
}
if (read(fin,&HeaderRec,sizeof(HeaderRec)) != sizeof(HeaderRec))
{
Message("Read Error\nHeader File");
close(fin);
exit(1);
}
close(fin);
if (ProgMode == STOCKCHECK && HeaderRec.Stock == '1')
{
return true;
}
if (ProgMode == PRICECHECK && HeaderRec.Price == '1')
{
return true;
}
if (ProgMode == GOODSIN && HeaderRec.Goods == '1')
{
return true;
}
if (ProgMode == ORDERCREATE && HeaderRec.Order == '1')
{
return true;
}
return false;
}
bool SetProgMode(void)
{
for(ProgMode = UNKNOWN; ProgMode == UNKNOWN;)
{
Menu();
switch(getch())
{
case '1':
ProgMode = STOCKCHECK;
break;
case '2':
ProgMode = PRICECHECK;
break;
case '3':
ProgMode = GOODSIN;
break;
case '4':
ProgMode = ORDERCREATE;
break;
case EXIT:
return false;
}
}
return true;
}
void Menu(void)
{
cls();
printf("Select Function");
Show(0, 2, "1 Stock Check");
Show(0, 3, "2 Price Check");
Show(0, 4, "3 Goods In");
Show(0, 5, "4 Order Create");
Show(0, 7, "ESC Exit");
}
void Message(char *String)
{
cls();
printf(String);
getch();
}
void ShowHeading(void)
{
cls();
if (ProgMode == STOCKCHECK)
Show(0, 0, " STOCK CHECK");
if (ProgMode == PRICECHECK)
Show(0, 0, " PRICE CHECK");
if (ProgMode == ORDERCREATE)
Show(0, 0, " SET ORDER ");
if (ProgMode == GOODSIN)
Show(0, 0, " GOODS IN");
}
void Show(int x, int y, char *String)
{
gotoxy(x, y);
printf(String);
}
//------------------------------------------------------------------------------
//
// gotoxy - Position cursor
//
//------------------------------------------------------------------------------
void gotoxy(int col, int row) // move cursor
{
regs.h.ah=2;
regs.h.bh=0;
regs.h.dh=(unsigned char)row;
regs.h.dl=(unsigned char)col;
int86(LCD,®s,®s);
}
void cls(void) // clear screen
{
regs.h.ah=0;
int86(LCD,®s,®s);
}
void setfont(int mode)
{
regs.h.ah = mode;
int86(0x09,®s,®s);
}
int disk_space(void)
{
int space;
regs.h.ah=0x36;
regs.h.al=0;
intdos(®s,®s);
space = (int) regs.x.bx;
return (space);
}
void error_beep(void)
{
regs.x.ax = 0;
regs.x.bx = 6;
int86(0x31,®s,®s);
}
void setenvp() {} // disable Microsoft Environment
void PowerSave(void) // enter power saving mode
{
int86(0x22,®s,®s);
}
void EnableScanner(int type)
{
regs.h.ah=0x51;
regs.h.al=type;
intdos(®s, ®s);
}
void InitScanner(void)
{
SCAN_ORIGIN = 2; // hard set to "Auto"
// Set Symbologies etc
regs.h.ah = 0x1f;
regs.h.bh = 3;
regs.h.bl = 0x011;
regs.h.al = 13;
intdos(®s,®s);
regs.h.ah = 0x1f;
regs.h.bh = 3;
regs.h.bl = 0x012;
regs.h.al = 9;
intdos(®s,®s);
setfont(1);
// EnableScanner(SCAN_ORIGIN);
}