home *** CD-ROM | disk | FTP | other *** search
- /*#############################################################################
- DEMO.DO
- dObject Demonstration Application
-
- This is a simple doctor's office manager program that keeps
- track of offices, doctors, doctor assignments to one or more
- offices, patients, and patient visits. It is intended to
- be an example of how to write an application to use DBF files
- with menus, windows, and data entry forms using dObject.
-
- NOTE - you must first run the supplied "CRDEMO.DO" program
- to create the DBF files used by this application
-
- Copyright (c) 1991 Intelligent Systems Research
- License is granted to copy or modify this program freely
- #############################################################################*/
- #include "keydef.do"
-
- /*
- a stub for functions not implemented yet
- */
- method Nil::tbd()
- {
- w = new(Window,1,79,79," Not Implemented ",5,5,6,50);
- ? "This function has not been implemented\nPress any key to continue...";
- inkey();
- remove(w);
- }
-
-
- /*
- this method validates that a doctor is assigned to an office
- self is the cost center id
- f2 is the Doctor id
- there should be a record in the officed table for these two values
- */
- method Int::validDoctor(self,f2)
- {
- officed = new(Dbffile,"officed");
- setFilter(officed,#(ccenter == self & docid == f2));
- top(officed);
- if(recno(officed) <= 0L) {
- w = new(Window,1,79,79," Error ",5,5,6,60);
- display(asString(self)+asString(f2)
- + asString(recno(officed))
- + " Doctor is not assigned to this office");
- remove(w);
- }
- close(officed);
- }
-
-
- /*
- this method sets the "scale" value in a form to the scale for a patient
- self = database being appended to
- w = window for data entry form
- mcaseno = case number to look up rate for
- */
- method Dbffile::defaultRate(self,w,mcaseno)
- {
- db = new(Dbffile,"billrate");
- locate(db,"caseno",mcaseno);
- mscale = rate;
- close(db);
- select(self);
- scale = mscale;
- draw(w);
- }
-
- /*
- this method implements a data entry form for appending a new
- record to the DBF file in self, similar to the DBASE append
- command
- */
- method Dbffile::append(self)
- {
- /*
- put up a status line on the bottom of the screen
- */
- w = currentWindow();
- say(status,0,0,"Fill in the fields for the new "+trim(name(self))
- +" record F10:Accept ESC:Quit",80,112);
- select(w);
-
- /*
- construct the field definitions from the structure of the
- DBF file being appended to
- */
- clearGets(currentWindow());
- l = structure(self); % returns a Collection of field def Collections
- for(i=1;i<=numFields(self);i=i+1) {
- field_def = at(l,i);
- fieldname = at(field_def,1); % field name is first element
- say(currentWindow(),i,1,fieldname,10,112);
- width = at(field_def,3); % field width is third element
- if(at(field_def,2)=='D') width = width+2;
- f = new(Field,w,i,15,fieldname,width,79);
-
- /*
- assign field hot keys based on the field being defined
- */
- if(trim(fieldname) == "docid")
- onKey(f,RETURN,#validDoctor(program,docid));
- if(trim(fieldname) == "CASENO")
- onKey(f,RETURN,#defaultRate(self,w,caseno));
- }
-
- /*
- assign a hot key for the window
- if the F8 key is pressed, invoke the myEdit method to display
- the contents of the current field in a scrollable window
- */
- onKey(w,F8,#myEdit(currentWindow()));
-
- /*
- loop processing keystrokes (use the read() method)
- read() returns the last key pressed from the data entry form
- */
- setFilter(self,#F); % this disallows any scrolling
- key = read(currentWindow());
- if(key == F10) {
- write(self,0L);
- say(status,0,0,"Record added; press any key...",80,112);
- inkey();
- }
- }
-
- /*
- this method implements a pop-up scrollable display of a field
- value within a data entry form; see Int::onKey() to see how to
- assign this to a particular hot key
- */
- method Window::myEdit(self)
- {
- f = currentField(self);
- s = asString(eval(asId(name(f)))); % returns value of current field
- w = new(Window,1,112,112,name(f),5,5,10,40);
- display(s); % change this to edit(s) for an editor
- remove(w);
- cursor(self,row(self),col(self)); % re-displays the cursor
- }
-
-
- /*
- this method asks the user for a CASENO value to locate, then does
- a record-by-record scan of the DBF file in self
- w = current window that data entry form is displayed in
- */
- method Dbffile::myLocate(self,w)
- {
- w2 = new(Window,1,112,112," LOCATE ",5,5,4,20);
- set("softseek",T);
- s = accept("CASENO ? ");
- top(self);
- locate(self,"caseno",s);
- remove(w2);
- draw(w);
- gotoField(w,currentField(w));
- }
-
- /*
- edit the visits for a patient
- */
- method Dbffile::editVisits(self,case)
- {
- w = currentWindow();
- visit = new(Dbffile,"visit");
- setFilter(visit,#trim(caseno)==case);
- top(visit);
- w2 = new(Window,2,112,112," VISIT(s) FOR "+case+" ",6,9,16,40);
- edit(visit,w2);
- close(visit);
- remove(w2);
- select(w);
- gotoField(w,firstField(w));
- }
-
- /*
- edit the bill rates for a patient
- */
- method Dbffile::editRates(self,case)
- {
- w = currentWindow();
- billrate = new(Dbffile,"billrate");
- setFilter(billrate,#trim(caseno)==case);
- top(billrate);
- w2 = new(Window,2,112,112," Billing Rate(s) FOR "+case+" ",9,9,10,40);
- edit(billrate,w2);
- close(billrate);
- remove(w2);
- select(w);
- gotoField(w,firstField(w));
- }
-
- /*
- edit the Doctors assigned to an office (cost center)
- */
- method Dbffile::editWorkers(self,ccenter)
- {
- w = currentWindow();
- doctor = new(Dbffile,"doctor");
- top(doctor);
- w2 = new(Window,2,112,112," Doctor(s) ",9,9,10,60);
- edit(doctor,w2);
- close(doctor);
- remove(w2);
- select(w);
- gotoField(w,firstField(w));
- }
-
-
- /*
- edit a Dbffile using a full screen editor
- */
- method Dbffile::edit(self,w)
- {
- /*
- create a status line showing the user what functions/keys are
- available from within the data entry form
- the status line depends on the name of the DBF file being edited
- (this is NOT very generic !)
- */
- cw = currentWindow();
- line = "HOME:Top PgUp:Next PgDn:Prev END:Bot F3:Find F4:Update F10:Exit";
- switch(name(self)) {
- case "PATIENT.DBF": line =
- "HOME:Top PgUp:Nxt PgDn:Prev END:Bot F1:Visits F2:Rates F3:Find F4:Upd F10:Exit";
- case "OFFICE.DBF": line =
- "HOME:Top PgUp:Next PgDn:Prev END:Bot F1:CaseWorkers F3:Find F4:Update F10:Exit";
- }
-
- /*
- put up the status line
- */
- status = new(Window,80,112,0,"",24,0,1,80);
- say(status,0,0,line,80,112);
-
- /*
- select the data entry window as current, and initialize it
- by clearing any existing GET field definitions
- */
- select(cw);
- clearGets(w);
- sayExp(w,0,1,#name(self),len(name(self)),112);
- sayExp(w,0,20,#"Record=",7,112);
- sayExp(w,0,27,#recno(self),7,112);
-
- /*
- construct a data entry form for this DBF file from its
- structure information Collection
- */
- l = structure(self);
- for(i=1;i<=numFields(self);i=i+1) {
- field_def = at(l,i);
- fname = at(field_def,1); % name is first element in field def
- say(w,i,1,fname,10,112); % prompt for field is field name
- width = at(field_def,3); % field width
- if(at(field_def,2)=='D') width = width+2;
- new(Field,w,i,15,fname,width,79); % get field
- }
-
- /*
- based on the DBASE file being edited, set up special actions
- for function keys. If patient database is being edited,
- set up the F1 key to edit visits for that patient; set up
- F2 to edit billing rates for the patient. If the office database
- is being edited, set up F1 to edit the workers assigned to the office
- */
- switch(name(self)) {
- case "PATIENT.DBF": {
- onKey(w,F1,#editVisits(self,caseno));
- onKey(w,F2,#editRates(self,caseno));
- }
- case "OFFICE.DBF": onKey(w,F1,#editWorkers(self,ccenter));
- }
- onKey(w,F3,#myLocate(self,w));
- onKey(w,F8,#myEdit(w));
- /*
- execute the form
- */
- top(self);
- read(w);
- clearKeys(w);
- remove(status);
- }
-
-
- /*
- print a report of all visits for a given date
- pressing ESC will abort this function
- */
- method Nil::visitReport()
- {
- /*
- open a file to contain report output
- */
- fp = new(File,"visit.rpt",1,0,0);
- /*
- prompt the user; if a response is entered, write the report
- */
- s = accept("Enter date for report (ESC to exit): ");
- if(len(s) > 0) {
- writeDevice(fp);
- d = asDate(s,"MM/DD/CCYY");
- ? "Visits for ",d;
- visit = new(Dbffile,"visit");
- setFilter(visit,#date == d);
- top(visit);
- ? "CASENO\tDATE\t\tSERVICE\tHOURS\tPAID\tDUE\tSCALED";
- while(!eof(visit)) {
- ? caseno,"\t",date,"\t",service,"\t",hours,
- "\t$",paid,"\t$",due,"\t$",scale;
- skip(visit,1L);
- }
- close(fp);
- close(visit);
- display(fileString("visit.rpt")); % display report results
- }
- else close(fp);
- }
-
- /*
- print a report of all visits for a patient
- */
- method Nil::patientVisitReport()
- {
- fp = new(File,"visit.rpt",1,0,0);
- s = accept("Enter case # for report (ESC to exit): ");
- if(len(s) > 0) {
- writeDevice(fp);
- visit = new(Dbffile,"visit");
- setFilter(visit,#caseno == s);
- top(visit);
- ? "CASENO\tDATE\t\tSERVICE\tHOURS\tPAID\tDUE";
- while(!eof(visit)) {
- ? caseno,"\t",date,"\t",service,"\t",hours,
- "\t$",paid,"\t$",due;
- skip(visit,1L);
- }
- close(fp);
- close(visit);
- display(fileString("visit.rpt"));
- }
- else close(fp);
- }
-
- /*
- execute a main menu choice
- */
- method Int::execute(self,title)
- {
- w = new(Window,1,112,112,title,4,6,16,70);
-
- switch(self) {
- case 1: { office = new(Dbffile,"office");
- blank(office);
- ccenter = max(office,#ccenter)+1;
- append(office);
- close(office);
- }
- case 2: { doctor = new(Dbffile,"doctor");
- blank(doctor);
- docid = max(doctor,#docid)+1;
- indate = date();
- append(doctor);
- close(doctor);
- }
- case 3: { patient = new(Dbffile,"patient");
- blank(patient);
- % calculate the next highest case number (patient id)
- caseno = format(asInt(
- at(max(patient,#caseno),1,6))+1,"%06d");
- indate = date();
- append(patient);
- close(patient);
- }
- case 4: { visit = new(Dbffile,"visit");
- blank(visit);
- date=date();
- append(visit);
- close(visit);
- }
- case 5: { office = new(Dbffile,"office");
- top(office);
- edit(office,w);
- close(office);
- }
- case 6: { patient = new(Dbffile,"patient");
- top(patient);
- edit(patient,w);
- close(patient);
- }
- case 7: visitReport();
- case 8: patientVisitReport();
- case 9: tbd();
- }
- remove(w);
- }
-
- /*
- Main program
- */
- cls;
- status = new(Window,80,112,0,"",24,0,1,80);
-
- /*
- create a Collection of main menu choices
- */
- choices = [
- "Create New Office",
- "Create New Doctor",
- "Create New Patient",
- "Create New Visit",
- "Edit Existing Offices/Doctors",
- "Edit Existing Patients/Visits",
- "Visit Report for Date",
- "Visit Report for Patient",
- "Insurance Bill for Visit"];
-
- /*
- create the main menu
- */
- m= new(Menu,1,2,3,9,112,112,choices," Doctor's Office Manager Main Menu ");
- say(status,0,0,"Select a menu option using the arrow keys",80,112);
-
- /*
- execute the main menu
- */
- b = choice(m,1);
- while(b > 0) {
- execute(b," "+at(choices,b)+" ");
- remove(m);
- say(status,0,0,"Select a menu option using the arrow keys",80,112);
- b = choice(m,b);
- }
- remove(m);
- remove(status);
-
-