* Program: ctSetSlots2.prg * Purpose: Return a result set of available times to schedule a procedure set PARAMETERS tiSetID,tdStartDate,tdEndDate * Load Our Library SET PROCEDURE TO ctsch3fun addi ldStartOn=tdStartDate ldEndOn=tdEndDate lnDaysToSearch=tdEndDate-tdStartDate lcStartDate=DTOC(tdStartDate) lcEndDate=DTOC(tdEndDate) PUBLIC gcResultString gcResultString="" * Create our Temp Canidate Table SQLEXEC(gnConnHandle,[Select * from coCan],"CurTemp") SELECT * from curTemp INTO CURSOR xCurTemp readwrite * Get all cases between the daterange * Get the requirements for the set lcCmd=[SELECT dbo.procstg1.proccode, dbo.procstg1.description, dbo.procstg1.initialproctime, dbo.procstg1.tue, dbo.procstg1.mon, dbo.procstg1.wed, ] lcCmd=lcCmd+[ dbo.procstg1.thu, dbo.procstg1.fri, dbo.procstg2.procstg2ID, dbo.procstg2.procID, dbo.procstg2.minoffset, dbo.procstg2.maxoffset, dbo.coproc.dcode, ] lcCmd=lcCmd+[ dbo.coproc.description AS Expr1, dbo.coRoomToGroup.RoomID, dbo.corooms.roomname,dbo.coRooms.DeptID,dbo.coRooms.schedFrom,dbo.coRooms.SchedTo ] lcCmd=lcCmd+[ FROM dbo.corooms INNER JOIN ] lcCmd=lcCmd+[ dbo.coRoomToGroup ON dbo.corooms.roomid = dbo.coRoomToGroup.RoomID INNER JOIN ] lcCmd=lcCmd+[ dbo.coproc INNER JOIN ] lcCmd=lcCmd+[ dbo.procstg2 ON dbo.coproc.procid = dbo.procstg2.procID INNER JOIN ] lcCmd=lcCmd+[ dbo.coProcRoomGrp ON dbo.coproc.procid = dbo.coProcRoomGrp.procID INNER JOIN ] lcCmd=lcCmd+[ dbo.procstg1 ON dbo.procstg2.procstgid = dbo.procstg1.procstgid ON dbo.coRoomToGroup.coRoomGrpID = dbo.coProcRoomGrp.coRoomGrpID ] lcCmd=lcCmd+[ where dbo.procstg1.procstgid=?tiSetID] lcCmd=lcCmd+[ order by procStg2.ProcStg2ID ] IF SQLEXEC(gnConnHandle,lcCmd,"curSetData") < 1 =sqlerror() ELSE * Next Step * Determine How Many Differnt Strings we have SELECT dist procstg2ID as stgID FROM curSetData INTO CURSOR curStrings ltInitialDT={} PUBLIC ARRAY laSlots[RECCOUNT("curStrings"),7] SELECT curStrings llFirstProc=.t. lnSlotPtr=1 llSlotFound=.f. lnProcCtr=1 lnMinOff=0 ltInitialProcEnd=0 * Loop through each procedure finding a slot SELECT curStrings SCAN * Get the Min OffSet * Get an array of room id's we can do this procedure in lnCurrID=curStrings.stgID SELECT dist roomid,schedfrom,schedto,0,deptid,minoffset,procid,roomname,expr1 FROM cursetdata WHERE curSetData.procstg2id=lnCurrID INTO ARRAY laRooms llFirst=.t. * Get Required Procedure Time (minutes) lcCmd=[SELECT dbo.coproc.setup, dbo.coproc.cleanup, dbo.coproc.defaulttime ] lcCmd=lcCmd+[FROM dbo.procstg2 INNER JOIN ] lcCmd=lcCmd+[dbo.coproc ON dbo.procstg2.procID = dbo.coproc.procid ] lcCmd=lcCmd+[where dbo.procstg2.procStg2ID = ?lnCurrID ] SQLEXEC(gnConnHandle,lcCmd,"curDefaTime") lnMinutesRequired=IIF(ISNULL(defaulttime),30,defaulttime) SELECT curSTrings ltSearchStart=CTOT(DTOC(ldStartOn)+[ ]+formattime(360)) *!* Loop through the number of days available in the search llFirstDaysLoop=.t. FOR lnDays=1 TO lnDaysToSearch SET MESSAGE TO [Searching lnDays=]+TRANSFORM(lnDays) * Advance the search date IF !llFirstDaysLoop ldStartOn=ldStartOn+1 ELSE llFirstDaysLoop=.f. ENDIF * Loop through each room IF lnProcCtr=1 ltEarly=0 && Need to store the earliest one if it is the first procedure we are search for endif FOR lnRoomLoop = 1 TO ALEN(laRooms,1) * get the available number of 15 minutes slots we can search for this room lnSlots=((((laRooms[lnRoomLoop,3]-laRooms[lnRoomLoop,2])/100)*60)/15) * Store Starting Time For Room * Not all rooms will have the same open periods lnRoomStart=((laRooms[lnRoomLoop,2]/100)*60) lnRoomID= laRooms[lnRoomLoop,1] lnDeptID= laRooms[lnRoomLoop,5] lnOffSet= laRooms[lnRoomLoop,6] lnProcID= laRooms[lnRoomLoop,7] lcRoomName=laRooms[lnRoomLoop,8] lcProcDesc=laRooms[lnRoomLoop,9] llFirstSlotLoop=.t. * Loop through each available slot for a match FOR lnSlotLoop=1 TO lnSlots * Set the search dateTime parameters IF llFirstSlotLoop ltSearchFrom=CTOT(DTOC(ldStartOn)+[ ]+formattime(lnRoomStart)) llFirstSlotLoop = .f. ELSE ltSearchFrom=ltSearchFrom+900 ENDIF * Check the required offset (minutes) from the end of the first * procedure. If we are not meeting the offset, skip and let it advance the datetime ltSearchTo =ltSearchFrom+(lnMinutesRequired*60) IF lnProcCtr > 1 AND ltSearchFrom < (ltInitialProcEnd+(lnOffSet*60)) * We Need to Advance the time ELSE * Build the string to search for existing cases in the time slot lcCmd=[SELECT meetingnumber from meetings ] lcCmd=lcCmd+[WHERE roomid = ?lnRoomID ] lcCmd=lcCmd+[AND (begintime between ?ltSearchFrom and ?ltSearchTo ] lcCmd=lcCmd+[OR endtime between ?ltSearchFrom and ?ltSearchTo) ] * Exec the sqlexec IF SQLEXEC(gnConnHandle,lcCmd,"curConflict") < 1 =sqlerror() ELSE * Check to see if we have a conflict (Reccount > 0) IF RECCOUNT("curConflict") > 0 * No Good, there is already something booked in this timeslot and room llSlotFound=.f. ELSE * Create Temporary records to show this slot as used in case someone else * tries to search this period =ctManageLocks(lnRoomid,lnDeptID,ltSearchFrom,ltSearchTo,lnLockID,DATETIME(),.t.) IF lnProcCtr=1 * IF it is the first procedure, then we need to store the time slot we found * so we have a baseline for the offset on the rest of the procedures ltInitialProcEnd=ltSearchTo endif * Store into a public array so we can show it to the user in the calling form. laSlots[lnSlotPtr,1]=TRANSFORM(ltSearchFrom) laSlots[lnSlotPtr,2]=TRANSFORM(ltSearchTo) laSlots[lnSlotPtr,3]=TRANSFORM(lcRoomName) laSlots[lnSlotPtr,4]=TRANSFORM(lcProcDesc) && Proc Description laSlots[lnSlotPtr,5]=TRANSFORM(lnProcID) laSlots[lnSlotPtr,6]=TRANSFORM(lnRoomID) laSlots[lnSlotPtr,7]=TRANSFORM(lnDeptID) * Advance the Array Pointer lnSlotPtr=lnSlotPtr+1 * Set the flag that we found a slot llSlotFound=.t. ENDIF ENDIF ENDIF IF llSlotFound EXIT endif ENDFOR IF llSlotFound EXIT endif ENDFOR IF llSlotFound EXIT endif ENDFOR llSlotFound=.f. lnProcCtr=lnProcCtr+1 ENDSCAN ENDIF