source: Scheduling/trunk/cs/bsdx0200GUISourceCode/CGDocumentManager.cs@ 821

Last change on this file since 821 was 821, checked in by Sam Habiel, 14 years ago

Mostly commenting the code.

File size: 33.2 KB
Line 
1using System;
2using System.Windows.Forms;
3using System.Collections;
4using System.Data;
5using System.Diagnostics;
6using IndianHealthService.BMXNet;
7using Mono.Options;
8using System.Runtime.InteropServices;
9
10namespace IndianHealthService.ClinicalScheduling
11{
12 /// <summary>
13 /// Summary description for DocumentManager.
14 /// </summary>
15 public class CGDocumentManager : System.Windows.Forms.Form
16 {
17 #region Member Variables
18
19 private static CGDocumentManager _current;
20 private Hashtable _views = new Hashtable();
21 private Hashtable m_AVViews = new Hashtable();
22 private string m_sWindowText = "Clinical Scheduling"; //Default Window Text
23 private bool m_bSchedManager;
24 private bool m_bExitOK = true;
25 public string m_sHandle = "0";
26 private string m_AccessCode="";
27 private string m_VerifyCode="";
28 private string m_Server="";
29 private int m_Port=0;
30
31 //M Connection member variables
32 private DataSet m_dsGlobal = null;
33 private System.ComponentModel.IContainer components = null;
34 private BMXNetConnectInfo m_ConnectInfo = null;
35 private BMXNetConnectInfo.BMXNetEventDelegate CDocMgrEventDelegate;
36
37 #endregion
38
39 public CGDocumentManager()
40 {
41 InitializeComponent();
42 m_ConnectInfo = new BMXNetConnectInfo();
43 //m_ConnectInfo.bmxNetLib.StartLog(); //This line turns on logging of messages
44 m_bSchedManager = false;
45 CDocMgrEventDelegate = new BMXNetConnectInfo.BMXNetEventDelegate(CDocMgrEventHandler);
46 m_ConnectInfo.BMXNetEvent += CDocMgrEventDelegate;
47 m_ConnectInfo.EventPollingEnabled = false;
48 }
49
50 #region BMXNet Event Handler
51 private void CDocMgrEventHandler(Object obj, BMXNet.BMXNetEventArgs e)
52 {
53 if (e.BMXEvent == "BSDX CALL WORKSTATIONS")
54 {
55 string sParam = "";
56 string sDelim="~";
57 sParam += this.m_ConnectInfo.UserName + sDelim;
58 sParam += this.m_sHandle + sDelim;
59 sParam += Application.ProductVersion + sDelim;
60 sParam += this._views.Count.ToString();
61 _current.m_ConnectInfo.RaiseEvent("BSDX WORKSTATION REPORT", sParam, true);
62 }
63 if (e.BMXEvent == "BSDX ADMIN MESSAGE")
64 {
65 string sMsg = e.BMXParam;
66 ShowAdminMsgDelegate samd = new ShowAdminMsgDelegate(ShowAdminMsg);
67 this.Invoke(samd, new object [] {sMsg});
68 }
69 if (e.BMXEvent == "BSDX ADMIN SHUTDOWN")
70 {
71 string sMsg = e.BMXParam;
72 CloseAllDelegate cad = new CloseAllDelegate(CloseAll);
73 this.Invoke(cad, new object [] {sMsg});
74 }
75 }
76
77 delegate void ShowAdminMsgDelegate(string sMsg);
78
79 private void ShowAdminMsg(string sMsg)
80 {
81 MessageBox.Show(sMsg, "Message from Scheduling Administrator", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
82 }
83
84 #endregion BMXNet Event Handler
85
86 #region Properties
87
88 /// <summary>
89 /// Returns the document manager's BMXNetConnectInfo member
90 /// </summary>
91 public BMXNetConnectInfo ConnectInfo
92 {
93 get
94 {
95 return m_ConnectInfo;
96 }
97 }
98
99 /// <summary>
100 /// True if the current user holds the BSDXZMGR or XUPROGMODE keys in RPMS
101 /// </summary>
102 public bool ScheduleManager
103 {
104 get
105 {
106 return m_bSchedManager;
107 }
108 }
109
110 /// <summary>
111 /// Holds the user and division
112 /// </summary>
113 public string WindowText
114 {
115 get
116 {
117 return m_sWindowText;
118 }
119 }
120
121 /// <summary>
122 /// This dataset contains tables used by the entire application
123 /// </summary>
124 public DataSet GlobalDataSet
125 {
126 get
127 {
128 return m_dsGlobal;
129 }
130 set
131 {
132 m_dsGlobal = value;
133 }
134 }
135 //public BMXNetConnection ADOConnection
136 //{
137 // get
138 // {
139 // return m_ADOConnection;
140 // }
141 //}
142
143 /// <summary>
144 /// Returns the single CGDocumentManager object
145 /// </summary>
146 public static CGDocumentManager Current
147 {
148 get
149 {
150 return _current;
151 }
152 }
153
154 /// <summary>
155 /// Returns the list of currently opened documents
156 /// </summary>
157 public Hashtable Views
158 {
159 get
160 {
161 return _views;
162 }
163 }
164
165 /// <summary>
166 /// Returns the list of currently opened CGAVViews
167 /// </summary>
168 public Hashtable AvailabilityViews
169 {
170 get
171 {
172 return this.m_AVViews;
173 }
174 }
175
176
177 #endregion
178
179 #region Methods & Events
180 /// <summary>
181 /// Clean up any resources being used.
182 /// </summary>
183 protected override void Dispose( bool disposing )
184 {
185 if( disposing )
186 {
187 if (m_ConnectInfo != null)
188 {
189 m_ConnectInfo.EventPollingEnabled = false;
190 m_ConnectInfo.UnSubscribeEvent("BSDX SCHEDULE");
191 m_ConnectInfo.UnSubscribeEvent("BSDX CALL WORKSTATIONS");
192 m_ConnectInfo.CloseConnection();
193 }
194 if (components != null)
195 {
196 components.Dispose();
197 }
198 }
199 base.Dispose( disposing );
200 }
201
202
203 private void InitializeComponent()
204 {
205 //
206 // CGDocumentManager
207 //
208 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
209 this.ClientSize = new System.Drawing.Size(292, 266);
210 this.Name = "CGDocumentManager";
211
212 }
213
214
215 private DSplash m_ds;
216 public void StartSplash()
217 {
218 m_ds = new DSplash();
219 m_ds.ShowDialog();
220 }
221
222 private void InitializeApp()
223 {
224 InitializeApp(false);
225 }
226
227 private void InitializeApp(bool bReLogin)
228 {
229 try
230 {
231 //Set M connection info
232 //Show a splash screen while initializing
233 m_ds = new DSplash();
234 m_ds.Show(this);
235 m_ds.SetStatus("Loading Configuration Settings...");
236 m_ds.Refresh();
237 this.Activate();
238 // smh--not used System.Configuration.ConfigurationManager.GetSection("appSettings");
239 m_ds.SetStatus("Connecting to VistA Server...");
240 m_ds.Refresh();
241 bool bRetry = true;
242
243 //Try to connect using supplied values for Server and Port
244 //Why am I doing this? The library BMX net uses prompts for access and verify code
245 //whether you can connect or not. Not good. So I test first whether
246 //we can connect at all by doing a simple connection and disconnect.
247 //TODO: Make this more robust by sending a TCPConnect message and seeing if you get a response.
248
249 if (m_Server != "" && m_Port != 0)
250 {
251 System.Net.Sockets.TcpClient tcpClient = new System.Net.Sockets.TcpClient();
252 try
253 {
254 tcpClient.Connect(m_Server, m_Port); // open it
255 tcpClient.Close(); // then close it
256 }
257 catch (System.Net.Sockets.SocketException ex)
258 {
259 throw ex;
260 }
261 }
262 do
263 {
264 // login crap
265 try
266 {
267 // Not my code
268 if (bReLogin == true)
269 {
270 //Prompt for Access and Verify codes
271 _current.m_ConnectInfo.LoadConnectInfo("", "");
272 }
273 // My code -- buts looks so ugly!
274 else
275 {
276 if (m_Server != String.Empty && m_Port != 0 && m_AccessCode != String.Empty
277 && m_VerifyCode != String.Empty)
278 {
279 m_ConnectInfo.LoadConnectInfo(m_Server, m_Port, m_AccessCode, m_VerifyCode);
280 }
281 else if (m_Server != String.Empty && m_Port != 0)
282 m_ConnectInfo.LoadConnectInfo(m_Server, m_Port, "", "");
283 else
284 m_ConnectInfo.LoadConnectInfo();
285 }
286 bRetry = false;
287 }
288 catch (System.Net.Sockets.SocketException)
289 {
290 MessageBox.Show("Cannot connect to VistA. ");
291 }
292 catch (Exception ex)
293 {
294 m_ds.Close();
295 if (MessageBox.Show("Unable to connect to VistA. " + ex.Message, "Clinical Scheduling", MessageBoxButtons.RetryCancel) == DialogResult.Retry)
296 {
297 bRetry = true;
298 _current.m_ConnectInfo.ChangeServerInfo();
299 }
300 else
301 {
302 bRetry = false;
303 throw ex;
304 }
305 }
306 }while (bRetry == true);
307
308 //Create global dataset
309 _current.m_dsGlobal = new DataSet("GlobalDataSet");
310
311 //Version info
312 m_ds.SetStatus("Getting Version Info...");
313 m_ds.Refresh();
314 String sCmd = "BMX VERSION INFO^BSDX^";
315 this.m_ConnectInfo.RPMSDataTable(sCmd, "VersionInfo", m_dsGlobal);
316
317 //Keep the following commented code for future use:
318 //How to extract the version numbers:
319 //DataTable dtVersion = m_dsGlobal.Tables["VersionInfo"];
320 //Debug.Assert(dtVersion.Rows.Count == 1);
321 //DataRow rVersion = dtVersion.Rows[0];
322 //string sMajor = rVersion["MAJOR_VERSION"].ToString();
323 //string sMinor = rVersion["MINOR_VERSION"].ToString();
324 //string sBuild = rVersion["BUILD"].ToString();
325 //decimal fBuild = Convert.ToDecimal(sBuild);
326
327 //Set application context
328 m_ds.SetStatus("Setting Application Context to BSDXRPC...");
329 m_ds.Refresh();
330 m_ConnectInfo.AppContext = "BSDXRPC";
331
332 //Load global recordsets
333 m_ds.SetStatus("Loading VistA data tables...");
334 m_ds.Refresh();
335 if (_current.LoadGlobalRecordsets() == false)
336 {
337 MessageBox.Show("Unable to create VistA recordsets"); //TODO Improve this message
338 m_ds.Close();
339 return;
340 }
341
342 //smh -- why get handles?
343 System.IntPtr pHandle = this.Handle;
344 System.IntPtr pConnHandle = this.ConnectInfo.Handle;
345 this.m_sHandle = pHandle.ToString();
346
347 _current.m_ConnectInfo.ReceiveTimeout = 30000; //30-second timeout
348
349#if DEBUG
350 _current.m_ConnectInfo.ReceiveTimeout = 600000; //longer timeout for debugging
351#endif
352 _current.m_ConnectInfo.SubscribeEvent("BSDX SCHEDULE");
353 _current.m_ConnectInfo.SubscribeEvent("BSDX CALL WORKSTATIONS");
354 _current.m_ConnectInfo.SubscribeEvent("BSDX ADMIN MESSAGE");
355 _current.m_ConnectInfo.SubscribeEvent("BSDX ADMIN SHUTDOWN");
356
357 _current.m_ConnectInfo.EventPollingInterval = 5000; //in milliseconds
358 _current.m_ConnectInfo.EventPollingEnabled = true;
359 _current.m_ConnectInfo.AutoFire = 12; //AutoFire every 12*5 seconds
360
361 m_ds.Close();
362 }
363 catch (Exception ex)
364 {
365 m_ds.Close();
366 Debug.Write(ex.Message);
367 MessageBox.Show(ex.Message + ex.StackTrace, "Clinical Scheduling Error -- Closing Application");
368 throw ex;
369 }
370 }
371
372 //To write to the console
373 [DllImport("kernel32.dll")]
374 static extern bool AttachConsole(int dwProcessId);
375 private const int ATTACH_PARENT_PROCESS = -1;
376
377 [STAThread()]
378 static void Main(string[] args)
379 {
380#if DEBUG
381 // Print console messages to console if launched from console
382 // Note: Imported From kernel32.dll
383 AttachConsole(ATTACH_PARENT_PROCESS);
384#endif
385 try
386 {
387 //Store the current manager
388 _current = new CGDocumentManager();
389
390 //Get command line options; store in private variables
391 var opset = new OptionSet () {
392 { "s=", s => _current.m_Server = s },
393 { "p=", p => _current.m_Port = int.Parse(p) },
394 { "a=", a => _current.m_AccessCode = a },
395 { "v=", v => _current.m_VerifyCode = v }
396 };
397
398 opset.Parse(args);
399
400 try
401 {
402 _current.InitializeApp();
403 }
404 catch (Exception ex)
405 {
406 Debug.Write(ex.Message);
407 return;
408 }
409
410 //Create the first empty document
411 CGDocument doc = new CGDocument();
412 doc.DocManager = _current;
413 doc.OnNewDocument();
414 Application.DoEvents();
415
416 //Run the application
417 Application.Run();
418 }
419 catch (Exception ex)
420 {
421 Debug.Write(ex.Message);
422 MessageBox.Show(ex.Message + ex.StackTrace, "CGDocumentManager.Main(): Clinical Scheduling Error -- Closing Application");
423 return;
424 }
425 }
426
427 public void LoadAccessTypesTable()
428 {
429 string sCommandText = "SELECT * FROM BSDX_ACCESS_TYPE";
430 ConnectInfo.RPMSDataTable(sCommandText, "AccessTypes", m_dsGlobal);
431 Debug.Write("LoadGlobalRecordsets -- AccessTypes loaded\n");
432 }
433
434 public void LoadAccessGroupsTable()
435 {
436 string sCommandText = "SELECT * FROM BSDX_ACCESS_GROUP";
437 ConnectInfo.RPMSDataTable(sCommandText, "AccessGroup", m_dsGlobal);
438 Debug.Write("LoadGlobalRecordsets -- AccessGroups loaded\n");
439 }
440
441 public void LoadAccessGroupTypesTable()
442 {
443 string sCommandText = "BSDX GET ACCESS GROUP TYPES";
444 ConnectInfo.RPMSDataTable(sCommandText, "AccessGroupType", m_dsGlobal);
445 Debug.Write("LoadGlobalRecordsets -- AccessGroupTypes loaded\n");
446 }
447
448 //TODO:REMOVE THIS
449 /*public void LoadClinicSetupTable()
450 {
451 string sCommandText = "BSDX CLINIC SETUP";
452 ConnectInfo.RPMSDataTable(sCommandText, "ClinicSetupParameters", m_dsGlobal);
453 Debug.Write("LoadGlobalRecordsets -- ClinicSetupParameters loaded\n");
454 }*/
455
456 public void LoadBSDXResourcesTable()
457 {
458 string sCommandText = "BSDX RESOURCES^" + m_ConnectInfo.DUZ;
459 ConnectInfo.RPMSDataTable(sCommandText, "Resources", m_dsGlobal);
460 Debug.Write("LoadGlobalRecordsets -- Resources loaded\n");
461 }
462
463 public void LoadResourceGroupTable()
464 {
465 //ResourceGroup Table (Resource Groups by User)
466 //Table "ResourceGroup" contains all resource group names
467 //to which user has access
468 //Fields are: RESOURCE_GROUPID, RESOURCE_GROUP
469 string sCommandText = "BSDX RESOURCE GROUPS BY USER^" + m_ConnectInfo.DUZ;
470 ConnectInfo.RPMSDataTable(sCommandText, "ResourceGroup", m_dsGlobal);
471 Debug.Write("LoadGlobalRecordsets -- ResourceGroup loaded\n");
472 }
473
474 public void LoadGroupResourcesTable()
475 {
476 //Table "GroupResources" contains all active GROUP/RESOURCE combinations
477 //to which user has access based on entries in BSDX RESOURCE USER file
478 //If user has BSDXZMGR or XUPROGMODE keys, then ALL Group/Resource combinstions
479 //are returned.
480 //Fields are: RESOURCE_GROUPID, RESOURCE_GROUP, RESOURCE_GROUP_ITEMID, RESOURCE_NAME, RESOURCE_ID
481 string sCommandText = "BSDX GROUP RESOURCE^" + m_ConnectInfo.DUZ;
482 ConnectInfo.RPMSDataTable(sCommandText, "GroupResources", m_dsGlobal);
483 Debug.Write("LoadGlobalRecordsets -- GroupResources loaded\n");
484 }
485
486 public void LoadScheduleUserTable()
487 {
488 //Table "ScheduleUser" contains an entry for each user in File 200 (NEW PERSON)
489 //who possesses the BSDXZMENU security key.
490 string sCommandText = "BSDX SCHEDULE USER";
491 ConnectInfo.RPMSDataTable(sCommandText, "ScheduleUser", m_dsGlobal);
492 Debug.Write("LoadGlobalRecordsets -- ScheduleUser loaded\n");
493 }
494
495 public void LoadResourceUserTable()
496 {
497 //Table "ResourceUser" duplicates the BSDX RESOURCE USER File.
498 //NOTE: Column names are RESOURCEUSER_ID, RESOURCEID,
499 // OVERBOOK, MODIFY_SCHEDULE, USERID, USERID1
500 //string sCommandText = "SELECT BMXIEN RESOURCEUSER_ID, INTERNAL[RESOURCENAME] RESOURCEID, OVERBOOK, MODIFY_SCHEDULE, USERNAME USERID, INTERNAL[USERNAME] FROM BSDX_RESOURCE_USER";
501 LoadResourceUserTable(false);
502 }
503
504 public void LoadResourceUserTable(bool bAllUsers)
505 {
506 string sCommandText = "SELECT BMXIEN RESOURCEUSER_ID, RESOURCENAME, INTERNAL[RESOURCENAME] RESOURCEID, OVERBOOK, MODIFY_SCHEDULE, MODIFY_APPOINTMENTS, USERNAME, INTERNAL[USERNAME] USERID FROM BSDX_RESOURCE_USER";
507 ConnectInfo.RPMSDataTable(sCommandText, "ResourceUser", m_dsGlobal);
508 Debug.Write("LoadGlobalRecordsets -- ResourceUser loaded\n");
509 }
510
511 private bool LoadGlobalRecordsets()
512 {
513 //Schedule User Info
514 string sCommandText = "BSDX SCHEDULING USER INFO^" + m_ConnectInfo.DUZ;
515 DataTable dtUser = ConnectInfo.RPMSDataTable(sCommandText, "SchedulingUser", m_dsGlobal);
516
517 Debug.Assert(dtUser.Rows.Count == 1);
518 DataRow rUser = dtUser.Rows[0];
519 Object oUser = rUser["MANAGER"];
520 string sUser = oUser.ToString();
521 m_bSchedManager = (sUser == "YES")?true:false;
522
523 //AccessTypes
524 LoadAccessTypesTable();
525
526 //Build Primary Key for AccessTypes table
527 DataTable dtTypes = m_dsGlobal.Tables["AccessTypes"];
528 DataColumn dcKey = dtTypes.Columns["BMXIEN"];
529 DataColumn[] dcKeys = new DataColumn[1];
530 dcKeys[0] = dcKey;
531 dtTypes.PrimaryKey = dcKeys;
532
533 //AccessGroups
534 LoadAccessGroupsTable();
535
536 //Build Primary Key for AccessGroup table
537 DataTable dtGroups = m_dsGlobal.Tables["AccessGroup"];
538 dcKey = dtGroups.Columns["ACCESS_GROUP"];
539 dcKeys = new DataColumn[1];
540 dcKeys[0] = dcKey;
541 dtGroups.PrimaryKey = dcKeys;
542
543 //AccessGroupType
544 LoadAccessGroupTypesTable();
545
546 //Build Primary Key for AccessGroupType table
547 DataTable dtAGTypes = m_dsGlobal.Tables["AccessGroupType"];
548 DataColumn dcGTKey = dtAGTypes.Columns["ACCESS_GROUP_TYPEID"];
549 DataColumn[] dcGTKeys = new DataColumn[1];
550 dcGTKeys[0] = dcGTKey;
551 dtAGTypes.PrimaryKey = dcGTKeys;
552
553 //Build Data Relationship between AccessGroupType and AccessTypes tables
554 DataRelation dr = new DataRelation("AccessGroupType", //Relation Name
555 m_dsGlobal.Tables["AccessGroup"].Columns["BMXIEN"], //Parent
556 m_dsGlobal.Tables["AccessGroupType"].Columns["ACCESS_GROUP_ID"]); //Child
557 m_dsGlobal.Relations.Add(dr);
558
559 //ResourceGroup Table (Resource Groups by User)
560 LoadResourceGroupTable();
561
562 //Resources by user
563 LoadBSDXResourcesTable();
564
565 //Build Primary Key for Resources table
566 DataColumn[] dc = new DataColumn[1];
567 dc[0] = m_dsGlobal.Tables["Resources"].Columns["RESOURCEID"];
568 m_dsGlobal.Tables["Resources"].PrimaryKey = dc;
569
570 //GroupResources table
571 LoadGroupResourcesTable();
572
573 //Build Primary Key for ResourceGroup table
574 dc = new DataColumn[1];
575 dc[0] = m_dsGlobal.Tables["ResourceGroup"].Columns["RESOURCE_GROUP"];
576 m_dsGlobal.Tables["ResourceGroup"].PrimaryKey = dc;
577
578 //Build Data Relationships between ResourceGroup and GroupResources tables
579 dr = new DataRelation("GroupResource", //Relation Name
580 m_dsGlobal.Tables["ResourceGroup"].Columns["RESOURCE_GROUP"], //Parent
581 m_dsGlobal.Tables["GroupResources"].Columns["RESOURCE_GROUP"]); //Child
582 CGSchedLib.OutputArray(m_dsGlobal.Tables["GroupResources"], "GroupResources");
583 m_dsGlobal.Relations.Add(dr);
584
585 //HospitalLocation table
586 //cmd.CommandText = "SELECT BMXIEN 'HOSPITAL_LOCATION_ID', NAME 'HOSPITAL_LOCATION', DEFAULT_PROVIDER, STOP_CODE_NUMBER, INACTIVATE_DATE, REACTIVATE_DATE FROM HOSPITAL_LOCATION";
587 sCommandText = "BSDX HOSPITAL LOCATION";
588 ConnectInfo.RPMSDataTable(sCommandText, "HospitalLocation", m_dsGlobal);
589 Debug.Write("LoadGlobalRecordsets -- HospitalLocation loaded\n");
590
591 //Build Primary Key for HospitalLocation table
592 dc = new DataColumn[1];
593 DataTable dtTemp = m_dsGlobal.Tables["HospitalLocation"];
594 dc[0] = dtTemp.Columns["HOSPITAL_LOCATION_ID"];
595 m_dsGlobal.Tables["HospitalLocation"].PrimaryKey = dc;
596
597 //smh
598 //LoadClinicSetupTable();
599
600 //smh
601 //Build Primary Key for ClinicSetupParameters table
602 /*dc = new DataColumn[1];
603 dtTemp = m_dsGlobal.Tables["ClinicSetupParameters"];
604 dc[0] = dtTemp.Columns["HOSPITAL_LOCATION_ID"];
605 m_dsGlobal.Tables["ClinicSetupParameters"].PrimaryKey = dc;
606
607 //Build Data Relationships between ClinicSetupParameters and HospitalLocation tables
608 dr = new DataRelation("HospitalLocationClinic", //Relation Name
609 m_dsGlobal.Tables["HospitalLocation"].Columns["HOSPITAL_LOCATION_ID"], //Parent
610 m_dsGlobal.Tables["ClinicSetupParameters"].Columns["HOSPITAL_LOCATION_ID"], false); //Child
611 m_dsGlobal.Relations.Add(dr);*/
612 /*SMH
613 dtTemp.Columns.Add("PROVIDER", System.Type.GetType("System.String"), "Parent.DEFAULT_PROVIDER");
614 dtTemp.Columns.Add("CLINIC_STOP", System.Type.GetType("System.String"), "Parent.STOP_CODE_NUMBER");
615 dtTemp.Columns.Add("INACTIVATE_DATE", System.Type.GetType("System.String"), "Parent.INACTIVATE_DATE");
616 dtTemp.Columns.Add("REACTIVATE_DATE", System.Type.GetType("System.String"), "Parent.REACTIVATE_DATE");
617 */
618
619 //Build Data Relationships between Resources and HospitalLocation tables
620 dr = new DataRelation("HospitalLocationResource", //Relation Name
621 m_dsGlobal.Tables["HospitalLocation"].Columns["HOSPITAL_LOCATION_ID"], //Parent
622 m_dsGlobal.Tables["Resources"].Columns["HOSPITAL_LOCATION_ID"], false); //Child
623 m_dsGlobal.Relations.Add(dr);
624
625 //Build ScheduleUser table
626 this.LoadScheduleUserTable();
627
628 //Build Primary Key for ScheduleUser table
629 dc = new DataColumn[1];
630 dtTemp = m_dsGlobal.Tables["ScheduleUser"];
631 dc[0] = dtTemp.Columns["USERID"];
632 m_dsGlobal.Tables["ScheduleUser"].PrimaryKey = dc;
633
634 //Build ResourceUser table
635 this.LoadResourceUserTable();
636
637 //Build Primary Key for ResourceUser table
638 dc = new DataColumn[1];
639 dtTemp = m_dsGlobal.Tables["ResourceUser"];
640 dc[0] = dtTemp.Columns["RESOURCEUSER_ID"];
641 m_dsGlobal.Tables["ResourceUser"].PrimaryKey = dc;
642
643 //Create relation between BSDX Resource and BSDX Resource User tables
644 dr = new DataRelation("ResourceUser", //Relation Name
645 m_dsGlobal.Tables["Resources"].Columns["RESOURCEID"], //Parent
646 m_dsGlobal.Tables["ResourceUser"].Columns["RESOURCEID"]); //Child
647 m_dsGlobal.Relations.Add(dr);
648
649 //Build active provider table
650 sCommandText = "SELECT BMXIEN, NAME FROM NEW_PERSON WHERE INACTIVE_DATE = ''";
651 ConnectInfo.RPMSDataTable(sCommandText, "Provider", m_dsGlobal);
652 Debug.Write("LoadGlobalRecordsets -- Provider loaded\n");
653
654 //Build the CLINIC_STOP table
655 // sCommandText = "SELECT BMXIEN, CODE, NAME FROM CLINIC_STOP"; //SMH
656 sCommandText = "SELECT BMXIEN, AMIS_REPORTING_STOP_CODE, NAME FROM CLINIC_STOP";
657 ConnectInfo.RPMSDataTable(sCommandText, "ClinicStop", m_dsGlobal);
658 Debug.Write("LoadGlobalRecordsets -- ClinicStop loaded\n");
659
660 //Build the HOLIDAY table
661 sCommandText = "SELECT NAME, DATE FROM HOLIDAY WHERE DATE > '" + DateTime.Today.ToShortDateString() + "'";
662 ConnectInfo.RPMSDataTable(sCommandText, "HOLIDAY", m_dsGlobal);
663 Debug.Write("LoadingGlobalRecordsets -- Holidays loaded\n");
664
665
666 //Save the xml schema
667 //m_dsGlobal.WriteXmlSchema(@"..\..\csSchema20060526.xsd");
668
669 return true;
670 }
671
672 public void RegisterDocumentView(CGDocument doc, CGView view)
673 {
674 //Store the view in the list of views
675 this.Views.Add(view, doc);
676
677 //Hook into the view's 'closed' event
678 view.Closed += new EventHandler(ViewClosed);
679
680 //Hook into the view's mnuRPMSServer.Click event
681 view.mnuRPMSServer.Click += new EventHandler(mnuRPMSServer_Click);
682
683 //Hook into the view's mnuRPMSLogin.Click event
684 view.mnuRPMSLogin.Click += new EventHandler(mnuRPMSLogin_Click);
685
686 }
687
688 public void RegisterAVDocumentView(CGAVDocument doc, CGAVView view)
689 {
690 //Store the view in the list of views
691 this.AvailabilityViews.Add(view, doc);
692
693 //Hook into the view's 'closed' event
694 view.Closed += new EventHandler(AVViewClosed);
695 }
696
697 public CGAVView GetAVViewByResource(ArrayList sResourceArray)
698 {
699 if (sResourceArray == null)
700 return null;
701
702 bool bEqual = true;
703 foreach (CGAVView v in m_AVViews.Keys)
704 {
705 CGAVDocument d = v.Document;
706
707 bEqual = false;
708 if (d.Resources.Count == sResourceArray.Count)
709 {
710 bEqual = true;
711 for (int j = 0; j < sResourceArray.Count; j++)
712 {
713 if (sResourceArray.Contains(d.Resources[j]) == false)
714 {
715 bEqual = false;
716 break;
717 }
718 if (d.Resources.Contains(sResourceArray[j]) == false)
719 {
720 bEqual = false;
721 break;
722 }
723 }
724 if (bEqual == true)
725 return v;
726 }
727 }
728 return null;
729 }
730 /// <summary>
731 /// Return the first view having a resource array matching sResourceArray
732 /// </summary>
733 /// <param name="sResourceArray"></param>
734 /// <returns></returns>
735 public CGView GetViewByResource(ArrayList sResourceArray)
736 {
737 if (sResourceArray == null)
738 return null;
739
740 bool bEqual = true;
741 foreach (CGView v in _views.Keys)
742 {
743 CGDocument d = v.Document;
744
745 bEqual = false;
746 if (d.Resources.Count == sResourceArray.Count)
747 {
748 bEqual = true;
749 for (int j = 0; j < sResourceArray.Count; j++)
750 {
751 if (sResourceArray.Contains(d.Resources[j]) == false)
752 {
753 bEqual = false;
754 break;
755 }
756 if (d.Resources.Contains(sResourceArray[j]) == false)
757 {
758 bEqual = false;
759 break;
760 }
761 }
762 if (bEqual == true)
763 return v;
764 }
765 }
766 return null;
767 }
768
769 private void ViewClosed(object sender, EventArgs e)
770 {
771 //Remove the sender from our document list
772 Views.Remove(sender);
773
774 //If no documents left, then close RPMS connection & exit the application
775 if ((Views.Count == 0)&&(this.AvailabilityViews.Count == 0)&&(m_bExitOK == true))
776 {
777 m_ConnectInfo.EventPollingEnabled = false;
778 m_ConnectInfo.UnSubscribeEvent("BSDX SCHEDULE");
779 m_ConnectInfo.CloseConnection();
780 Application.Exit();
781 }
782 }
783
784 private void AVViewClosed(object sender, EventArgs e)
785 {
786 //Remove the sender from our document list
787 this.AvailabilityViews.Remove(sender);
788
789 //If no documents left, then close RPMS connection & exit the application
790 if ((Views.Count == 0)&&(this.AvailabilityViews.Count == 0)&&(m_bExitOK == true))
791 {
792 m_ConnectInfo.bmxNetLib.CloseConnection();
793 Application.Exit();
794 }
795 }
796
797 private void KeepAlive()
798 {
799 foreach (CGView v in _views.Keys)
800 {
801 CGDocument d = v.Document;
802 DateTime dNow = DateTime.Now;
803 DateTime dLast = d.LastRefreshed;
804 TimeSpan tsDiff = dNow - dLast;
805 if (tsDiff.Seconds > 180)
806 {
807 for (int j = 0; j < d.Resources.Count; j++)
808 {
809 v.RaiseRPMSEvent("SCHEDULE-" + d.Resources[j].ToString(), "");
810 }
811
812 break;
813 }
814 }
815 }
816
817 /// <summary>
818 /// Propogate availability updates to all sRresource's doc/views
819 /// </summary>
820 public void UpdateViews(string sResource, string sOldResource)
821 {
822 if (sResource == null)
823 return;
824 foreach (CGView v in _views.Keys)
825 {
826 CGDocument d = v.Document;
827 for (int j = 0; j < d.Resources.Count; j++)
828 {
829 if ((sResource == "") || (sResource == ((string) d.Resources[j])) || (sOldResource == ((string) d.Resources[j])))
830 {
831 d.RefreshDocument();
832 break;
833 }
834 }
835 v.UpdateTree();
836 }
837 }
838
839 /// <summary>
840 /// Propogate availability updates to all doc/views
841 /// </summary>
842 public void UpdateViews()
843 {
844 UpdateViews("","");
845 foreach (CGView v in _views.Keys)
846 {
847 v.UpdateTree();
848 }
849 }
850
851 /// <summary>
852 /// Calls each view associated with document Doc and closes it.
853 /// </summary>
854 public void CloseAllViews(CGDocument doc)
855 {
856 //iterate through all views and call update.
857 Hashtable h = CGDocumentManager.Current.Views;
858
859 CGDocument d;
860 int nTempCount = h.Count;
861 do
862 {
863 nTempCount = h.Count;
864 foreach (CGView v in h.Keys)
865 {
866 d = (CGDocument) h[v];
867 if (d == doc)
868 {
869 v.Close();
870 break;
871 }
872 }
873 } while ((h.Count > 0) && (nTempCount != h.Count));
874 }
875
876 /// <summary>
877 /// Calls each view associated with Availability Doc and closes it.
878 /// </summary>
879 public void CloseAllViews(CGAVDocument doc)
880 {
881 //iterate through all views and call update.
882 Hashtable h = CGDocumentManager.Current.AvailabilityViews;
883
884 CGAVDocument d;
885 int nTempCount = h.Count;
886 do
887 {
888 nTempCount = h.Count;
889 foreach (CGAVView v in h.Keys)
890 {
891 d = (CGAVDocument) h[v];
892 if (d == doc)
893 {
894 v.Close();
895 break;
896 }
897 }
898 } while ((h.Count > 0) && (nTempCount != h.Count));
899
900
901 }
902
903 private void mnuRPMSServer_Click(object sender, EventArgs e)
904 {
905 //Warn that changing servers will close all schedules
906 if (MessageBox.Show("Are you sure you want to close all schedules and connect to a different VistA server?", "Clinical Scheduling", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK)
907 return;
908
909 //Reconnect to RPMS and recreate all global recordsets
910 try
911 {
912 m_bExitOK = false;
913 bool bRetry = true;
914 BMXNetConnectInfo tmpInfo;
915 do
916 {
917 tmpInfo = m_ConnectInfo;
918 try
919 {
920 tmpInfo.ChangeServerInfo();
921 bRetry = false;
922 }
923 catch (Exception ex)
924 {
925 if (ex.Message == "User cancelled.")
926 {
927 bRetry = false;
928 return;
929 }
930 if (MessageBox.Show("Unable to connect to VistA. " + ex.Message , "Clinical Scheduling", MessageBoxButtons.RetryCancel) == DialogResult.Retry)
931 {
932 bRetry = true;
933 }
934 else
935 {
936 bRetry = false;
937 return;
938 }
939 }
940 } while (bRetry == true);
941
942 CloseAll();
943 m_bExitOK = true;
944 m_ConnectInfo = tmpInfo;
945
946 this.InitializeApp();
947
948 //Create a new document
949 CGDocument doc = new CGDocument();
950 doc.DocManager = _current;
951 doc.OnNewDocument();
952
953 }
954 catch (Exception ex)
955 {
956 throw ex;
957 }
958
959 }
960
961 private void mnuRPMSLogin_Click(object sender, EventArgs e)
962 {
963 //Warn that changing login will close all schedules
964 if (MessageBox.Show("Are you sure you want to close all schedules and login to VistA?", "Clinical Scheduling", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK)
965 return;
966
967 //Reconnect to RPMS and recreate all global recordsets
968 try
969 {
970 m_bExitOK = false;
971 CloseAll();
972 m_bExitOK = true;
973 _current.m_ConnectInfo = new BMXNet.BMXNetConnectInfo();
974 this.InitializeApp(true);
975 //Create a new document
976 CGDocument doc = new CGDocument();
977 doc.DocManager = _current;
978 doc.OnNewDocument();
979 }
980 catch (Exception ex)
981 {
982 throw ex;
983 }
984
985 }
986
987 delegate void CloseAllDelegate(string sMsg);
988
989 private void CloseAll(string sMsg)
990 {
991 if (sMsg == "")
992 {
993 sMsg = "Scheduling System Shutting Down Immediately for Maintenance.";
994 }
995
996 MessageBox.Show(sMsg, "Clinical Scheduling Administrator -- System Shutdown Notification", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
997
998 CloseAll();
999 }
1000
1001 private void CloseAll()
1002 {
1003 //Close all documents, views and connections
1004 Hashtable h = CGDocumentManager.Current.Views;
1005 int nTempCount = h.Count;
1006 do
1007 {
1008 nTempCount = h.Count;
1009 foreach (CGView v in h.Keys)
1010 {
1011 v.Close();
1012 break;
1013 }
1014 } while ((h.Count > 0) && (nTempCount != h.Count));
1015
1016 h = CGDocumentManager.Current.AvailabilityViews;
1017 nTempCount = h.Count;
1018 do
1019 {
1020 nTempCount = h.Count;
1021 foreach (CGAVView v in h.Keys)
1022 {
1023 v.Close();
1024 break;
1025 }
1026 } while ((h.Count > 0) && (nTempCount != h.Count));
1027
1028 }
1029
1030 delegate DataTable RPMSDataTableDelegate(string CommandString, string TableName);
1031
1032 public DataTable RPMSDataTable(string sSQL, string sTableName)
1033 {
1034 //Retrieves a recordset from RPMS
1035 string sErrorMessage = "";
1036 try
1037 {
1038 System.IntPtr pHandle = this.Handle;
1039 DataTable dtOut;
1040 RPMSDataTableDelegate rdtd = new RPMSDataTableDelegate(ConnectInfo.RPMSDataTable);
1041 dtOut = (DataTable) this.Invoke(rdtd, new object[] {sSQL, sTableName});
1042 return dtOut;
1043 }
1044 catch (Exception ex)
1045 {
1046 sErrorMessage = "CGDocumentManager.RPMSDataTable error: " + ex.Message;
1047 throw ex;
1048 }
1049 }
1050
1051 public void ChangeDivision(System.Windows.Forms.Form frmCaller)
1052 {
1053 this.ConnectInfo.ChangeDivision(frmCaller);
1054 foreach (CGView v in _views.Keys)
1055 {
1056 v.InitializeDocView(v.Document.DocName);
1057 v.Document.RefreshDocument();
1058 }
1059 }
1060
1061 public void ViewRefresh()
1062 {
1063 foreach (CGView v in _views.Keys)
1064 {
1065 try
1066 {
1067 v.Document.RefreshDocument();
1068 }
1069 catch (Exception ex)
1070 {
1071 Debug.Write("CGDocumentManager.ViewRefresh Exception: " + ex.Message + "\n");
1072 }
1073 finally
1074 {
1075 }
1076 }
1077 Debug.Write("DocManager refreshed all views.\n");
1078 }
1079
1080 #endregion Methods & Events
1081
1082 }
1083}
Note: See TracBrowser for help on using the repository browser.