| [614] | 1 | using System; | 
|---|
|  | 2 | using System.Collections; | 
|---|
|  | 3 | using System.Data; | 
|---|
|  | 4 | using System.Data.OleDb; | 
|---|
|  | 5 | using System.Diagnostics; | 
|---|
|  | 6 | using System.Drawing; | 
|---|
|  | 7 | using System.Windows.Forms; | 
|---|
|  | 8 | using IndianHealthService.BMXNet; | 
|---|
|  | 9 |  | 
|---|
|  | 10 | namespace IndianHealthService.ClinicalScheduling | 
|---|
|  | 11 | { | 
|---|
| [1071] | 12 | /// <summary> | 
|---|
|  | 13 | /// Contains the array of appointments and availabily that make up the document class | 
|---|
|  | 14 | /// </summary> | 
|---|
|  | 15 | public class CGDocument | 
|---|
|  | 16 | { | 
|---|
|  | 17 | #region Member Variables | 
|---|
|  | 18 | public int m_nColumnCount;                 //todo: this should point to the view's member for column count | 
|---|
|  | 19 | public int m_nTimeUnits;                   //? | 
|---|
|  | 20 | private string m_sDocName;                     //Document Name ? | 
|---|
|  | 21 | public ArrayList m_sResourcesArray;              //keeps the resources | 
|---|
|  | 22 | public ScheduleType m_ScheduleType;                 //Either a Resource or a Clinic (Group of Resources) | 
|---|
|  | 23 | private DateTime m_dSelectedDate;                //Holds the user's selection from the dtpicker | 
|---|
|  | 24 | private DateTime m_dStartDate;                   //Beginning date of document data | 
|---|
|  | 25 | private DateTime m_dEndDate;                     //Ending date of document data | 
|---|
|  | 26 | public CGAppointments m_appointments;                 //Appointment List | 
|---|
|  | 27 | private ArrayList m_pAvArray;                     //Availability List | 
|---|
|  | 28 | private CGDocumentManager m_DocManager;                 //Holds a reference to the document manager | 
|---|
|  | 29 | private DateTime m_dLastRefresh = DateTime.Now;  //Holds last refersh date | 
|---|
|  | 30 | #endregion | 
|---|
| [614] | 31 |  | 
|---|
| [1071] | 32 | /// <summary> | 
|---|
|  | 33 | /// Constructor. Initialize State Data: | 
|---|
|  | 34 | /// 3 Arrays (Appointments, Availabilities, and Resources) | 
|---|
|  | 35 | /// Schedule Type is Resource not Clinic | 
|---|
|  | 36 | /// Selected Date is Today | 
|---|
|  | 37 | /// Start Date is Today | 
|---|
|  | 38 | /// End Date is 7 days from Today | 
|---|
|  | 39 | /// </summary> | 
|---|
|  | 40 | public CGDocument() | 
|---|
|  | 41 | { | 
|---|
|  | 42 | m_appointments = new CGAppointments();      // Holds Appointments | 
|---|
|  | 43 | m_pAvArray = new ArrayList();               // Holds Availabilites | 
|---|
|  | 44 | m_sResourcesArray = new ArrayList();        // Holds Resources | 
|---|
|  | 45 | m_ScheduleType = ScheduleType.Resource;     // Default Schedule Type is a Resource | 
|---|
|  | 46 | m_dSelectedDate = DateTime.Today;           // Default Selected Date is Today | 
|---|
|  | 47 | m_dStartDate = DateTime.Today;              // Default Start Date is Today | 
|---|
|  | 48 | m_dEndDate = DateTime.Today.AddDays(7);     // Default End Date is 7 days from Today. | 
|---|
|  | 49 | } | 
|---|
| [614] | 50 |  | 
|---|
|  | 51 |  | 
|---|
| [1071] | 52 | #region Properties | 
|---|
| [614] | 53 |  | 
|---|
| [1071] | 54 | /// <summary> | 
|---|
|  | 55 | /// Returns the latest refresh time for this document | 
|---|
|  | 56 | /// </summary> | 
|---|
|  | 57 | public DateTime LastRefreshed | 
|---|
|  | 58 | { | 
|---|
|  | 59 | get | 
|---|
|  | 60 | { | 
|---|
|  | 61 | return m_dLastRefresh; | 
|---|
|  | 62 | } | 
|---|
|  | 63 | } | 
|---|
| [614] | 64 |  | 
|---|
| [1071] | 65 | /// <summary> | 
|---|
|  | 66 | /// The list of Resource names | 
|---|
|  | 67 | /// </summary> | 
|---|
|  | 68 | public ArrayList Resources | 
|---|
|  | 69 | { | 
|---|
|  | 70 | get | 
|---|
|  | 71 | { | 
|---|
|  | 72 | return this.m_sResourcesArray; | 
|---|
|  | 73 | } | 
|---|
|  | 74 | set | 
|---|
|  | 75 | { | 
|---|
|  | 76 | this.m_sResourcesArray = value; | 
|---|
|  | 77 | } | 
|---|
|  | 78 | } | 
|---|
| [614] | 79 |  | 
|---|
| [1071] | 80 | /// <summary> | 
|---|
|  | 81 | /// The array of CGAvailabilities that contains appt type and slots | 
|---|
|  | 82 | /// </summary> | 
|---|
|  | 83 | public ArrayList AvailabilityArray | 
|---|
|  | 84 | { | 
|---|
|  | 85 | get | 
|---|
|  | 86 | { | 
|---|
|  | 87 | return this.m_pAvArray; | 
|---|
|  | 88 | } | 
|---|
|  | 89 | } | 
|---|
| [614] | 90 |  | 
|---|
| [1071] | 91 | public CGDocumentManager DocManager | 
|---|
|  | 92 | { | 
|---|
|  | 93 | get | 
|---|
|  | 94 | { | 
|---|
|  | 95 | return m_DocManager; | 
|---|
|  | 96 | } | 
|---|
|  | 97 | set | 
|---|
|  | 98 | { | 
|---|
|  | 99 | m_DocManager = value; | 
|---|
|  | 100 | } | 
|---|
|  | 101 | } | 
|---|
| [614] | 102 |  | 
|---|
| [1071] | 103 | /// <summary> | 
|---|
|  | 104 | /// Contains the hashtable of appointments | 
|---|
|  | 105 | /// </summary> | 
|---|
|  | 106 | public CGAppointments Appointments | 
|---|
|  | 107 | { | 
|---|
|  | 108 | get | 
|---|
|  | 109 | { | 
|---|
|  | 110 | return m_appointments; | 
|---|
|  | 111 | } | 
|---|
|  | 112 | } | 
|---|
| [614] | 113 |  | 
|---|
| [1071] | 114 | /// <summary> | 
|---|
|  | 115 | /// Holds the date selected by the user in CGView.dateTimePicker1 | 
|---|
|  | 116 | /// </summary> | 
|---|
|  | 117 | public DateTime SelectedDate | 
|---|
|  | 118 | { | 
|---|
|  | 119 | get | 
|---|
|  | 120 | { | 
|---|
|  | 121 | return this.m_dSelectedDate; | 
|---|
|  | 122 | } | 
|---|
|  | 123 | set | 
|---|
|  | 124 | { | 
|---|
|  | 125 | this.m_dSelectedDate = value; | 
|---|
|  | 126 | } | 
|---|
|  | 127 | } | 
|---|
| [614] | 128 |  | 
|---|
| [1071] | 129 | /// <summary> | 
|---|
|  | 130 | /// Contains the beginning date of the appointment document | 
|---|
|  | 131 | /// </summary> | 
|---|
|  | 132 | public DateTime StartDate | 
|---|
|  | 133 | { | 
|---|
|  | 134 | get | 
|---|
|  | 135 | { | 
|---|
|  | 136 | return this.m_dStartDate; | 
|---|
|  | 137 | } | 
|---|
|  | 138 | } | 
|---|
| [614] | 139 |  | 
|---|
| [1071] | 140 | public string DocName | 
|---|
|  | 141 | { | 
|---|
|  | 142 | get | 
|---|
|  | 143 | { | 
|---|
|  | 144 | return this.m_sDocName; | 
|---|
|  | 145 | } | 
|---|
|  | 146 | set | 
|---|
|  | 147 | { | 
|---|
|  | 148 | this.m_sDocName = value; | 
|---|
|  | 149 | } | 
|---|
|  | 150 | } | 
|---|
| [614] | 151 |  | 
|---|
| [1071] | 152 | #endregion | 
|---|
| [614] | 153 |  | 
|---|
| [1071] | 154 | #region Methods | 
|---|
| [614] | 155 |  | 
|---|
| [1071] | 156 | public void UpdateAllViews() | 
|---|
|  | 157 | { | 
|---|
|  | 158 | //iterate through all views and call update. | 
|---|
|  | 159 | Hashtable h = CGDocumentManager.Current.Views; | 
|---|
| [614] | 160 |  | 
|---|
| [1071] | 161 | CGDocument d; | 
|---|
|  | 162 | foreach (CGView v in h.Keys) | 
|---|
|  | 163 | { | 
|---|
|  | 164 | d = (CGDocument)h[v]; | 
|---|
|  | 165 | if (d == this) | 
|---|
|  | 166 | { | 
|---|
|  | 167 | v.UpdateArrays(); | 
|---|
|  | 168 | } | 
|---|
|  | 169 | } | 
|---|
| [614] | 170 |  | 
|---|
| [1071] | 171 | } | 
|---|
|  | 172 |  | 
|---|
|  | 173 | /// <summary> | 
|---|
|  | 174 | /// Update schedule based on info in RPMS | 
|---|
|  | 175 | /// </summary> | 
|---|
|  | 176 | private bool RefreshDaysSchedule() | 
|---|
|  | 177 | { | 
|---|
|  | 178 | try | 
|---|
|  | 179 | { | 
|---|
|  | 180 | string sPatientName; | 
|---|
|  | 181 | string sPatientID; | 
|---|
|  | 182 | DateTime dStart; | 
|---|
|  | 183 | DateTime dEnd; | 
|---|
|  | 184 | DateTime dCheckIn; | 
|---|
|  | 185 | DateTime dAuxTime; | 
|---|
|  | 186 | int nKeyID; | 
|---|
|  | 187 | string sNote; | 
|---|
|  | 188 | string sResource; | 
|---|
|  | 189 | bool bNoShow = false; | 
|---|
|  | 190 | string sNoShow = "0"; | 
|---|
|  | 191 | string sHRN = ""; | 
|---|
|  | 192 | int nAccessTypeID; //used in autorebook | 
|---|
|  | 193 | string sWalkIn = "0"; | 
|---|
|  | 194 | bool bWalkIn; | 
|---|
|  | 195 | CGAppointment pAppointment; | 
|---|
|  | 196 | CGDocumentManager pApp = CGDocumentManager.Current; | 
|---|
|  | 197 | DataTable rAppointmentSchedule; | 
|---|
|  | 198 |  | 
|---|
| [821] | 199 | //Nice to know that it gets set here!!! | 
|---|
| [1071] | 200 | m_dLastRefresh = DateTime.Now; | 
|---|
| [614] | 201 |  | 
|---|
| [1071] | 202 | this.m_appointments.ClearAllAppointments(); | 
|---|
| [614] | 203 |  | 
|---|
| [850] | 204 | //  calls RPC to get appointments | 
|---|
| [1071] | 205 | rAppointmentSchedule = CGSchedLib.CreateAppointmentSchedule(m_DocManager, m_sResourcesArray, this.m_dStartDate, this.m_dEndDate); | 
|---|
|  | 206 |  | 
|---|
| [821] | 207 | // Datatable dumper into Debug Log (nice to know that this exists) | 
|---|
|  | 208 | CGSchedLib.OutputArray(rAppointmentSchedule, "rAppointmentSchedule"); | 
|---|
| [614] | 209 |  | 
|---|
|  | 210 |  | 
|---|
| [1071] | 211 | foreach (DataRow r in rAppointmentSchedule.Rows) | 
|---|
|  | 212 | { | 
|---|
| [614] | 213 |  | 
|---|
| [1071] | 214 | if (r["APPOINTMENTID"].ToString() == "0") | 
|---|
|  | 215 | { | 
|---|
|  | 216 | string sMsg = r["NOTE"].ToString(); | 
|---|
|  | 217 | throw new BMXNetException(sMsg); | 
|---|
|  | 218 | } | 
|---|
|  | 219 | nKeyID = Convert.ToInt32(r["APPOINTMENTID"].ToString()); | 
|---|
|  | 220 | sResource = r["RESOURCENAME"].ToString(); | 
|---|
|  | 221 | sPatientName = r["PATIENTNAME"].ToString(); | 
|---|
|  | 222 | sPatientID = r["PATIENTID"].ToString(); | 
|---|
|  | 223 | dStart = (DateTime)r["START_TIME"]; | 
|---|
|  | 224 | dEnd = (DateTime)r["END_TIME"]; | 
|---|
|  | 225 | dCheckIn = new DateTime(); | 
|---|
|  | 226 | dAuxTime = new DateTime(); | 
|---|
| [614] | 227 |  | 
|---|
| [1071] | 228 | if (r["CHECKIN"].GetType() != typeof(System.DBNull)) | 
|---|
|  | 229 | dCheckIn = (DateTime)r["CHECKIN"]; | 
|---|
|  | 230 | if (r["AUXTIME"].GetType() != typeof(System.DBNull)) | 
|---|
|  | 231 | dCheckIn = (DateTime)r["AUXTIME"]; | 
|---|
|  | 232 | sNote = r["NOTE"].ToString(); | 
|---|
|  | 233 | sNoShow = r["NOSHOW"].ToString(); | 
|---|
|  | 234 | bNoShow = (sNoShow == "1") ? true : false; | 
|---|
|  | 235 | sHRN = r["HRN"].ToString(); | 
|---|
|  | 236 | nAccessTypeID = (int)r["ACCESSTYPEID"]; | 
|---|
|  | 237 | sWalkIn = r["WALKIN"].ToString(); | 
|---|
|  | 238 | bWalkIn = (sWalkIn == "1") ? true : false; | 
|---|
| [614] | 239 |  | 
|---|
| [1071] | 240 | pAppointment = new CGAppointment(); | 
|---|
|  | 241 | pAppointment.CreateAppointment(dStart, dEnd, sNote, nKeyID, sResource); | 
|---|
|  | 242 | pAppointment.PatientName = sPatientName; | 
|---|
|  | 243 | pAppointment.PatientID = Convert.ToInt32(sPatientID); | 
|---|
|  | 244 | if (dCheckIn.Ticks > 0) | 
|---|
|  | 245 | pAppointment.CheckInTime = dCheckIn; | 
|---|
|  | 246 | if (dAuxTime.Ticks > 0) | 
|---|
|  | 247 | pAppointment.AuxTime = dAuxTime; | 
|---|
|  | 248 | pAppointment.NoShow = bNoShow; | 
|---|
|  | 249 | pAppointment.HealthRecordNumber = sHRN; | 
|---|
|  | 250 | pAppointment.AccessTypeID = nAccessTypeID; | 
|---|
|  | 251 | pAppointment.WalkIn = bWalkIn; | 
|---|
|  | 252 | this.m_appointments.AddAppointment(pAppointment); | 
|---|
| [614] | 253 |  | 
|---|
| [1071] | 254 | } | 
|---|
| [614] | 255 |  | 
|---|
| [1071] | 256 | return true; | 
|---|
|  | 257 | } | 
|---|
|  | 258 | catch (Exception Ex) | 
|---|
|  | 259 | { | 
|---|
|  | 260 | Debug.Write("CGDocument.RefreshDaysSchedule error: " + Ex.Message + "\n"); | 
|---|
|  | 261 | return false; | 
|---|
|  | 262 | } | 
|---|
|  | 263 | } | 
|---|
| [614] | 264 |  | 
|---|
|  | 265 |  | 
|---|
| [1071] | 266 | public bool IsRefreshNeeded() | 
|---|
|  | 267 | { | 
|---|
|  | 268 | if (m_sResourcesArray.Count == 0) return false; | 
|---|
|  | 269 | return this.WeekNeedsRefresh(1, m_dSelectedDate, out this.m_dStartDate, out this.m_dEndDate); | 
|---|
|  | 270 | } | 
|---|
| [614] | 271 |  | 
|---|
| [1073] | 272 | //sam: This is a test that duplicates RefreshDocument, but without the UpdateAllViews, | 
|---|
|  | 273 | // as that has to be done synchornously. | 
|---|
| [1083] | 274 | //XXX: Needs to be refactored obviously, but now for testing. | 
|---|
|  | 275 | //XXX: Tested extensively enough. Less refactoring now. 2011-01-26 | 
|---|
| [1073] | 276 | public void RefreshDocumentAsync() | 
|---|
|  | 277 | { | 
|---|
| [1083] | 278 | Debug.WriteLine("IN REFERSH DOCUMENT ASYNC\n\n"); | 
|---|
|  | 279 |  | 
|---|
| [1073] | 280 | bool bRet = false; | 
|---|
|  | 281 | if (m_sResourcesArray.Count == 0) | 
|---|
|  | 282 | return; | 
|---|
|  | 283 | if (m_sResourcesArray.Count == 1) | 
|---|
|  | 284 | { | 
|---|
|  | 285 | bRet = this.WeekNeedsRefresh(1, m_dSelectedDate, out this.m_dStartDate, out this.m_dEndDate); | 
|---|
|  | 286 | } | 
|---|
|  | 287 | else | 
|---|
|  | 288 | { | 
|---|
|  | 289 | this.m_dStartDate = m_dSelectedDate; | 
|---|
|  | 290 | this.m_dEndDate = m_dSelectedDate; | 
|---|
|  | 291 | this.m_dEndDate = this.m_dEndDate.AddHours(23); | 
|---|
|  | 292 | this.m_dEndDate = this.m_dEndDate.AddMinutes(59); | 
|---|
|  | 293 | this.m_dEndDate = this.m_dEndDate.AddSeconds(59); | 
|---|
|  | 294 | } | 
|---|
| [1071] | 295 |  | 
|---|
| [1073] | 296 | bRet = RefreshSchedule(); | 
|---|
|  | 297 | } | 
|---|
|  | 298 |  | 
|---|
|  | 299 |  | 
|---|
| [1071] | 300 | public void RefreshDocument() | 
|---|
|  | 301 | { | 
|---|
| [1070] | 302 | bool bRet = false; | 
|---|
| [1071] | 303 | if (m_sResourcesArray.Count == 0) | 
|---|
|  | 304 | return; | 
|---|
| [1070] | 305 | if (m_sResourcesArray.Count == 1) | 
|---|
|  | 306 | { | 
|---|
|  | 307 | bRet = this.WeekNeedsRefresh(1, m_dSelectedDate, out this.m_dStartDate, out this.m_dEndDate); | 
|---|
|  | 308 | } | 
|---|
|  | 309 | else | 
|---|
|  | 310 | { | 
|---|
|  | 311 | this.m_dStartDate = m_dSelectedDate; | 
|---|
|  | 312 | this.m_dEndDate = m_dSelectedDate; | 
|---|
|  | 313 | this.m_dEndDate = this.m_dEndDate.AddHours(23); | 
|---|
|  | 314 | this.m_dEndDate = this.m_dEndDate.AddMinutes(59); | 
|---|
|  | 315 | this.m_dEndDate = this.m_dEndDate.AddSeconds(59); | 
|---|
|  | 316 | } | 
|---|
| [614] | 317 |  | 
|---|
| [1071] | 318 | bRet = RefreshSchedule(); | 
|---|
| [1073] | 319 |  | 
|---|
| [1071] | 320 | this.UpdateAllViews(); | 
|---|
|  | 321 | } | 
|---|
| [614] | 322 |  | 
|---|
| [1071] | 323 | public void OnOpenDocument() | 
|---|
|  | 324 | { | 
|---|
|  | 325 | try | 
|---|
|  | 326 | { | 
|---|
|  | 327 | //Create new Document | 
|---|
|  | 328 | m_ScheduleType = (m_sResourcesArray.Count == 1) ? ScheduleType.Resource : ScheduleType.Clinic; | 
|---|
|  | 329 | bool bRet = false; | 
|---|
| [614] | 330 |  | 
|---|
| [1071] | 331 | //Set initial From and To dates based on current day | 
|---|
|  | 332 | DateTime dDate = DateTime.Today; | 
|---|
|  | 333 | if (m_ScheduleType == ScheduleType.Resource) | 
|---|
|  | 334 | { | 
|---|
|  | 335 | bRet = this.WeekNeedsRefresh(1, dDate, out this.m_dStartDate, out this.m_dEndDate); | 
|---|
|  | 336 | } | 
|---|
|  | 337 | else | 
|---|
|  | 338 | { | 
|---|
|  | 339 | this.m_dStartDate = dDate; | 
|---|
|  | 340 | this.m_dEndDate = dDate; | 
|---|
|  | 341 | this.m_dEndDate = this.m_dEndDate.AddHours(23); | 
|---|
|  | 342 | this.m_dEndDate = this.m_dEndDate.AddMinutes(59); | 
|---|
|  | 343 | this.m_dEndDate = this.m_dEndDate.AddSeconds(59); | 
|---|
|  | 344 | } | 
|---|
| [614] | 345 |  | 
|---|
| [1071] | 346 | bRet = RefreshSchedule(); | 
|---|
| [614] | 347 |  | 
|---|
| [1071] | 348 | CGView view = null; | 
|---|
|  | 349 | //If this document already has a view, the use it | 
|---|
| [1070] | 350 | //SAM: Why do this again??? | 
|---|
| [1071] | 351 | Hashtable h = CGDocumentManager.Current.Views; | 
|---|
|  | 352 | CGDocument d; | 
|---|
|  | 353 | bool bReuseView = false; | 
|---|
|  | 354 | foreach (CGView v in h.Keys) | 
|---|
|  | 355 | { | 
|---|
|  | 356 | d = (CGDocument)h[v]; | 
|---|
|  | 357 | if (d == this) | 
|---|
|  | 358 | { | 
|---|
|  | 359 | view = v; | 
|---|
|  | 360 | bReuseView = true; | 
|---|
|  | 361 | v.InitializeDocView(this.DocName); | 
|---|
|  | 362 | break; | 
|---|
|  | 363 | } | 
|---|
|  | 364 | } | 
|---|
| [614] | 365 |  | 
|---|
| [1071] | 366 | //Otherwise, create new View | 
|---|
|  | 367 | if (bReuseView == false) | 
|---|
|  | 368 | { | 
|---|
|  | 369 | view = new CGView(); | 
|---|
| [614] | 370 |  | 
|---|
| [1071] | 371 | view.InitializeDocView(this, | 
|---|
|  | 372 | this.DocManager, | 
|---|
|  | 373 | m_dStartDate, | 
|---|
|  | 374 | this.DocName); | 
|---|
| [614] | 375 |  | 
|---|
| [1071] | 376 | view.Show(); | 
|---|
|  | 377 | view.SyncTree(); | 
|---|
| [614] | 378 |  | 
|---|
| [1071] | 379 | } | 
|---|
|  | 380 | this.UpdateAllViews(); | 
|---|
|  | 381 | } | 
|---|
|  | 382 | catch (BMXNetException bmxEx) | 
|---|
|  | 383 | { | 
|---|
|  | 384 | throw bmxEx; | 
|---|
|  | 385 | } | 
|---|
|  | 386 | catch (Exception ex) | 
|---|
|  | 387 | { | 
|---|
|  | 388 | throw new BMXNet.BMXNetException("ClinicalScheduling.OnOpenDocument error:  " + ex.Message); | 
|---|
|  | 389 | } | 
|---|
|  | 390 | } | 
|---|
| [614] | 391 |  | 
|---|
| [1065] | 392 | /// <summary> | 
|---|
|  | 393 | /// Refreshes Availablility and Schedules from RPMS. | 
|---|
|  | 394 | /// </summary> | 
|---|
|  | 395 | /// <returns>Success or Failure. Should be always Success.</returns> | 
|---|
| [1071] | 396 | private bool RefreshSchedule() | 
|---|
|  | 397 | { | 
|---|
|  | 398 | try | 
|---|
|  | 399 | { | 
|---|
|  | 400 | bool bRet = this.RefreshAvailabilitySchedule(); | 
|---|
|  | 401 | if (bRet == false) | 
|---|
|  | 402 | { | 
|---|
|  | 403 | return bRet; | 
|---|
|  | 404 | } | 
|---|
|  | 405 | bRet = this.RefreshDaysSchedule(); | 
|---|
|  | 406 | return bRet; | 
|---|
|  | 407 | } | 
|---|
|  | 408 | catch (ApplicationException aex) | 
|---|
|  | 409 | { | 
|---|
|  | 410 | Debug.Write("CGDocument.RefreshSchedule Application Error:  " + aex.Message + "\n"); | 
|---|
|  | 411 | return false; | 
|---|
|  | 412 | } | 
|---|
|  | 413 | catch (Exception ex) | 
|---|
|  | 414 | { | 
|---|
|  | 415 | MessageBox.Show("CGDocument.RefreshSchedule error:  " + ex.Message + "\n"); | 
|---|
|  | 416 | return false; | 
|---|
|  | 417 | } | 
|---|
|  | 418 | } | 
|---|
| [614] | 419 |  | 
|---|
| [1071] | 420 | private bool RefreshAvailabilitySchedule() | 
|---|
|  | 421 | { | 
|---|
|  | 422 | try | 
|---|
|  | 423 | { | 
|---|
|  | 424 | if (this.m_DocManager.ConnectInfo.Connected == false) | 
|---|
|  | 425 | { | 
|---|
|  | 426 | m_DocManager.ConnectInfo.LoadConnectInfo(); | 
|---|
|  | 427 | } | 
|---|
| [614] | 428 |  | 
|---|
| [1071] | 429 | ArrayList saryApptTypes = new ArrayList(); | 
|---|
|  | 430 | int nApptTypeID = 0; | 
|---|
| [614] | 431 |  | 
|---|
| [1071] | 432 | //Refresh Availability schedules | 
|---|
|  | 433 | DataTable rAvailabilitySchedule; | 
|---|
|  | 434 | rAvailabilitySchedule = CGSchedLib.CreateAvailabilitySchedule(m_DocManager, m_sResourcesArray, this.m_dStartDate, this.m_dEndDate, saryApptTypes,/**/ m_ScheduleType, "0"); | 
|---|
|  | 435 | CGSchedLib.OutputArray(rAvailabilitySchedule, "rAvailabilitySchedule"); | 
|---|
| [614] | 436 |  | 
|---|
| [1071] | 437 | //Refresh Type Schedule | 
|---|
|  | 438 | string sResourceName = ""; | 
|---|
|  | 439 | DataTable rTypeSchedule = new DataTable(); ; | 
|---|
|  | 440 | for (int j = 0; j < m_sResourcesArray.Count; j++) | 
|---|
|  | 441 | { | 
|---|
|  | 442 | sResourceName = m_sResourcesArray[j].ToString(); | 
|---|
|  | 443 | DataTable dtTemp = CGSchedLib.CreateAssignedTypeSchedule(m_DocManager, sResourceName, this.m_dStartDate, this.m_dEndDate, m_ScheduleType); | 
|---|
|  | 444 | CGSchedLib.OutputArray(dtTemp, "dtTemp"); | 
|---|
|  | 445 | if (j == 0) | 
|---|
|  | 446 | { | 
|---|
|  | 447 | rTypeSchedule = dtTemp; | 
|---|
|  | 448 | } | 
|---|
|  | 449 | else | 
|---|
|  | 450 | { | 
|---|
|  | 451 | rTypeSchedule = CGSchedLib.UnionBlocks(rTypeSchedule, dtTemp); | 
|---|
|  | 452 | } | 
|---|
|  | 453 | } | 
|---|
|  | 454 | CGSchedLib.OutputArray(rTypeSchedule, "rTypeSchedule"); | 
|---|
| [614] | 455 |  | 
|---|
| [1071] | 456 | DateTime dStart; | 
|---|
|  | 457 | DateTime dEnd; | 
|---|
|  | 458 | DateTime dTypeStart; | 
|---|
|  | 459 | DateTime dTypeEnd; | 
|---|
|  | 460 | int nSlots; | 
|---|
|  | 461 | Rectangle crRectA = new Rectangle(0, 0, 1, 0); | 
|---|
|  | 462 | Rectangle crRectB = new Rectangle(0, 0, 1, 0); | 
|---|
|  | 463 | bool bIsect; | 
|---|
|  | 464 | string sResourceList; | 
|---|
|  | 465 | string sAccessRuleList; | 
|---|
| [614] | 466 |  | 
|---|
| [1083] | 467 | //smh: moved clear availabilities down here. | 
|---|
|  | 468 | //smh: Temporary solution to make sure that people don't touch the availability table at the same time!!! | 
|---|
|  | 469 | //NOTE: This lock makes sure that availabilities aren't queried for slots when the array is an intermediate | 
|---|
|  | 470 | //state. The other place that has this lock is SlotsAvailable function. | 
|---|
|  | 471 | lock (this.m_pAvArray) | 
|---|
| [1071] | 472 | { | 
|---|
| [1083] | 473 | m_pAvArray.Clear(); | 
|---|
| [614] | 474 |  | 
|---|
| [1083] | 475 | foreach (DataRow rTemp in rAvailabilitySchedule.Rows) | 
|---|
|  | 476 | { | 
|---|
|  | 477 | //get StartTime, EndTime and Slots | 
|---|
|  | 478 | dStart = (DateTime)rTemp["START_TIME"]; | 
|---|
|  | 479 | dEnd = (DateTime)rTemp["END_TIME"]; | 
|---|
| [614] | 480 |  | 
|---|
| [1083] | 481 | //TODO: Fix this slots datatype problem | 
|---|
|  | 482 | string sSlots = rTemp["SLOTS"].ToString(); | 
|---|
|  | 483 | nSlots = Convert.ToInt16(sSlots); | 
|---|
| [614] | 484 |  | 
|---|
| [1083] | 485 | sResourceList = rTemp["RESOURCE"].ToString(); | 
|---|
|  | 486 | sAccessRuleList = rTemp["ACCESS_TYPE"].ToString(); | 
|---|
| [614] | 487 |  | 
|---|
| [1083] | 488 | string sNote = rTemp["NOTE"].ToString(); | 
|---|
|  | 489 |  | 
|---|
|  | 490 | if ((nSlots < -1000) || (sAccessRuleList == "")) | 
|---|
| [1071] | 491 | { | 
|---|
| [1083] | 492 | nApptTypeID = 0; | 
|---|
|  | 493 | } | 
|---|
|  | 494 | else | 
|---|
|  | 495 | { | 
|---|
|  | 496 | foreach (DataRow rType in rTypeSchedule.Rows) | 
|---|
|  | 497 | { | 
|---|
| [614] | 498 |  | 
|---|
| [1083] | 499 | dTypeStart = (DateTime)rType["StartTime"]; | 
|---|
|  | 500 | dTypeEnd = (DateTime)rType["EndTime"]; | 
|---|
|  | 501 | //if start & end times overlap, then | 
|---|
|  | 502 | string sTypeResource = rType["ResourceName"].ToString(); | 
|---|
|  | 503 | if ((dTypeStart.DayOfYear == dStart.DayOfYear) && (sResourceList == sTypeResource)) | 
|---|
| [1071] | 504 | { | 
|---|
| [1083] | 505 | crRectA.Y = GetTotalMinutes(dStart); | 
|---|
|  | 506 | crRectA.Height = GetTotalMinutes(dEnd) - crRectA.Top; | 
|---|
|  | 507 | crRectB.Y = GetTotalMinutes(dTypeStart); | 
|---|
|  | 508 | crRectB.Height = GetTotalMinutes(dTypeEnd) - crRectB.Top; | 
|---|
|  | 509 | bIsect = crRectA.IntersectsWith(crRectB); | 
|---|
|  | 510 | if (bIsect == true) | 
|---|
|  | 511 | { | 
|---|
|  | 512 | //TODO: This code: | 
|---|
|  | 513 | //      nApptTypeID = (int) rType["AppointmentTypeID"]; | 
|---|
|  | 514 | //Causes this exception: | 
|---|
|  | 515 | //Unhandled Exception: System.InvalidCastException: Specified cast is not valid. | 
|---|
|  | 516 | string sTemp = rType["AppointmentTypeID"].ToString(); | 
|---|
|  | 517 | nApptTypeID = Convert.ToInt16(sTemp); | 
|---|
|  | 518 | break; | 
|---|
|  | 519 | } | 
|---|
| [1071] | 520 | } | 
|---|
| [1083] | 521 | }//end foreach datarow rType | 
|---|
|  | 522 | } | 
|---|
| [614] | 523 |  | 
|---|
|  | 524 |  | 
|---|
| [1083] | 525 | AddAvailability(dStart, dEnd, nApptTypeID, nSlots, false, sResourceList, sAccessRuleList, sNote); | 
|---|
|  | 526 | }//end foreach datarow rTemp | 
|---|
|  | 527 | }//end lock | 
|---|
| [1071] | 528 | return true; | 
|---|
|  | 529 | } | 
|---|
|  | 530 | catch (Exception ex) | 
|---|
|  | 531 | { | 
|---|
|  | 532 | Debug.Write("CGDocument.RefreshAvailabilitySchedule error: " + ex.Message + "\n"); | 
|---|
|  | 533 | return false; | 
|---|
|  | 534 | } | 
|---|
|  | 535 | } | 
|---|
| [614] | 536 |  | 
|---|
| [1071] | 537 | private int GetTotalMinutes(DateTime dDate) | 
|---|
|  | 538 | { | 
|---|
|  | 539 | return ((dDate.Hour * 60) + dDate.Minute); | 
|---|
|  | 540 | } | 
|---|
| [614] | 541 |  | 
|---|
| [1083] | 542 | /// <summary> | 
|---|
|  | 543 | /// Adds Availability to Availability Array held by document | 
|---|
|  | 544 | /// </summary> | 
|---|
|  | 545 | /// <param name="StartTime">Self-Explan</param> | 
|---|
|  | 546 | /// <param name="EndTime">Self-Explan</param> | 
|---|
|  | 547 | /// <param name="nType"></param> | 
|---|
|  | 548 | /// <param name="nSlots"></param> | 
|---|
|  | 549 | /// <param name="UpdateView"></param> | 
|---|
|  | 550 | /// <param name="sResourceList"></param> | 
|---|
|  | 551 | /// <param name="sAccessRuleList"></param> | 
|---|
|  | 552 | /// <param name="sNote"></param> | 
|---|
|  | 553 | /// <returns></returns> | 
|---|
| [1071] | 554 | public int AddAvailability(DateTime StartTime, DateTime EndTime, int nType, int nSlots, bool UpdateView, string sResourceList, string sAccessRuleList, string sNote) | 
|---|
|  | 555 | { | 
|---|
|  | 556 | //adds it to the object array | 
|---|
|  | 557 | //Returns the index in the array | 
|---|
| [614] | 558 |  | 
|---|
| [1071] | 559 | CGAvailability pNewAv = new CGAvailability(); | 
|---|
|  | 560 | pNewAv.Create(StartTime, EndTime, nType, nSlots, sResourceList, sAccessRuleList); | 
|---|
| [614] | 561 |  | 
|---|
| [1071] | 562 | pNewAv.Note = sNote; | 
|---|
| [614] | 563 |  | 
|---|
| [1071] | 564 | //Look up the color and type name using the AppointmentTypes datatable | 
|---|
|  | 565 | DataTable dtType = this.m_DocManager.GlobalDataSet.Tables["AccessTypes"]; | 
|---|
|  | 566 | DataRow dRow = dtType.Rows.Find(nType.ToString()); | 
|---|
|  | 567 | if (dRow != null) | 
|---|
|  | 568 | { | 
|---|
|  | 569 | string sColor = dRow["DISPLAY_COLOR"].ToString(); | 
|---|
|  | 570 | pNewAv.DisplayColor = sColor; | 
|---|
|  | 571 | string sTemp = dRow["RED"].ToString(); | 
|---|
|  | 572 | sTemp = (sTemp == "") ? "0" : sTemp; | 
|---|
|  | 573 | int nRed = Convert.ToInt16(sTemp); | 
|---|
|  | 574 | pNewAv.Red = nRed; | 
|---|
|  | 575 | sTemp = dRow["GREEN"].ToString(); | 
|---|
|  | 576 | sTemp = (sTemp == "") ? "0" : sTemp; | 
|---|
|  | 577 | int nGreen = Convert.ToInt16(sTemp); | 
|---|
|  | 578 | pNewAv.Green = nGreen; | 
|---|
|  | 579 | sTemp = dRow["BLUE"].ToString(); | 
|---|
|  | 580 | sTemp = (sTemp == "") ? "0" : sTemp; | 
|---|
|  | 581 | int nBlue = Convert.ToInt16(sTemp); | 
|---|
|  | 582 | pNewAv.Blue = nBlue; | 
|---|
| [614] | 583 |  | 
|---|
| [1071] | 584 | string sName = dRow["ACCESS_TYPE_NAME"].ToString(); | 
|---|
|  | 585 | pNewAv.AccessTypeName = sName; | 
|---|
|  | 586 | } | 
|---|
| [614] | 587 |  | 
|---|
| [1071] | 588 | int nIndex = 0; | 
|---|
|  | 589 | nIndex = m_pAvArray.Add(pNewAv); | 
|---|
|  | 590 | if (UpdateView == true) | 
|---|
|  | 591 | { | 
|---|
|  | 592 | this.UpdateAllViews(); | 
|---|
|  | 593 | } | 
|---|
|  | 594 | return nIndex; | 
|---|
|  | 595 | } | 
|---|
| [614] | 596 |  | 
|---|
| [1071] | 597 |  | 
|---|
|  | 598 | public void AddResource(string sResource) | 
|---|
|  | 599 | { | 
|---|
|  | 600 | //TODO:  Test that resource is not currently in list, that it IS a resource, etc | 
|---|
|  | 601 | this.m_sResourcesArray.Add(sResource); | 
|---|
|  | 602 | } | 
|---|
| [614] | 603 |  | 
|---|
| [1071] | 604 | public int SlotsAvailable(DateTime dSelStart, DateTime dSelEnd, string sResource, out string sAccessType, out string sAvailabilityMessage) | 
|---|
|  | 605 | { | 
|---|
|  | 606 | sAccessType = ""; | 
|---|
|  | 607 | sAvailabilityMessage = ""; | 
|---|
|  | 608 | DateTime dStart; | 
|---|
|  | 609 | DateTime dEnd; | 
|---|
|  | 610 | int nAvailableSlots = 999; | 
|---|
|  | 611 | int nSlots = 0; | 
|---|
|  | 612 | int i = 0; | 
|---|
|  | 613 | CGAvailability pAv; | 
|---|
|  | 614 | Rectangle crRectA = new Rectangle(0, 0, 1, 0); | 
|---|
|  | 615 | Rectangle crRectB = new Rectangle(0, 0, 1, 0); | 
|---|
|  | 616 | bool bIsect; | 
|---|
|  | 617 | crRectB.Y = GetTotalMinutes(dSelStart); | 
|---|
|  | 618 | crRectB.Height = GetTotalMinutes(dSelEnd) - crRectB.Y; | 
|---|
| [614] | 619 |  | 
|---|
| [1083] | 620 | //NOTE: What's this lock? This lock makes sure that nobody is editing the availability array | 
|---|
|  | 621 | //when we are looking at it. Since the availability array could potentially be updated on | 
|---|
|  | 622 | //a different thread, we are can be potentially left stuck with an empty array. | 
|---|
|  | 623 | // | 
|---|
|  | 624 | //The other place that uses this lock is the RefershAvailabilitySchedule method | 
|---|
|  | 625 | // | 
|---|
|  | 626 | //This is a temporary fix until I figure out how to divorce the availbilities here from those drawn | 
|---|
|  | 627 | //on the calendar. Appointments are cloned b/c they are in an object that supports that; and b/c I | 
|---|
|  | 628 | //don't need to suddenly query them at runtime like I do with Availabilities. | 
|---|
|  | 629 |  | 
|---|
|  | 630 | lock (this.m_pAvArray) | 
|---|
| [1071] | 631 | { | 
|---|
| [1083] | 632 | //loop thru m_pAvArray | 
|---|
|  | 633 | //Compare the start time and end time of eachblock | 
|---|
|  | 634 | while (i < m_pAvArray.Count) | 
|---|
| [1071] | 635 | { | 
|---|
| [1083] | 636 | pAv = (CGAvailability)m_pAvArray[i]; | 
|---|
|  | 637 | dStart = pAv.StartTime; | 
|---|
|  | 638 | dEnd = pAv.EndTime; | 
|---|
|  | 639 | if ((sResource == pAv.ResourceList) && | 
|---|
|  | 640 | ((dSelStart.Date == dStart.Date) || (dSelStart.Date == dEnd.Date))) | 
|---|
| [1071] | 641 | { | 
|---|
| [1083] | 642 | crRectA.Y = (dStart.Date < dSelStart.Date) ? 0 : GetTotalMinutes(dStart); | 
|---|
|  | 643 | crRectA.Height = (dEnd.Date > dSelEnd.Date) ? 1440 : GetTotalMinutes(dEnd); | 
|---|
|  | 644 | crRectA.Height = crRectA.Height - crRectA.Y; | 
|---|
|  | 645 | bIsect = crRectA.IntersectsWith(crRectB); | 
|---|
|  | 646 | if (bIsect != false) | 
|---|
| [1071] | 647 | { | 
|---|
| [1083] | 648 | nSlots = pAv.Slots; | 
|---|
|  | 649 | if (nSlots < 1) | 
|---|
|  | 650 | { | 
|---|
|  | 651 | nAvailableSlots = 0; | 
|---|
|  | 652 | break; | 
|---|
|  | 653 | } | 
|---|
|  | 654 | if (nSlots < nAvailableSlots) | 
|---|
|  | 655 | { | 
|---|
|  | 656 | nAvailableSlots = nSlots; | 
|---|
|  | 657 | sAccessType = pAv.AccessTypeName; | 
|---|
|  | 658 | sAvailabilityMessage = pAv.Note; | 
|---|
| [614] | 659 |  | 
|---|
| [1083] | 660 | } | 
|---|
|  | 661 | }//end if | 
|---|
|  | 662 | }//end if | 
|---|
|  | 663 | i++; | 
|---|
|  | 664 | }//end while | 
|---|
|  | 665 | }//end lock | 
|---|
|  | 666 |  | 
|---|
| [1071] | 667 | if (nAvailableSlots == 999) | 
|---|
|  | 668 | { | 
|---|
|  | 669 | nAvailableSlots = 0; | 
|---|
|  | 670 | } | 
|---|
|  | 671 | return nAvailableSlots; | 
|---|
|  | 672 | } | 
|---|
|  | 673 |  | 
|---|
|  | 674 | /// <summary> | 
|---|
|  | 675 | /// Given a selected date, | 
|---|
|  | 676 | /// Calculates StartDay and End Day and returns them in output params. | 
|---|
|  | 677 | /// nWeeks == number of Weeks to display | 
|---|
|  | 678 | /// nColumnCount is number of days displayed per week. | 
|---|
| [886] | 679 | /// If 5 columns, begin on Second Day of Week | 
|---|
| [1071] | 680 | /// If 7 Columns, begin on First Day of Week | 
|---|
| [886] | 681 | /// (this is a change from the hardcoded behavior for US-based calendars) | 
|---|
| [1071] | 682 | /// | 
|---|
|  | 683 | /// Returns TRUE if the document's data needs refreshing based on | 
|---|
|  | 684 | /// this newly selected date. | 
|---|
|  | 685 | /// </summary> | 
|---|
|  | 686 | public bool WeekNeedsRefresh(int nWeeks, DateTime SelectedDate, | 
|---|
|  | 687 | out DateTime WeekStartDay, out DateTime WeekEndDay) | 
|---|
|  | 688 | { | 
|---|
|  | 689 | DateTime OldStartDay = m_dStartDate; | 
|---|
|  | 690 | DateTime OldEndDay = m_dEndDate; | 
|---|
| [908] | 691 | // Week start based on thread locale | 
|---|
|  | 692 | int nStartWeekDay = (int)System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek; | 
|---|
| [913] | 693 | // Current Day | 
|---|
| [1071] | 694 | int nWeekDay = (int)SelectedDate.DayOfWeek; //0 == Sunday | 
|---|
| [614] | 695 |  | 
|---|
| [1071] | 696 | // this offset gets approrpriate day based on locale. | 
|---|
| [886] | 697 | int nOff = (nStartWeekDay + 1) % 7; | 
|---|
| [1071] | 698 | TimeSpan ts = new TimeSpan(nWeekDay - nOff, 0, 0, 0); //d,h,m,s | 
|---|
| [614] | 699 |  | 
|---|
| [913] | 700 | // if ts is negative, we will jump to the next week in the logic. | 
|---|
|  | 701 | // to show the correct week, add 7. Confusing, I know. | 
|---|
| [1071] | 702 | if (ts < new TimeSpan()) ts = ts + new TimeSpan(7, 0, 0, 0); | 
|---|
| [913] | 703 |  | 
|---|
| [1071] | 704 | if (m_nColumnCount == 1) // if one column start and end on the same day. | 
|---|
|  | 705 | { | 
|---|
|  | 706 | ts = new TimeSpan(0, 23, 59, 59); | 
|---|
|  | 707 | WeekStartDay = SelectedDate; | 
|---|
| [913] | 708 | WeekEndDay = WeekStartDay + ts; | 
|---|
| [1071] | 709 | } | 
|---|
| [913] | 710 | else if (m_nColumnCount == 5 || m_nColumnCount == 0) // if 5 column start (or default) at the 2nd day of this week and end in 4:23:59:59 days. | 
|---|
|  | 711 | { | 
|---|
|  | 712 | // if picked day is start of week (Sunday in US), start in the next day since that's the first day of work week | 
|---|
|  | 713 | // else, just substract the calculated time span to get to the start of week (first work day) | 
|---|
| [1071] | 714 | WeekStartDay = (nWeekDay == nStartWeekDay) ? SelectedDate + new TimeSpan(1, 0, 0, 0) : SelectedDate - ts; | 
|---|
| [913] | 715 | // End day calculation | 
|---|
|  | 716 | int nEnd = 3; | 
|---|
|  | 717 | ts = new TimeSpan((7 * nWeeks) - nEnd, 23, 59, 59); | 
|---|
|  | 718 | WeekEndDay = WeekStartDay + ts; | 
|---|
|  | 719 | } | 
|---|
|  | 720 | else // if 7 column start at the 1st day of this week and end in 6:23:59:59 days. | 
|---|
|  | 721 | { | 
|---|
|  | 722 | // if picked day is start of week, use that. Otherwise, go to the fist work day and substract one to get to start of week. | 
|---|
| [1071] | 723 | WeekStartDay = (nWeekDay == nStartWeekDay) ? SelectedDate : SelectedDate - ts - new TimeSpan(1, 0, 0, 0); | 
|---|
| [913] | 724 | // End day calculation | 
|---|
|  | 725 | int nEnd = 1; | 
|---|
|  | 726 | ts = new TimeSpan((7 * nWeeks) - nEnd, 23, 59, 59); | 
|---|
|  | 727 | WeekEndDay = WeekStartDay + ts; | 
|---|
|  | 728 | } | 
|---|
|  | 729 |  | 
|---|
| [1071] | 730 | bool bRet = ((WeekStartDay.Date != OldStartDay.Date) || (WeekEndDay.Date != OldEndDay.Date)); | 
|---|
|  | 731 | return bRet; | 
|---|
|  | 732 | } | 
|---|
| [614] | 733 |  | 
|---|
| [1071] | 734 | /// <summary> | 
|---|
|  | 735 | /// Calls RPMS to create appointment then | 
|---|
|  | 736 | /// adds appointment to the m_appointments collection | 
|---|
|  | 737 | /// Returns the IEN of the appointment in the RPMS BSDX APPOINTMENT file. | 
|---|
|  | 738 | /// </summary> | 
|---|
|  | 739 | /// <param name="rApptInfo"></param> | 
|---|
|  | 740 | /// <returns></returns> | 
|---|
|  | 741 | public int CreateAppointment(CGAppointment rApptInfo) | 
|---|
|  | 742 | { | 
|---|
|  | 743 | return CreateAppointment(rApptInfo, false); | 
|---|
|  | 744 | } | 
|---|
| [614] | 745 |  | 
|---|
| [1071] | 746 | /// <summary> | 
|---|
|  | 747 | /// Use this overload to create a walkin appointment | 
|---|
|  | 748 | /// </summary> | 
|---|
|  | 749 | /// <param name="rApptInfo"></param> | 
|---|
|  | 750 | /// <param name="bWalkin"></param> | 
|---|
|  | 751 | /// <returns></returns> | 
|---|
|  | 752 | public int CreateAppointment(CGAppointment rApptInfo, bool bWalkin) | 
|---|
|  | 753 | { | 
|---|
|  | 754 | string sStart; | 
|---|
|  | 755 | string sEnd; | 
|---|
|  | 756 | string sPatID; | 
|---|
|  | 757 | string sResource; | 
|---|
|  | 758 | string sNote; | 
|---|
|  | 759 | string sLen; | 
|---|
|  | 760 | string sApptID; | 
|---|
| [864] | 761 |  | 
|---|
| [1071] | 762 | //sStart = rApptInfo.StartTime.ToString("M-d-yyyy@HH:mm"); | 
|---|
|  | 763 | //sEnd = rApptInfo.EndTime.ToString("M-d-yyyy@HH:mm"); | 
|---|
|  | 764 |  | 
|---|
| [864] | 765 | // i18n code -- Use culture neutral FMDates | 
|---|
|  | 766 | sStart = FMDateTime.Create(rApptInfo.StartTime).FMDateString; | 
|---|
|  | 767 | sEnd = FMDateTime.Create(rApptInfo.EndTime).FMDateString; | 
|---|
|  | 768 |  | 
|---|
| [1071] | 769 | TimeSpan sp = rApptInfo.EndTime - rApptInfo.StartTime; | 
|---|
|  | 770 | sLen = sp.TotalMinutes.ToString(); | 
|---|
|  | 771 | sPatID = rApptInfo.PatientID.ToString(); | 
|---|
|  | 772 | sNote = rApptInfo.Note; | 
|---|
|  | 773 | sResource = rApptInfo.Resource; | 
|---|
|  | 774 | if (bWalkin == true) | 
|---|
|  | 775 | { | 
|---|
|  | 776 | sApptID = "WALKIN"; | 
|---|
|  | 777 | } | 
|---|
|  | 778 | else | 
|---|
|  | 779 | { | 
|---|
|  | 780 | sApptID = rApptInfo.AccessTypeID.ToString(); | 
|---|
|  | 781 | } | 
|---|
| [614] | 782 |  | 
|---|
| [1071] | 783 | CGAppointment aCopy = new CGAppointment(); | 
|---|
|  | 784 | aCopy.CreateAppointment(rApptInfo.StartTime, rApptInfo.EndTime, sNote, 0, sResource); | 
|---|
|  | 785 | aCopy.PatientID = rApptInfo.PatientID; | 
|---|
|  | 786 | aCopy.PatientName = rApptInfo.PatientName; | 
|---|
|  | 787 | aCopy.HealthRecordNumber = rApptInfo.HealthRecordNumber; | 
|---|
|  | 788 | aCopy.AccessTypeID = rApptInfo.AccessTypeID; | 
|---|
| [1083] | 789 | aCopy.WalkIn = bWalkin ? true : false; | 
|---|
| [614] | 790 |  | 
|---|
| [1071] | 791 | string sSql = "BSDX ADD NEW APPOINTMENT^" + sStart + "^" + sEnd + "^" + sPatID + "^" + sResource + "^" + sLen + "^" + sNote + "^" + sApptID; | 
|---|
|  | 792 | System.Data.DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "NewAppointment"); | 
|---|
|  | 793 | int nApptID; | 
|---|
| [614] | 794 |  | 
|---|
| [1071] | 795 | Debug.Assert(dtAppt.Rows.Count == 1); | 
|---|
|  | 796 | DataRow r = dtAppt.Rows[0]; | 
|---|
|  | 797 | nApptID = Convert.ToInt32(r["APPOINTMENTID"]); | 
|---|
|  | 798 | string sErrorID; | 
|---|
|  | 799 | sErrorID = r["ERRORID"].ToString(); | 
|---|
|  | 800 | if ((sErrorID != "") || (nApptID < 1)) | 
|---|
| [1084] | 801 | { | 
|---|
| [1071] | 802 | throw new Exception(sErrorID); | 
|---|
| [1084] | 803 | } | 
|---|
| [1071] | 804 | aCopy.AppointmentKey = nApptID; | 
|---|
|  | 805 | this.m_appointments.AddAppointment(aCopy); | 
|---|
| [1083] | 806 |  | 
|---|
|  | 807 |  | 
|---|
|  | 808 | //Have make appointment from CGView responsible for requesting an update for the avialability. | 
|---|
|  | 809 | //bool bRet = RefreshAvailabilitySchedule(); | 
|---|
| [614] | 810 |  | 
|---|
| [1083] | 811 | //Sam: don't think this is needed as it is called from CGView. | 
|---|
|  | 812 | //Make CGView responsible for all drawing. | 
|---|
|  | 813 | //UpdateAllViews(); | 
|---|
| [614] | 814 |  | 
|---|
| [1071] | 815 | return nApptID; | 
|---|
|  | 816 | } | 
|---|
| [614] | 817 |  | 
|---|
| [1071] | 818 | public void EditAppointment(CGAppointment pAppt, string sNote) | 
|---|
|  | 819 | { | 
|---|
|  | 820 | try | 
|---|
|  | 821 | { | 
|---|
|  | 822 | int nApptID = pAppt.AppointmentKey; | 
|---|
|  | 823 | string sSql = "BSDX EDIT APPOINTMENT^" + nApptID.ToString() + "^" + sNote; | 
|---|
| [614] | 824 |  | 
|---|
| [1071] | 825 | System.Data.DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "EditAppointment"); | 
|---|
| [614] | 826 |  | 
|---|
| [1071] | 827 | Debug.Assert(dtAppt.Rows.Count == 1); | 
|---|
|  | 828 | DataRow r = dtAppt.Rows[0]; | 
|---|
|  | 829 | string sErrorID = r["ERRORID"].ToString(); | 
|---|
|  | 830 | if (sErrorID == "-1") | 
|---|
|  | 831 | pAppt.Note = sNote; | 
|---|
| [614] | 832 |  | 
|---|
| [1071] | 833 | if (this.m_appointments.AppointmentTable.ContainsKey(nApptID)) | 
|---|
|  | 834 | { | 
|---|
|  | 835 | bool bRet = RefreshAvailabilitySchedule(); | 
|---|
|  | 836 | UpdateAllViews(); | 
|---|
|  | 837 | } | 
|---|
|  | 838 | } | 
|---|
|  | 839 | catch (Exception ex) | 
|---|
|  | 840 | { | 
|---|
|  | 841 | Debug.Write("CGDocument.EditAppointment Failed:  " + ex.Message); | 
|---|
|  | 842 | } | 
|---|
|  | 843 | } | 
|---|
| [614] | 844 |  | 
|---|
| [1071] | 845 | public void CheckInAppointment(int nApptID, DateTime dCheckIn) | 
|---|
|  | 846 | { | 
|---|
|  | 847 | string sCheckIn = FMDateTime.Create(dCheckIn).FMDateString; | 
|---|
|  | 848 |  | 
|---|
| [1062] | 849 | string sSql = "BSDX CHECKIN APPOINTMENT^" + nApptID.ToString() + "^" + sCheckIn; // +"^"; | 
|---|
| [1071] | 850 | //sSql += ClinicStopIEN + "^" + ProviderIEN + "^" + PrintRouteSlip + "^"; | 
|---|
|  | 851 | //sSql += PCCClinicIEN + "^" + PCCFormIEN + "^" + PCCOutGuide; | 
|---|
| [614] | 852 |  | 
|---|
| [1071] | 853 | System.Data.DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "CheckInAppointment"); | 
|---|
| [614] | 854 |  | 
|---|
| [1071] | 855 | Debug.Assert(dtAppt.Rows.Count == 1); | 
|---|
|  | 856 | DataRow r = dtAppt.Rows[0]; | 
|---|
|  | 857 | string sErrorID = r["ERRORID"].ToString(); | 
|---|
| [614] | 858 |  | 
|---|
| [1083] | 859 |  | 
|---|
| [1071] | 860 | } | 
|---|
| [614] | 861 |  | 
|---|
| [1071] | 862 | public string DeleteAppointment(int nApptID) | 
|---|
|  | 863 | { | 
|---|
|  | 864 | return DeleteAppointment(nApptID, true, 0, ""); | 
|---|
|  | 865 | } | 
|---|
| [614] | 866 |  | 
|---|
| [1071] | 867 | public string DeleteAppointment(int nApptID, bool bClinicCancelled, int nReason, string sRemarks) | 
|---|
|  | 868 | { | 
|---|
|  | 869 | //Returns "" if deletion successful | 
|---|
|  | 870 | //Otherwise, returns reason for failure | 
|---|
| [614] | 871 |  | 
|---|
| [1071] | 872 | string sClinicCancelled = (bClinicCancelled == true) ? "C" : "PC"; | 
|---|
|  | 873 | string sReasonID = nReason.ToString(); | 
|---|
|  | 874 | string sSql = "BSDX CANCEL APPOINTMENT^" + nApptID.ToString(); | 
|---|
|  | 875 | sSql += "^" + sClinicCancelled; | 
|---|
|  | 876 | sSql += "^" + sReasonID; | 
|---|
|  | 877 | sSql += "^" + sRemarks; | 
|---|
|  | 878 | DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "DeleteAppointment"); | 
|---|
| [614] | 879 |  | 
|---|
| [1071] | 880 | Debug.Assert(dtAppt.Rows.Count == 1); | 
|---|
|  | 881 | DataRow r = dtAppt.Rows[0]; | 
|---|
|  | 882 | string sErrorID = r["ERRORID"].ToString(); | 
|---|
|  | 883 | if (sErrorID != "") | 
|---|
|  | 884 | return sErrorID; | 
|---|
| [614] | 885 |  | 
|---|
| [1071] | 886 | if (this.m_appointments.AppointmentTable.ContainsKey(nApptID)) | 
|---|
|  | 887 | { | 
|---|
|  | 888 | this.m_appointments.RemoveAppointment(nApptID); | 
|---|
| [1084] | 889 |  | 
|---|
|  | 890 | // View responsible for deciding to redraw the grid; not the document now. | 
|---|
|  | 891 | //bool bRet = RefreshAvailabilitySchedule(); | 
|---|
|  | 892 | //UpdateAllViews(); | 
|---|
| [1071] | 893 | } | 
|---|
|  | 894 | return ""; | 
|---|
|  | 895 | } | 
|---|
| [614] | 896 |  | 
|---|
| [1071] | 897 | public string AutoRebook(CGAppointment a, int nSearchType, int nMinimumDays, int nMaximumDays, out CGAppointment aRebook) | 
|---|
|  | 898 | { | 
|---|
|  | 899 | //If successful Returns "1" and new start date and time returned in aRebook | 
|---|
|  | 900 | //Otherwise, returns error message | 
|---|
| [614] | 901 |  | 
|---|
| [1071] | 902 | CGAppointment aCopy = new CGAppointment(); | 
|---|
|  | 903 | aCopy.CreateAppointment(a.StartTime, a.EndTime, a.Note, 0, a.Resource); | 
|---|
|  | 904 | aCopy.PatientID = a.PatientID; | 
|---|
|  | 905 | aCopy.PatientName = a.PatientName; | 
|---|
|  | 906 | aCopy.HealthRecordNumber = a.HealthRecordNumber; | 
|---|
|  | 907 | aCopy.AccessTypeID = a.AccessTypeID; | 
|---|
|  | 908 | aRebook = aCopy; | 
|---|
| [614] | 909 |  | 
|---|
| [1071] | 910 | //Determine Rebook access type | 
|---|
|  | 911 | //nSearchType = -1: use current, -2: use any non-zero type, >0 use this access type id | 
|---|
|  | 912 | int nAVType = 0; | 
|---|
| [614] | 913 |  | 
|---|
| [1071] | 914 | switch (nSearchType) | 
|---|
|  | 915 | { | 
|---|
|  | 916 | case -1: | 
|---|
|  | 917 | nAVType = a.AccessTypeID; | 
|---|
|  | 918 | break; | 
|---|
|  | 919 | case -2: | 
|---|
|  | 920 | nAVType = 0; | 
|---|
|  | 921 | break; | 
|---|
|  | 922 | default: | 
|---|
|  | 923 | nAVType = nSearchType; | 
|---|
|  | 924 | break; | 
|---|
|  | 925 | } | 
|---|
| [614] | 926 |  | 
|---|
| [1071] | 927 | int nSlots = 0; | 
|---|
|  | 928 | string sSlots = ""; | 
|---|
|  | 929 | int nAccessTypeID;  //To compare with nAVType | 
|---|
| [614] | 930 |  | 
|---|
| [1071] | 931 | DateTime dResult = new DateTime(); //StartTime of access block to autorebook into | 
|---|
| [614] | 932 |  | 
|---|
| [1071] | 933 | //Next two are empty, but needed to pass to CreateAvailabilitySchedule | 
|---|
|  | 934 | ArrayList alAccessTypes = new ArrayList(); | 
|---|
|  | 935 | string sSearchInfo = ""; | 
|---|
| [614] | 936 |  | 
|---|
| [1071] | 937 | //Find the StartTime of first availability block of this type for this clinic | 
|---|
|  | 938 | //between nMinimumDays and nMaximumDays | 
|---|
| [614] | 939 |  | 
|---|
| [1071] | 940 | string sAVStart = a.StartTime.AddDays(nMinimumDays).ToString("M/d/yyyy@H:mm"); | 
|---|
| [614] | 941 |  | 
|---|
| [1071] | 942 | //dtAVEnd is the last day to search | 
|---|
|  | 943 | DateTime dtAVEnd = a.StartTime.AddDays(nMinimumDays + nMaximumDays); | 
|---|
|  | 944 | string sAVEnd = dtAVEnd.ToString("M/d/yyyy@H:mm"); | 
|---|
|  | 945 |  | 
|---|
|  | 946 | //Increment start day to search a week (or so) at a time | 
|---|
|  | 947 | //30 is a test increment.  Need to test different values for performance | 
|---|
|  | 948 | int nIncrement = (nMaximumDays < 30) ? nMaximumDays : 30; | 
|---|
|  | 949 |  | 
|---|
|  | 950 | //nCount and nCountEnd are the 'moving' counters | 
|---|
|  | 951 | //that I add to start and end to get the bracket | 
|---|
|  | 952 | //At the beginning of the DO loop, nCount and nCountEnd are already set | 
|---|
|  | 953 | bool bFinished = false; | 
|---|
|  | 954 | bool bFound = false; | 
|---|
|  | 955 |  | 
|---|
|  | 956 | DateTime dStart = a.StartTime.AddDays(nMinimumDays); | 
|---|
| [864] | 957 | // v 1.3 i18n support - FM Date passed insated of American Date | 
|---|
|  | 958 | string sStart = FMDateTime.Create(dStart).DateOnly.FMDateString; | 
|---|
| [1071] | 959 | DateTime dEnd = dStart.AddDays(nIncrement); | 
|---|
|  | 960 | do | 
|---|
|  | 961 | { | 
|---|
|  | 962 | string sSql = "BSDX REBOOK NEXT BLOCK^" + sStart + "^" + a.Resource + "^" + nAVType.ToString(); | 
|---|
|  | 963 | DataTable dtNextBlock = this.DocManager.RPMSDataTable(sSql, "NextBlock"); | 
|---|
|  | 964 | Debug.Assert(dtNextBlock.Rows.Count == 1); | 
|---|
|  | 965 | DataRow drNextBlockRow = dtNextBlock.Rows[0]; | 
|---|
| [614] | 966 |  | 
|---|
| [1071] | 967 | object oNextBlock; | 
|---|
|  | 968 | oNextBlock = drNextBlockRow["NEXTBLOCK"]; | 
|---|
|  | 969 | if (oNextBlock.GetType() == typeof(System.DBNull)) | 
|---|
|  | 970 | break; | 
|---|
|  | 971 | DateTime dNextBlock = (DateTime)drNextBlockRow["NEXTBLOCK"]; | 
|---|
|  | 972 | if (dNextBlock > dtAVEnd) | 
|---|
|  | 973 | { | 
|---|
|  | 974 | break; | 
|---|
|  | 975 | } | 
|---|
| [614] | 976 |  | 
|---|
| [1071] | 977 | dStart = dNextBlock; | 
|---|
|  | 978 | dEnd = dStart.AddDays(nIncrement); | 
|---|
|  | 979 | if (dEnd > dtAVEnd) | 
|---|
|  | 980 | dEnd = dtAVEnd; | 
|---|
| [614] | 981 |  | 
|---|
| [1071] | 982 | DataTable dtResult = CGSchedLib.CreateAvailabilitySchedule(m_DocManager, this.Resources, dStart, dEnd, alAccessTypes, ScheduleType.Resource, sSearchInfo); | 
|---|
|  | 983 | //Loop thru dtResult looking for a slot having the required availability type. | 
|---|
|  | 984 | //If found, set bFinished = true; | 
|---|
|  | 985 | foreach (DataRow dr in dtResult.Rows) | 
|---|
|  | 986 | { | 
|---|
| [614] | 987 |  | 
|---|
| [1071] | 988 | sSlots = dr["SLOTS"].ToString(); | 
|---|
|  | 989 | if (sSlots == "") | 
|---|
|  | 990 | sSlots = "0"; | 
|---|
|  | 991 | nSlots = Convert.ToInt16(sSlots); | 
|---|
|  | 992 | if (nSlots > 0) | 
|---|
|  | 993 | { | 
|---|
|  | 994 | nAccessTypeID = 0;  //holds the access type id of the availability block | 
|---|
|  | 995 | if (dr["ACCESS_TYPE"].ToString() != "") | 
|---|
|  | 996 | nAccessTypeID = Convert.ToInt16(dr["ACCESS_TYPE"].ToString()); | 
|---|
|  | 997 | if ((nSearchType == -2) && (nAccessTypeID > 0)) //Match on any non-zero type | 
|---|
|  | 998 | { | 
|---|
|  | 999 | bFinished = true; | 
|---|
|  | 1000 | bFound = true; | 
|---|
|  | 1001 | dResult = (DateTime)dr["START_TIME"]; | 
|---|
|  | 1002 | break; | 
|---|
|  | 1003 | } | 
|---|
|  | 1004 | if (nAccessTypeID == nAVType) | 
|---|
|  | 1005 | { | 
|---|
|  | 1006 | bFinished = true; | 
|---|
|  | 1007 | bFound = true; | 
|---|
|  | 1008 | dResult = (DateTime)dr["START_TIME"]; | 
|---|
|  | 1009 | break; | 
|---|
|  | 1010 | } | 
|---|
|  | 1011 | } | 
|---|
|  | 1012 | } | 
|---|
|  | 1013 | dStart = dEnd.AddDays(1); | 
|---|
|  | 1014 | dEnd = dStart.AddDays(nIncrement); | 
|---|
|  | 1015 | if (dEnd > dtAVEnd) | 
|---|
|  | 1016 | dEnd = dtAVEnd; | 
|---|
|  | 1017 | } while (bFinished == false); | 
|---|
| [614] | 1018 |  | 
|---|
| [1071] | 1019 | if (bFound == true) | 
|---|
|  | 1020 | { | 
|---|
|  | 1021 | aCopy.StartTime = dResult; | 
|---|
|  | 1022 | aCopy.EndTime = dResult.AddMinutes(a.Duration); | 
|---|
|  | 1023 | //Create the appointment | 
|---|
|  | 1024 | //Set the AUTOREBOOKED flag | 
|---|
|  | 1025 | //and store the "AutoRebooked To DateTime" | 
|---|
|  | 1026 | //in each autorebooked appointment | 
|---|
|  | 1027 | this.CreateAppointment(aCopy); | 
|---|
|  | 1028 | SetAutoRebook(a, dResult); | 
|---|
|  | 1029 | return "1"; | 
|---|
|  | 1030 | } | 
|---|
|  | 1031 | else | 
|---|
|  | 1032 | { | 
|---|
|  | 1033 | return "0"; | 
|---|
|  | 1034 | } | 
|---|
|  | 1035 | } | 
|---|
|  | 1036 |  | 
|---|
|  | 1037 | private void SetAutoRebook(CGAppointment a, DateTime dtRebookedTo) | 
|---|
|  | 1038 | { | 
|---|
|  | 1039 | string sApptKey = a.AppointmentKey.ToString(); | 
|---|
|  | 1040 | //string sRebookedTo = dtRebookedTo.ToString("M/d/yyyy@HH:mm"); | 
|---|
| [864] | 1041 | // i18n | 
|---|
|  | 1042 | string sRebookedTo = FMDateTime.Create(dtRebookedTo).FMDateString; | 
|---|
| [1071] | 1043 | string sSql = "BSDX REBOOK SET^" + sApptKey + "^" + sRebookedTo; | 
|---|
|  | 1044 | System.Data.DataTable dtRebook = m_DocManager.RPMSDataTable(sSql, "AutoRebook"); | 
|---|
| [614] | 1045 |  | 
|---|
| [1071] | 1046 | } | 
|---|
| [614] | 1047 |  | 
|---|
| [1071] | 1048 | public string AppointmentNoShow(int nApptID, bool bNoShow) | 
|---|
|  | 1049 | { | 
|---|
|  | 1050 | /* | 
|---|
|  | 1051 | * BSDX NOSHOW RPC Returns 1  in ERRORID if  successfully sets NOSHOW flag in BSDX APPOINTMENT and, if applicable, File 2 | 
|---|
|  | 1052 | *Otherwise, returns negative numbers for failure and errormessage in ERRORTXT | 
|---|
|  | 1053 | * | 
|---|
|  | 1054 | */ | 
|---|
| [614] | 1055 |  | 
|---|
| [1071] | 1056 | string sTest = bNoShow.ToString(); | 
|---|
|  | 1057 | string sNoShow = (bNoShow == true) ? "1" : "0"; | 
|---|
|  | 1058 | string sSql = "BSDX NOSHOW^" + nApptID.ToString(); | 
|---|
|  | 1059 | sSql += "^"; | 
|---|
|  | 1060 | sSql += sNoShow; | 
|---|
| [614] | 1061 |  | 
|---|
| [1071] | 1062 | DataTable dtAppt = m_DocManager.RPMSDataTable(sSql, "AppointmentNoShow"); | 
|---|
| [614] | 1063 |  | 
|---|
| [1071] | 1064 | Debug.Assert(dtAppt.Rows.Count == 1); | 
|---|
|  | 1065 | DataRow r = dtAppt.Rows[0]; | 
|---|
|  | 1066 | string sErrorID = r["ERRORID"].ToString(); | 
|---|
|  | 1067 | if (sErrorID != "1") | 
|---|
|  | 1068 | { | 
|---|
|  | 1069 | return r["ERRORTEXT"].ToString(); | 
|---|
|  | 1070 | } | 
|---|
| [614] | 1071 |  | 
|---|
| [1071] | 1072 | bool bRet = RefreshSchedule(); | 
|---|
| [614] | 1073 |  | 
|---|
| [1071] | 1074 | return sErrorID; | 
|---|
|  | 1075 | } | 
|---|
|  | 1076 |  | 
|---|
|  | 1077 | #endregion Methods | 
|---|
|  | 1078 |  | 
|---|
|  | 1079 | }//End class | 
|---|
| [614] | 1080 | }//End namespace | 
|---|