home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / database / do1beta.zip / DEMO.DO < prev    next >
Text File  |  1991-08-25  |  11KB  |  439 lines

  1. /*#############################################################################
  2.     DEMO.DO
  3.     dObject Demonstration Application
  4.  
  5.     This is a simple doctor's office manager program that keeps
  6.     track of offices, doctors, doctor assignments to one or more
  7.     offices, patients, and patient visits.  It is intended to 
  8.     be an example of how to write an application to use DBF files
  9.     with menus, windows, and data entry forms using dObject.
  10.  
  11.     NOTE - you must first run the supplied "CRDEMO.DO" program
  12.     to create the DBF files used by this application
  13.  
  14.     Copyright (c) 1991 Intelligent Systems Research
  15.     License is granted to copy or modify this program freely
  16. #############################################################################*/
  17. #include "keydef.do"
  18.  
  19. /*
  20.      a stub for functions not implemented yet
  21. */
  22. method Nil::tbd()
  23. {
  24.     w = new(Window,1,79,79," Not Implemented ",5,5,6,50);
  25.     ? "This function has not been implemented\nPress any key to continue...";
  26.     inkey();
  27.     remove(w);
  28. }
  29.  
  30.     
  31. /*
  32.     this method validates that a doctor is assigned to an office
  33.     self is the cost center id
  34.     f2 is the Doctor id
  35.     there should be a record in the officed table for these two values
  36. */
  37. method Int::validDoctor(self,f2)
  38. {
  39.     officed = new(Dbffile,"officed");
  40.     setFilter(officed,#(ccenter == self & docid == f2));
  41.     top(officed);
  42.     if(recno(officed) <= 0L) {
  43.         w = new(Window,1,79,79," Error ",5,5,6,60);
  44.         display(asString(self)+asString(f2)
  45.             + asString(recno(officed))
  46.             + " Doctor is not assigned to this office");
  47.         remove(w);
  48.     }
  49.     close(officed);
  50. }
  51.  
  52.  
  53. /*
  54.     this method sets the "scale" value in a form to the scale for a patient
  55.     self = database being appended to
  56.     w = window for data entry form
  57.     mcaseno = case number to look up rate for
  58. */
  59. method Dbffile::defaultRate(self,w,mcaseno)
  60. {
  61.     db = new(Dbffile,"billrate");
  62.     locate(db,"caseno",mcaseno);
  63.     mscale = rate;
  64.     close(db);
  65.     select(self);
  66.     scale = mscale;
  67.     draw(w);
  68. }
  69.  
  70. /*
  71.     this method implements a data entry form for appending a new
  72.     record to the DBF file in self, similar to the DBASE append
  73.     command
  74. */    
  75. method Dbffile::append(self)
  76. {
  77. /*
  78.     put up a status line on the bottom of the screen
  79. */
  80.     w = currentWindow();
  81.     say(status,0,0,"Fill in the fields for the new "+trim(name(self))
  82.         +" record         F10:Accept ESC:Quit",80,112);
  83.     select(w);
  84.  
  85. /*
  86.     construct the field definitions from the structure of the
  87.     DBF file being appended to
  88. */
  89.     clearGets(currentWindow());
  90.     l = structure(self); % returns a Collection of field def Collections
  91.     for(i=1;i<=numFields(self);i=i+1) {
  92.         field_def = at(l,i);
  93.         fieldname = at(field_def,1);    % field name is first element
  94.         say(currentWindow(),i,1,fieldname,10,112);
  95.         width = at(field_def,3);    % field width is third element
  96.         if(at(field_def,2)=='D') width = width+2; 
  97.         f = new(Field,w,i,15,fieldname,width,79);
  98.  
  99. /*
  100.     assign field hot keys based on the field being defined
  101. */
  102.         if(trim(fieldname) == "docid") 
  103.             onKey(f,RETURN,#validDoctor(program,docid));
  104.         if(trim(fieldname) == "CASENO")
  105.             onKey(f,RETURN,#defaultRate(self,w,caseno));
  106.     }
  107.  
  108. /*
  109.     assign a hot key for the window
  110.     if the F8 key is pressed, invoke the myEdit method to display
  111.     the contents of the current field in a scrollable window
  112. */
  113.     onKey(w,F8,#myEdit(currentWindow()));
  114.  
  115. /*
  116.     loop processing keystrokes (use the read() method)
  117.     read() returns the last key pressed from the data entry form
  118. */
  119.     setFilter(self,#F);    % this disallows any scrolling 
  120.     key = read(currentWindow());
  121.     if(key == F10) {
  122.         write(self,0L);
  123.         say(status,0,0,"Record added; press any key...",80,112);
  124.         inkey();
  125.     }
  126. }
  127.  
  128. /*
  129.     this method implements a pop-up scrollable display of a field
  130.     value within a data entry form; see Int::onKey() to see how to
  131.     assign this to a particular hot key
  132. */
  133. method Window::myEdit(self)
  134. {
  135.     f = currentField(self);
  136.     s = asString(eval(asId(name(f)))); % returns value of current field
  137.     w = new(Window,1,112,112,name(f),5,5,10,40);
  138.     display(s);    % change this to edit(s) for an editor
  139.     remove(w);
  140.     cursor(self,row(self),col(self)); % re-displays the cursor
  141. }
  142.  
  143.  
  144. /*
  145.     this method asks the user for a CASENO value to locate, then does
  146.     a record-by-record scan of the DBF file in self
  147.     w = current window that data entry form is displayed in
  148. */
  149. method Dbffile::myLocate(self,w)
  150. {
  151.     w2 = new(Window,1,112,112," LOCATE ",5,5,4,20);
  152.     set("softseek",T);
  153.     s = accept("CASENO ? ");
  154.     top(self);
  155.     locate(self,"caseno",s);
  156.     remove(w2);
  157.     draw(w);
  158.     gotoField(w,currentField(w));
  159. }
  160.  
  161. /*
  162.     edit the visits for a patient
  163. */
  164. method Dbffile::editVisits(self,case)
  165. {
  166.     w = currentWindow();
  167.     visit = new(Dbffile,"visit");
  168.     setFilter(visit,#trim(caseno)==case);
  169.     top(visit);
  170.     w2 = new(Window,2,112,112," VISIT(s) FOR "+case+" ",6,9,16,40);
  171.     edit(visit,w2);
  172.     close(visit);
  173.     remove(w2);
  174.     select(w);
  175.     gotoField(w,firstField(w));
  176. }
  177.  
  178. /*
  179.     edit the bill rates for a patient
  180. */
  181. method Dbffile::editRates(self,case)
  182. {
  183.     w = currentWindow();
  184.     billrate = new(Dbffile,"billrate");
  185.     setFilter(billrate,#trim(caseno)==case);
  186.     top(billrate);
  187.     w2 = new(Window,2,112,112," Billing Rate(s) FOR "+case+" ",9,9,10,40);
  188.     edit(billrate,w2);
  189.     close(billrate);
  190.     remove(w2);
  191.     select(w);
  192.     gotoField(w,firstField(w));
  193. }
  194.  
  195. /*
  196.     edit the Doctors assigned to an office (cost center)
  197. */
  198. method Dbffile::editWorkers(self,ccenter)
  199. {
  200.     w = currentWindow();
  201.     doctor = new(Dbffile,"doctor");
  202.     top(doctor);
  203.     w2 = new(Window,2,112,112," Doctor(s) ",9,9,10,60);
  204.     edit(doctor,w2);
  205.     close(doctor);
  206.     remove(w2);
  207.     select(w);
  208.     gotoField(w,firstField(w));
  209. }
  210.  
  211.     
  212. /*
  213.     edit a Dbffile using a full screen editor
  214. */
  215. method Dbffile::edit(self,w)
  216. {
  217. /*
  218.     create a status line showing the user what functions/keys are
  219.     available from within the data entry form
  220.     the status line depends on the name of the DBF file being edited
  221.         (this is NOT very generic !)
  222. */            
  223.     cw = currentWindow();
  224.     line = "HOME:Top  PgUp:Next  PgDn:Prev  END:Bot  F3:Find  F4:Update  F10:Exit";
  225.     switch(name(self)) {
  226.         case "PATIENT.DBF": line = 
  227. "HOME:Top PgUp:Nxt PgDn:Prev END:Bot F1:Visits F2:Rates F3:Find F4:Upd F10:Exit";
  228.         case "OFFICE.DBF": line = 
  229. "HOME:Top PgUp:Next PgDn:Prev END:Bot F1:CaseWorkers F3:Find F4:Update F10:Exit";
  230.     }
  231.     
  232. /*
  233.     put up the status line
  234. */
  235.     status = new(Window,80,112,0,"",24,0,1,80);
  236.     say(status,0,0,line,80,112);
  237.     
  238. /*
  239.     select the data entry window as current, and initialize it
  240.     by clearing any existing GET field definitions
  241. */
  242.     select(cw);
  243.     clearGets(w);
  244.     sayExp(w,0,1,#name(self),len(name(self)),112);
  245.     sayExp(w,0,20,#"Record=",7,112);
  246.     sayExp(w,0,27,#recno(self),7,112);
  247.     
  248. /*
  249.     construct a data entry form for this DBF file from its 
  250.     structure information Collection
  251. */
  252.     l = structure(self);
  253.     for(i=1;i<=numFields(self);i=i+1) {
  254.         field_def = at(l,i);
  255.         fname = at(field_def,1); % name is first element in field def
  256.         say(w,i,1,fname,10,112); % prompt for field is field name
  257.         width = at(field_def,3); % field width
  258.         if(at(field_def,2)=='D') width = width+2;
  259.         new(Field,w,i,15,fname,width,79); % get field
  260.     }
  261.     
  262. /*
  263.     based on the DBASE file being edited, set up special actions
  264.     for function keys.  If patient database is being edited,
  265.     set up the F1 key to edit visits for that patient; set up
  266.     F2 to edit billing rates for the patient.  If the office database
  267.     is being edited, set up F1 to edit the workers assigned to the office
  268. */
  269.     switch(name(self)) {
  270.         case "PATIENT.DBF": {
  271.             onKey(w,F1,#editVisits(self,caseno));
  272.             onKey(w,F2,#editRates(self,caseno));
  273.         }
  274.         case "OFFICE.DBF": onKey(w,F1,#editWorkers(self,ccenter));
  275.     }
  276.     onKey(w,F3,#myLocate(self,w));
  277.     onKey(w,F8,#myEdit(w));
  278. /*
  279.     execute the form
  280. */
  281.     top(self);
  282.     read(w);
  283.     clearKeys(w);
  284.     remove(status);
  285. }
  286.  
  287.  
  288. /*
  289.     print a report of all visits for a given date
  290.     pressing ESC will abort this function
  291. */
  292. method Nil::visitReport()
  293. {
  294. /*
  295.     open a file to contain report output
  296. */
  297.     fp = new(File,"visit.rpt",1,0,0);
  298. /*
  299.     prompt the user; if a response is entered, write the report
  300. */
  301.     s = accept("Enter date for report (ESC to exit): ");
  302.     if(len(s) > 0) {
  303.         writeDevice(fp);
  304.         d = asDate(s,"MM/DD/CCYY");
  305.         ? "Visits for ",d;
  306.         visit = new(Dbffile,"visit");
  307.         setFilter(visit,#date == d);
  308.         top(visit);
  309.         ? "CASENO\tDATE\t\tSERVICE\tHOURS\tPAID\tDUE\tSCALED";
  310.         while(!eof(visit)) {
  311.             ? caseno,"\t",date,"\t",service,"\t",hours,
  312.                 "\t$",paid,"\t$",due,"\t$",scale;
  313.             skip(visit,1L);
  314.         }
  315.         close(fp);
  316.         close(visit);
  317.         display(fileString("visit.rpt")); % display report results
  318.     }
  319.     else close(fp);
  320. }
  321.  
  322. /*
  323.     print a report of all visits for a patient
  324. */
  325. method Nil::patientVisitReport()
  326. {
  327.     fp = new(File,"visit.rpt",1,0,0);
  328.     s = accept("Enter case # for report (ESC to exit): ");
  329.     if(len(s) > 0) {
  330.         writeDevice(fp);
  331.         visit = new(Dbffile,"visit");
  332.         setFilter(visit,#caseno == s);
  333.         top(visit);
  334.         ? "CASENO\tDATE\t\tSERVICE\tHOURS\tPAID\tDUE";
  335.         while(!eof(visit)) {
  336.             ? caseno,"\t",date,"\t",service,"\t",hours,
  337.                 "\t$",paid,"\t$",due;
  338.             skip(visit,1L);
  339.         }
  340.         close(fp);
  341.         close(visit);
  342.         display(fileString("visit.rpt"));
  343.     }
  344.     else close(fp);
  345. }
  346.  
  347. /*
  348.     execute a main menu choice
  349. */
  350. method Int::execute(self,title)
  351. {
  352.     w = new(Window,1,112,112,title,4,6,16,70);
  353.  
  354.     switch(self) {            
  355.         case 1: { office = new(Dbffile,"office");
  356.             blank(office);
  357.             ccenter = max(office,#ccenter)+1;
  358.             append(office);
  359.             close(office);
  360.             }
  361.         case 2: { doctor = new(Dbffile,"doctor");
  362.             blank(doctor);
  363.             docid = max(doctor,#docid)+1;
  364.             indate = date();
  365.             append(doctor);
  366.             close(doctor);
  367.             }
  368.         case 3: { patient = new(Dbffile,"patient");
  369.             blank(patient);
  370.             % calculate the next highest case number (patient id)
  371.             caseno = format(asInt( 
  372.                 at(max(patient,#caseno),1,6))+1,"%06d");
  373.             indate = date();
  374.             append(patient);
  375.             close(patient);
  376.             }
  377.         case 4: { visit = new(Dbffile,"visit");
  378.             blank(visit);
  379.             date=date(); 
  380.             append(visit);
  381.             close(visit);
  382.             }
  383.         case 5: { office = new(Dbffile,"office");
  384.             top(office);
  385.             edit(office,w);
  386.             close(office);
  387.             }
  388.         case 6:    { patient = new(Dbffile,"patient");
  389.             top(patient);
  390.             edit(patient,w); 
  391.             close(patient);
  392.             } 
  393.         case 7: visitReport();
  394.         case 8: patientVisitReport();
  395.         case 9:    tbd();
  396.     }
  397.     remove(w);
  398. }
  399.  
  400. /*
  401.     Main program
  402. */
  403. cls;
  404. status = new(Window,80,112,0,"",24,0,1,80);
  405.  
  406. /*
  407.     create a Collection of main menu choices
  408. */
  409. choices = [
  410.     "Create New Office",
  411.     "Create New Doctor",
  412.     "Create New Patient",
  413.     "Create New Visit",
  414.     "Edit Existing Offices/Doctors",
  415.     "Edit Existing Patients/Visits",
  416.     "Visit Report for Date",
  417.     "Visit Report for Patient",
  418.     "Insurance Bill for Visit"];
  419.  
  420. /*
  421.     create the main menu
  422. */
  423. m= new(Menu,1,2,3,9,112,112,choices," Doctor's Office Manager Main Menu ");
  424. say(status,0,0,"Select a menu option using the arrow keys",80,112);
  425.  
  426. /*
  427.     execute the main menu
  428. */
  429. b = choice(m,1);
  430. while(b > 0) {
  431.     execute(b," "+at(choices,b)+" ");
  432.     remove(m);
  433.     say(status,0,0,"Select a menu option using the arrow keys",80,112);
  434.     b = choice(m,b);
  435. }
  436. remove(m);
  437. remove(status);
  438.  
  439.