GolfService Example Class

:Class GolfService
:Using System
    
    :Field Private GOLFILE'' ⍝ Name of Golf data file
    :Field Private GOLFID0 ⍝ Tie number Golf data file
    
    :Class GolfCourse
        :Field Public Code¯1
        :Field Public Name''
        
         ctor args
          :Implements Constructor
          :Access Public Instance
          Code Nameargs
          ⎕DF Name,'(',(Code),')'
        
    
    :EndClass
    
    :Class Slot
        :Field Public Time
        :Field Public Players
        
         ctor1 t
          :Implements Constructor
          :Access Public Instance
          Timet
          Players0⍴⊂''
        
         ctor2 (t pl)
          :Implements Constructor
          :Access Public Instance
          Time Playerst pl
        
         format
          :Implements Trigger Players
          ⎕DFTime Players
        
    :EndClass
    :Class Booking
        :Field Public OK
        :Field Public Course
        :Field Public TeeTime
        :Field Public Message
        
         ctor args
          :Implements Constructor
          :Access Public Instance
          OK Course TeeTime Messageargs
        
         format
          :Implements Trigger OK,Message
          ⎕DFCourse TeeTime(OKMessage'OK')
        
    :EndClass
    
    :Class StartingSheet
        :Field Public OK
        :Field Public Course
        :Field Public Date
        :Field Public Slots⎕NULL
        :Field Public Message
        
         ctor args
          :Implements Constructor
          :Access Public Instance
          OK Course Dateargs
        
         format
          :Implements Trigger OK,Message
          ⎕DF2 1(Course Date)(↑⍕¨Slots)
        
    :EndClass
    

     ctor file
      :Implements Constructor
      :Access Public Instance
      GOLFILEfile
      ⎕FUNTIE(((⎕FNAMES)~' ')⍳⊂GOLFILE)⎕FNUMS,0
      :Trap 22
          GOLFIDGOLFILE ⎕FTIE 0
      :Else
          InitFile
      :EndTrap
    
     dtor
      :Implements Destructor
      ⎕FUNTIE GOLFID
    
    
     InitFile;COURSECODES;COURSES;INDEX;I
      :Access Public
      :If GOLFID0
          GOLFILE ⎕FERASE GOLFID
      :EndIf
      GOLFIDGOLFILE ⎕FCREATE 0
      COURSECODES1 2 3
      COURSES'St Andrews' 'Hindhead' 'Basingstoke'
      INDEX(COURSES)0
      COURSECODES COURSES INDEX ⎕FAPPEND GOLFID
      :For I :In ⍳⍴COURSES
          INDEX[I]  ⎕FAPPEND 1
      :EndFor
      COURSECODES COURSES INDEX ⎕FREPLACE GOLFID 1
    
    
     RGetCourses;COURSECODES;COURSES;INDEX
      :Access Public
      COURSECODES COURSES INDEX⎕FREAD GOLFID 1
      R{⎕NEW GolfCourse }¨↓⍉↑COURSECODES COURSES
    
     RGetStartingSheet ARGS;CODE;COURSE;DATE;COURSECODES
                             ;COURSES;INDEX;COURSEI;IDN
                             ;DATES;COMPS;IDATE;TEETIMES
                             ;GOLFERS;I;T
      :Access Public
      CODE DATEARGS
      COURSECODES COURSES INDEX⎕FREAD GOLFID 1
      COURSEICOURSECODESCODE
      COURSE⎕NEW GolfCourse(CODE(COURSEICOURSES,⊂''))
      R⎕NEW StartingSheet(0 COURSE DATE)
      :If COURSEI>⍴COURSECODES
          R.Message'Invalid course code'
          :Return
      :EndIf
      IDN2 ⎕NQ'.' 'DateToIDN',DATE.(Year Month Day)
      DATES COMPS⎕FREAD GOLFID,COURSEIINDEX
      IDATEDATESIDN
      :If IDATE>⍴DATES
          R.Message'No Starting Sheet available'
          :Return
      :EndIf
      TEETIMES GOLFERS⎕FREAD GOLFID,IDATECOMPS
      TDateTime.New¨(DATE.(Year Month Day)),¨[1]
                                   24 60 1TEETIMES
      R.Slots{⎕NEW Slot }¨T,¨GOLFERS
      R.OK1
    
     RMakeBooking ARGS;CODE;COURSE;SLOT;TEETIME
                        ;COURSECODES;COURSES;INDEX
                        ;COURSEI;IDN;DATES;COMPS;IDATE
                        ;TEETIMES;GOLFERS;OLD;COMP;HOURS
                        ;MINUTES;NEAREST;TIME;NAMES;FREE
                        ;FREETIMES;I;J;DIFF
      :Access Public
      ⍝ If GimmeNearest is 0, tries for specified time          ⍝ If GimmeNearest is 1, gets nearest time     
      CODE TEETIME NEAREST3ARGS
      COURSECODES COURSES INDEX⎕FREAD GOLFID 1
      COURSEICOURSECODESCODE
      COURSE⎕NEW GolfCourse(CODE(COURSEICOURSES,⊂''))
      SLOT⎕NEW Slot TEETIME
      R⎕NEW Booking(0 COURSE SLOT'')
      :If COURSEI>⍴COURSECODES
          R.Message'Invalid course code'
          :Return
      :EndIf
      :If TEETIME.Now>TEETIME
          R.Message'Requested tee-time is in the past'
          :Return
      :EndIf
      :If TEETIME>TEETIME.Now.AddDays 30
          R.Message'Requested tee-time is more than 30
                                          days from now'
          :Return
      :EndIf
      IDN2 ⎕NQ'.' 'DateToIDN',TEETIME.(Year Month Day)
      DATES COMPS⎕FREAD GOLFID,COURSEIINDEX
      IDATEDATESIDN
      :If IDATE>⍴DATES
          TEETIMES(24 607 0)+10ׯ1+⍳1+8×6
          GOLFERS((TEETIMES),4)⍴⊂''llowed per tee time
          :If 0=OLD(DATES<2 ⎕NQ'.' 'DateToIDN',3⎕TS)/
                                                 ⍳⍴DATES
              COMP(TEETIMES GOLFERS)⎕FAPPEND GOLFID
              DATES,IDN
              COMPS,COMP
              (DATES COMPS)⎕FREPLACE GOLFID,COURSEIINDEX
          :Else
              DATES[OLD]IDN
              (TEETIMES GOLFERS)⎕FREPLACE GOLFID,
                                          COMPOLDCOMPS
              DATES COMPS ⎕FREPLACE GOLFID,COURSEIINDEX
          :EndIf
          :Else
          COMPIDATECOMPS
          TEETIMES GOLFERS⎕FREAD GOLFID COMP
      :EndIf
      HOURS MINUTESTEETIME.(Hour Minute)
      NAMES(3ARGS)~''
      TIME24 60HOURS MINUTES
      TIME10×⌊0.5+TIME÷10
      :If ~NEAREST
          ITEETIMESTIME
          :If I>⍴TEETIMES
          :OrIf (NAMES)>⊃,/+/0=⍴¨GOLFERS[I;]
              R.Message'Not available'
              :Return
          :EndIf
      :Else
          :If ~∨/FREE(NAMES)≤⊃,/+/0=⍴¨GOLFERS
              R.Message'Not available'
              :Return
          :EndIf
          FREETIMES(FREE×TEETIMES)+32767×~FREE
          DIFF|FREETIMES-TIME
          IDIFF⍳⌊/DIFF
      :EndIf
      J(⊃,/0=⍴¨GOLFERS[I;])/4
      GOLFERS[I;(NAMES)J]NAMES
      (TEETIMES GOLFERS)⎕FREPLACE GOLFID COMP
      TEETIMEDateTime.New TEETIME.(Year Month Day),
                                  324 60ITEETIMES
      SLOT.TimeTEETIME
      SLOT.Players(⊃,/0<⍴¨GOLFERS[I;])/GOLFERS[I;]
      R.(OK TeeTime)1 SLOT
    
    
:EndClass