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

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

CGView: Added various shortcuts keys for menus; removed extra overbook prompt after booking if doing an overbook. You already get one before booking.
CGDocumentManager: Mickey mouse connection check to prevent prompting for access and verify if there's no connection to VISTA.
CGDocumentManager: Test SQL statement to retrieve Hospital Locations and default providers associated with them.
Remove garbage file {85FE etc}.rpt

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 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 try
265 {
266 if (bReLogin == true)
267 {
268 //Prompt for Access and Verify codes
269 _current.m_ConnectInfo.LoadConnectInfo("", "");
270 }
271 else
272 {
273 if (m_Server != String.Empty && m_Port != 0 && m_AccessCode != String.Empty
274 && m_VerifyCode != String.Empty)
275 {
276 m_ConnectInfo.LoadConnectInfo(m_Server, m_Port, m_AccessCode, m_VerifyCode);
277 }
278 else if (m_Server != String.Empty && m_Port != 0)
279 m_ConnectInfo.LoadConnectInfo(m_Server, m_Port, "", "");
280 else
281 m_ConnectInfo.LoadConnectInfo();
282 }
283 bRetry = false;
284 }
285 catch (System.Net.Sockets.SocketException)
286 {
287 MessageBox.Show("Cannot connect to VistA. ");
288 }
289 catch (Exception ex)
290 {
291 m_ds.Close();
292 if (MessageBox.Show("Unable to connect to VistA. " + ex.Message, "Clinical Scheduling", MessageBoxButtons.RetryCancel) == DialogResult.Retry)
293 {
294 bRetry = true;
295 _current.m_ConnectInfo.ChangeServerInfo();
296 }
297 else
298 {
299 bRetry = false;
300 throw ex;
301 }
302 }
303 }while (bRetry == true);
304
305 //Create global dataset
306 _current.m_dsGlobal = new DataSet("GlobalDataSet");
307
308 //Version info
309 m_ds.SetStatus("Getting Version Info...");
310 m_ds.Refresh();
311 String sCmd = "BMX VERSION INFO^BSDX^";
312 this.m_ConnectInfo.RPMSDataTable(sCmd, "VersionInfo", m_dsGlobal);
313
314 //Keep the following commented code for future use:
315 //How to extract the version numbers:
316 //DataTable dtVersion = m_dsGlobal.Tables["VersionInfo"];
317 //Debug.Assert(dtVersion.Rows.Count == 1);
318 //DataRow rVersion = dtVersion.Rows[0];
319 //string sMajor = rVersion["MAJOR_VERSION"].ToString();
320 //string sMinor = rVersion["MINOR_VERSION"].ToString();
321 //string sBuild = rVersion["BUILD"].ToString();
322 //decimal fBuild = Convert.ToDecimal(sBuild);
323
324 //Set application context
325 m_ds.SetStatus("Setting Application Context to BSDXRPC...");
326 m_ds.Refresh();
327 m_ConnectInfo.AppContext = "BSDXRPC";
328
329 //Load global recordsets
330 m_ds.SetStatus("Loading VistA data tables...");
331 m_ds.Refresh();
332 if (_current.LoadGlobalRecordsets() == false)
333 {
334 MessageBox.Show("Unable to create VistA recordsets"); //TODO Improve this message
335 m_ds.Close();
336 return;
337 }
338
339 System.IntPtr pHandle = this.Handle;
340 System.IntPtr pConnHandle = this.ConnectInfo.Handle;
341 this.m_sHandle = pHandle.ToString();
342
343 _current.m_ConnectInfo.ReceiveTimeout = 30000; //30-second timeout
344
345#if DEBUG
346 _current.m_ConnectInfo.ReceiveTimeout = 600000; //longer timeout for debugging
347#endif
348 _current.m_ConnectInfo.SubscribeEvent("BSDX SCHEDULE");
349 _current.m_ConnectInfo.SubscribeEvent("BSDX CALL WORKSTATIONS");
350 _current.m_ConnectInfo.SubscribeEvent("BSDX ADMIN MESSAGE");
351 _current.m_ConnectInfo.SubscribeEvent("BSDX ADMIN SHUTDOWN");
352
353 _current.m_ConnectInfo.EventPollingInterval = 5000; //in milliseconds
354 _current.m_ConnectInfo.EventPollingEnabled = true;
355 _current.m_ConnectInfo.AutoFire = 12; //AutoFire every 12*5 seconds
356
357 m_ds.Close();
358 }
359 catch (Exception ex)
360 {
361 m_ds.Close();
362 Debug.Write(ex.Message);
363 MessageBox.Show(ex.Message + ex.StackTrace, "Clinical Scheduling Error -- Closing Application");
364 throw ex;
365 }
366 }
367
368 //To write to the console
369 [DllImport("kernel32.dll")]
370 static extern bool AttachConsole(int dwProcessId);
371 private const int ATTACH_PARENT_PROCESS = -1;
372
373 [STAThread()]
374 static void Main(string[] args)
375 {
376#if DEBUG
377 // Print console messages to console if launched from console
378 AttachConsole(ATTACH_PARENT_PROCESS);
379#endif
380 try
381 {
382 //Store the current manager
383 _current = new CGDocumentManager();
384
385 //Get command line options; store in private variables
386 var opset = new OptionSet () {
387 { "s=", s => _current.m_Server = s },
388 { "p=", p => _current.m_Port = int.Parse(p) },
389 { "a=", a => _current.m_AccessCode = a },
390 { "v=", v => _current.m_VerifyCode = v }
391 };
392
393 opset.Parse(args);
394
395 try
396 {
397 _current.InitializeApp();
398 }
399 catch (Exception ex)
400 {
401 Debug.Write(ex.Message);
402 return;
403 }
404
405 //Create the first empty document
406 CGDocument doc = new CGDocument();
407 doc.DocManager = _current;
408 doc.OnNewDocument();
409 Application.DoEvents();
410
411 //Run the application
412 Application.Run();
413 }
414 catch (Exception ex)
415 {
416 Debug.Write(ex.Message);
417 MessageBox.Show(ex.Message + ex.StackTrace, "CGDocumentManager.Main(): Clinical Scheduling Error -- Closing Application");
418 return;
419 }
420 }
421
422 public void LoadAccessTypesTable()
423 {
424 string sCommandText = "SELECT * FROM BSDX_ACCESS_TYPE";
425 ConnectInfo.RPMSDataTable(sCommandText, "AccessTypes", m_dsGlobal);
426 Debug.Write("LoadGlobalRecordsets -- AccessTypes loaded\n");
427 }
428
429 public void LoadAccessGroupsTable()
430 {
431 string sCommandText = "SELECT * FROM BSDX_ACCESS_GROUP";
432 ConnectInfo.RPMSDataTable(sCommandText, "AccessGroup", m_dsGlobal);
433 Debug.Write("LoadGlobalRecordsets -- AccessGroups loaded\n");
434 }
435
436 public void LoadAccessGroupTypesTable()
437 {
438 string sCommandText = "BSDX GET ACCESS GROUP TYPES";
439 ConnectInfo.RPMSDataTable(sCommandText, "AccessGroupType", m_dsGlobal);
440 Debug.Write("LoadGlobalRecordsets -- AccessGroupTypes loaded\n");
441 }
442
443 //TODO:REMOVE THIS
444 public void LoadClinicSetupTable()
445 {
446 string sCommandText = "BSDX CLINIC SETUP";
447 ConnectInfo.RPMSDataTable(sCommandText, "ClinicSetupParameters", m_dsGlobal);
448 Debug.Write("LoadGlobalRecordsets -- ClinicSetupParameters loaded\n");
449 }
450
451 public void LoadBSDXResourcesTable()
452 {
453 string sCommandText = "BSDX RESOURCES^" + m_ConnectInfo.DUZ;
454 ConnectInfo.RPMSDataTable(sCommandText, "Resources", m_dsGlobal);
455 Debug.Write("LoadGlobalRecordsets -- Resources loaded\n");
456 }
457
458 public void LoadResourceGroupTable()
459 {
460 //ResourceGroup Table (Resource Groups by User)
461 //Table "ResourceGroup" contains all resource group names
462 //to which user has access
463 //Fields are: RESOURCE_GROUPID, RESOURCE_GROUP
464 string sCommandText = "BSDX RESOURCE GROUPS BY USER^" + m_ConnectInfo.DUZ;
465 ConnectInfo.RPMSDataTable(sCommandText, "ResourceGroup", m_dsGlobal);
466 Debug.Write("LoadGlobalRecordsets -- ResourceGroup loaded\n");
467 }
468
469 public void LoadGroupResourcesTable()
470 {
471 //Table "GroupResources" contains all active GROUP/RESOURCE combinations
472 //to which user has access based on entries in BSDX RESOURCE USER file
473 //If user has BSDXZMGR or XUPROGMODE keys, then ALL Group/Resource combinstions
474 //are returned.
475 //Fields are: RESOURCE_GROUPID, RESOURCE_GROUP, RESOURCE_GROUP_ITEMID, RESOURCE_NAME, RESOURCE_ID
476 string sCommandText = "BSDX GROUP RESOURCE^" + m_ConnectInfo.DUZ;
477 ConnectInfo.RPMSDataTable(sCommandText, "GroupResources", m_dsGlobal);
478 Debug.Write("LoadGlobalRecordsets -- GroupResources loaded\n");
479 }
480
481 public void LoadScheduleUserTable()
482 {
483 //Table "ScheduleUser" contains an entry for each user in File 200 (NEW PERSON)
484 //who possesses the BSDXZMENU security key.
485 string sCommandText = "BSDX SCHEDULE USER";
486 ConnectInfo.RPMSDataTable(sCommandText, "ScheduleUser", m_dsGlobal);
487 Debug.Write("LoadGlobalRecordsets -- ScheduleUser loaded\n");
488 }
489
490 public void LoadResourceUserTable()
491 {
492 //Table "ResourceUser" duplicates the BSDX RESOURCE USER File.
493 //NOTE: Column names are RESOURCEUSER_ID, RESOURCEID,
494 // OVERBOOK, MODIFY_SCHEDULE, USERID, USERID1
495 //string sCommandText = "SELECT BMXIEN RESOURCEUSER_ID, INTERNAL[RESOURCENAME] RESOURCEID, OVERBOOK, MODIFY_SCHEDULE, USERNAME USERID, INTERNAL[USERNAME] FROM BSDX_RESOURCE_USER";
496 LoadResourceUserTable(false);
497 }
498
499 public void LoadResourceUserTable(bool bAllUsers)
500 {
501 string sCommandText = "SELECT BMXIEN RESOURCEUSER_ID, RESOURCENAME, INTERNAL[RESOURCENAME] RESOURCEID, OVERBOOK, MODIFY_SCHEDULE, MODIFY_APPOINTMENTS, USERNAME, INTERNAL[USERNAME] USERID FROM BSDX_RESOURCE_USER";
502 ConnectInfo.RPMSDataTable(sCommandText, "ResourceUser", m_dsGlobal);
503 Debug.Write("LoadGlobalRecordsets -- ResourceUser loaded\n");
504 }
505
506 private bool LoadGlobalRecordsets()
507 {
508 //Schedule User Info
509 string sCommandText = "BSDX SCHEDULING USER INFO^" + m_ConnectInfo.DUZ;
510 DataTable dtUser = ConnectInfo.RPMSDataTable(sCommandText, "SchedulingUser", m_dsGlobal);
511
512 Debug.Assert(dtUser.Rows.Count == 1);
513 DataRow rUser = dtUser.Rows[0];
514 Object oUser = rUser["MANAGER"];
515 string sUser = oUser.ToString();
516 m_bSchedManager = (sUser == "YES")?true:false;
517
518 //AccessTypes
519 LoadAccessTypesTable();
520
521 //Build Primary Key for AccessTypes table
522 DataTable dtTypes = m_dsGlobal.Tables["AccessTypes"];
523 DataColumn dcKey = dtTypes.Columns["BMXIEN"];
524 DataColumn[] dcKeys = new DataColumn[1];
525 dcKeys[0] = dcKey;
526 dtTypes.PrimaryKey = dcKeys;
527
528 //AccessGroups
529 LoadAccessGroupsTable();
530
531 //Build Primary Key for AccessGroup table
532 DataTable dtGroups = m_dsGlobal.Tables["AccessGroup"];
533 dcKey = dtGroups.Columns["ACCESS_GROUP"];
534 dcKeys = new DataColumn[1];
535 dcKeys[0] = dcKey;
536 dtGroups.PrimaryKey = dcKeys;
537
538 //AccessGroupType
539 LoadAccessGroupTypesTable();
540
541 //Build Primary Key for AccessGroupType table
542 DataTable dtAGTypes = m_dsGlobal.Tables["AccessGroupType"];
543 DataColumn dcGTKey = dtAGTypes.Columns["ACCESS_GROUP_TYPEID"];
544 DataColumn[] dcGTKeys = new DataColumn[1];
545 dcGTKeys[0] = dcGTKey;
546 dtAGTypes.PrimaryKey = dcGTKeys;
547
548 //Build Data Relationship between AccessGroupType and AccessTypes tables
549 DataRelation dr = new DataRelation("AccessGroupType", //Relation Name
550 m_dsGlobal.Tables["AccessGroup"].Columns["BMXIEN"], //Parent
551 m_dsGlobal.Tables["AccessGroupType"].Columns["ACCESS_GROUP_ID"]); //Child
552 m_dsGlobal.Relations.Add(dr);
553
554 //ResourceGroup Table (Resource Groups by User)
555 LoadResourceGroupTable();
556
557 //Resources by user
558 LoadBSDXResourcesTable();
559
560 //Build Primary Key for Resources table
561 DataColumn[] dc = new DataColumn[1];
562 dc[0] = m_dsGlobal.Tables["Resources"].Columns["RESOURCEID"];
563 m_dsGlobal.Tables["Resources"].PrimaryKey = dc;
564
565 //GroupResources table
566 LoadGroupResourcesTable();
567
568 //Build Primary Key for ResourceGroup table
569 dc = new DataColumn[1];
570 dc[0] = m_dsGlobal.Tables["ResourceGroup"].Columns["RESOURCE_GROUP"];
571 m_dsGlobal.Tables["ResourceGroup"].PrimaryKey = dc;
572
573 //Build Data Relationships between ResourceGroup and GroupResources tables
574 dr = new DataRelation("GroupResource", //Relation Name
575 m_dsGlobal.Tables["ResourceGroup"].Columns["RESOURCE_GROUP"], //Parent
576 m_dsGlobal.Tables["GroupResources"].Columns["RESOURCE_GROUP"]); //Child
577 CGSchedLib.OutputArray(m_dsGlobal.Tables["GroupResources"], "GroupResources");
578 m_dsGlobal.Relations.Add(dr);
579
580 //HospitalLocation table
581 //cmd.CommandText = "SELECT BMXIEN 'HOSPITAL_LOCATION_ID', NAME 'HOSPITAL_LOCATION', DEFAULT_PROVIDER, STOP_CODE_NUMBER, INACTIVATE_DATE, REACTIVATE_DATE FROM HOSPITAL_LOCATION";
582 sCommandText = "BSDX HOSPITAL LOCATION";
583 ConnectInfo.RPMSDataTable(sCommandText, "HospitalLocation", m_dsGlobal);
584 Debug.Write("LoadGlobalRecordsets -- HospitalLocation loaded\n");
585
586 //Build Primary Key for HospitalLocation table
587 dc = new DataColumn[1];
588 DataTable dtTemp = m_dsGlobal.Tables["HospitalLocation"];
589 dc[0] = dtTemp.Columns["HOSPITAL_LOCATION_ID"];
590 m_dsGlobal.Tables["HospitalLocation"].PrimaryKey = dc;
591
592 LoadClinicSetupTable();
593
594 //Build Primary Key for ClinicSetupParameters table
595 dc = new DataColumn[1];
596 dtTemp = m_dsGlobal.Tables["ClinicSetupParameters"];
597 dc[0] = dtTemp.Columns["HOSPITAL_LOCATION_ID"];
598 m_dsGlobal.Tables["ClinicSetupParameters"].PrimaryKey = dc;
599
600 //Build Data Relationships between ClinicSetupParameters and HospitalLocation tables
601 dr = new DataRelation("HospitalLocationClinic", //Relation Name
602 m_dsGlobal.Tables["HospitalLocation"].Columns["HOSPITAL_LOCATION_ID"], //Parent
603 m_dsGlobal.Tables["ClinicSetupParameters"].Columns["HOSPITAL_LOCATION_ID"], false); //Child
604 m_dsGlobal.Relations.Add(dr);
605
606 dtTemp.Columns.Add("PROVIDER", System.Type.GetType("System.String"), "Parent.DEFAULT_PROVIDER");
607 dtTemp.Columns.Add("CLINIC_STOP", System.Type.GetType("System.String"), "Parent.STOP_CODE_NUMBER");
608 dtTemp.Columns.Add("INACTIVATE_DATE", System.Type.GetType("System.String"), "Parent.INACTIVATE_DATE");
609 dtTemp.Columns.Add("REACTIVATE_DATE", System.Type.GetType("System.String"), "Parent.REACTIVATE_DATE");
610
611 //Build Data Relationships between Resources and HospitalLocation tables
612 dr = new DataRelation("HospitalLocationResource", //Relation Name
613 m_dsGlobal.Tables["HospitalLocation"].Columns["HOSPITAL_LOCATION_ID"], //Parent
614 m_dsGlobal.Tables["Resources"].Columns["HOSPITAL_LOCATION_ID"], false); //Child
615 m_dsGlobal.Relations.Add(dr);
616
617 //Build ScheduleUser table
618 this.LoadScheduleUserTable();
619
620 //Build Primary Key for ScheduleUser table
621 dc = new DataColumn[1];
622 dtTemp = m_dsGlobal.Tables["ScheduleUser"];
623 dc[0] = dtTemp.Columns["USERID"];
624 m_dsGlobal.Tables["ScheduleUser"].PrimaryKey = dc;
625
626 //Build ResourceUser table
627 this.LoadResourceUserTable();
628
629 //Build Primary Key for ResourceUser table
630 dc = new DataColumn[1];
631 dtTemp = m_dsGlobal.Tables["ResourceUser"];
632 dc[0] = dtTemp.Columns["RESOURCEUSER_ID"];
633 m_dsGlobal.Tables["ResourceUser"].PrimaryKey = dc;
634
635 //Create relation between BSDX Resource and BSDX Resource User tables
636 dr = new DataRelation("ResourceUser", //Relation Name
637 m_dsGlobal.Tables["Resources"].Columns["RESOURCEID"], //Parent
638 m_dsGlobal.Tables["ResourceUser"].Columns["RESOURCEID"]); //Child
639 m_dsGlobal.Relations.Add(dr);
640
641 //Build active provider table
642 sCommandText = "SELECT BMXIEN, NAME FROM NEW_PERSON WHERE INACTIVE_DATE = ''";
643 ConnectInfo.RPMSDataTable(sCommandText, "Provider", m_dsGlobal);
644 Debug.Write("LoadGlobalRecordsets -- Provider loaded\n");
645
646 //Build the CLINIC_STOP table
647 // sCommandText = "SELECT BMXIEN, CODE, NAME FROM CLINIC_STOP"; //SMH
648 sCommandText = "SELECT BMXIEN, AMIS_REPORTING_STOP_CODE, NAME FROM CLINIC_STOP";
649 ConnectInfo.RPMSDataTable(sCommandText, "ClinicStop", m_dsGlobal);
650 Debug.Write("LoadGlobalRecordsets -- ClinicStop loaded\n");
651
652 //Build the HOLIDAY table
653 sCommandText = "SELECT NAME, DATE FROM HOLIDAY WHERE DATE > '" + DateTime.Today.ToShortDateString() + "'";
654 ConnectInfo.RPMSDataTable(sCommandText, "HOLIDAY", m_dsGlobal);
655 Debug.Write("LoadingGlobalRecordsets -- Holidays loaded\n");
656
657 sCommandText = @"SELECT HOSPITAL_LOCATION.BMXIEN 'BMXIEN', HOSPITAL_LOCATION.PROVIDER.PROVIDER 'PROVIDER', HOSPITAL_LOCATION.PROVIDER.DEFAULT_PROVIDER 'DEFAULT' FROM HOSPITAL_LOCATION";
658 ConnectInfo.RPMSDataTable(sCommandText, "ClinicProviders", m_dsGlobal);
659 Debug.Write("LoadingGlobalRecordsets -- ClinicProviders loaded\n");
660
661 //Save the xml schema
662 //m_dsGlobal.WriteXmlSchema(@"..\..\csSchema20060526.xsd");
663
664 return true;
665 }
666
667 public void RegisterDocumentView(CGDocument doc, CGView view)
668 {
669 //Store the view in the list of views
670 this.Views.Add(view, doc);
671
672 //Hook into the view's 'closed' event
673 view.Closed += new EventHandler(ViewClosed);
674
675 //Hook into the view's mnuRPMSServer.Click event
676 view.mnuRPMSServer.Click += new EventHandler(mnuRPMSServer_Click);
677
678 //Hook into the view's mnuRPMSLogin.Click event
679 view.mnuRPMSLogin.Click += new EventHandler(mnuRPMSLogin_Click);
680
681 }
682
683 public void RegisterAVDocumentView(CGAVDocument doc, CGAVView view)
684 {
685 //Store the view in the list of views
686 this.AvailabilityViews.Add(view, doc);
687
688 //Hook into the view's 'closed' event
689 view.Closed += new EventHandler(AVViewClosed);
690 }
691
692 public CGAVView GetAVViewByResource(ArrayList sResourceArray)
693 {
694 if (sResourceArray == null)
695 return null;
696
697 bool bEqual = true;
698 foreach (CGAVView v in m_AVViews.Keys)
699 {
700 CGAVDocument d = v.Document;
701
702 bEqual = false;
703 if (d.Resources.Count == sResourceArray.Count)
704 {
705 bEqual = true;
706 for (int j = 0; j < sResourceArray.Count; j++)
707 {
708 if (sResourceArray.Contains(d.Resources[j]) == false)
709 {
710 bEqual = false;
711 break;
712 }
713 if (d.Resources.Contains(sResourceArray[j]) == false)
714 {
715 bEqual = false;
716 break;
717 }
718 }
719 if (bEqual == true)
720 return v;
721 }
722 }
723 return null;
724 }
725 /// <summary>
726 /// Return the first view having a resource array matching sResourceArray
727 /// </summary>
728 /// <param name="sResourceArray"></param>
729 /// <returns></returns>
730 public CGView GetViewByResource(ArrayList sResourceArray)
731 {
732 if (sResourceArray == null)
733 return null;
734
735 bool bEqual = true;
736 foreach (CGView v in _views.Keys)
737 {
738 CGDocument d = v.Document;
739
740 bEqual = false;
741 if (d.Resources.Count == sResourceArray.Count)
742 {
743 bEqual = true;
744 for (int j = 0; j < sResourceArray.Count; j++)
745 {
746 if (sResourceArray.Contains(d.Resources[j]) == false)
747 {
748 bEqual = false;
749 break;
750 }
751 if (d.Resources.Contains(sResourceArray[j]) == false)
752 {
753 bEqual = false;
754 break;
755 }
756 }
757 if (bEqual == true)
758 return v;
759 }
760 }
761 return null;
762 }
763
764 private void ViewClosed(object sender, EventArgs e)
765 {
766 //Remove the sender from our document list
767 Views.Remove(sender);
768
769 //If no documents left, then close RPMS connection & exit the application
770 if ((Views.Count == 0)&&(this.AvailabilityViews.Count == 0)&&(m_bExitOK == true))
771 {
772 m_ConnectInfo.EventPollingEnabled = false;
773 m_ConnectInfo.UnSubscribeEvent("BSDX SCHEDULE");
774 m_ConnectInfo.CloseConnection();
775 Application.Exit();
776 }
777 }
778
779 private void AVViewClosed(object sender, EventArgs e)
780 {
781 //Remove the sender from our document list
782 this.AvailabilityViews.Remove(sender);
783
784 //If no documents left, then close RPMS connection & exit the application
785 if ((Views.Count == 0)&&(this.AvailabilityViews.Count == 0)&&(m_bExitOK == true))
786 {
787 m_ConnectInfo.bmxNetLib.CloseConnection();
788 Application.Exit();
789 }
790 }
791
792 private void KeepAlive()
793 {
794 foreach (CGView v in _views.Keys)
795 {
796 CGDocument d = v.Document;
797 DateTime dNow = DateTime.Now;
798 DateTime dLast = d.LastRefreshed;
799 TimeSpan tsDiff = dNow - dLast;
800 if (tsDiff.Seconds > 180)
801 {
802 for (int j = 0; j < d.Resources.Count; j++)
803 {
804 v.RaiseRPMSEvent("SCHEDULE-" + d.Resources[j].ToString(), "");
805 }
806
807 break;
808 }
809 }
810 }
811
812 /// <summary>
813 /// Propogate availability updates to all sRresource's doc/views
814 /// </summary>
815 public void UpdateViews(string sResource, string sOldResource)
816 {
817 if (sResource == null)
818 return;
819 foreach (CGView v in _views.Keys)
820 {
821 CGDocument d = v.Document;
822 for (int j = 0; j < d.Resources.Count; j++)
823 {
824 if ((sResource == "") || (sResource == ((string) d.Resources[j])) || (sOldResource == ((string) d.Resources[j])))
825 {
826 d.RefreshDocument();
827 break;
828 }
829 }
830 v.UpdateTree();
831 }
832 }
833
834 /// <summary>
835 /// Propogate availability updates to all doc/views
836 /// </summary>
837 public void UpdateViews()
838 {
839 UpdateViews("","");
840 foreach (CGView v in _views.Keys)
841 {
842 v.UpdateTree();
843 }
844 }
845
846 /// <summary>
847 /// Calls each view associated with document Doc and closes it.
848 /// </summary>
849 public void CloseAllViews(CGDocument doc)
850 {
851 //iterate through all views and call update.
852 Hashtable h = CGDocumentManager.Current.Views;
853
854 CGDocument d;
855 int nTempCount = h.Count;
856 do
857 {
858 nTempCount = h.Count;
859 foreach (CGView v in h.Keys)
860 {
861 d = (CGDocument) h[v];
862 if (d == doc)
863 {
864 v.Close();
865 break;
866 }
867 }
868 } while ((h.Count > 0) && (nTempCount != h.Count));
869 }
870
871 /// <summary>
872 /// Calls each view associated with Availability Doc and closes it.
873 /// </summary>
874 public void CloseAllViews(CGAVDocument doc)
875 {
876 //iterate through all views and call update.
877 Hashtable h = CGDocumentManager.Current.AvailabilityViews;
878
879 CGAVDocument d;
880 int nTempCount = h.Count;
881 do
882 {
883 nTempCount = h.Count;
884 foreach (CGAVView v in h.Keys)
885 {
886 d = (CGAVDocument) h[v];
887 if (d == doc)
888 {
889 v.Close();
890 break;
891 }
892 }
893 } while ((h.Count > 0) && (nTempCount != h.Count));
894
895
896 }
897
898 private void mnuRPMSServer_Click(object sender, EventArgs e)
899 {
900 //Warn that changing servers will close all schedules
901 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)
902 return;
903
904 //Reconnect to RPMS and recreate all global recordsets
905 try
906 {
907 m_bExitOK = false;
908 bool bRetry = true;
909 BMXNetConnectInfo tmpInfo;
910 do
911 {
912 tmpInfo = m_ConnectInfo;
913 try
914 {
915 tmpInfo.ChangeServerInfo();
916 bRetry = false;
917 }
918 catch (Exception ex)
919 {
920 if (ex.Message == "User cancelled.")
921 {
922 bRetry = false;
923 return;
924 }
925 if (MessageBox.Show("Unable to connect to VistA. " + ex.Message , "Clinical Scheduling", MessageBoxButtons.RetryCancel) == DialogResult.Retry)
926 {
927 bRetry = true;
928 }
929 else
930 {
931 bRetry = false;
932 return;
933 }
934 }
935 } while (bRetry == true);
936
937 CloseAll();
938 m_bExitOK = true;
939 m_ConnectInfo = tmpInfo;
940
941 this.InitializeApp();
942
943 //Create a new document
944 CGDocument doc = new CGDocument();
945 doc.DocManager = _current;
946 doc.OnNewDocument();
947
948 }
949 catch (Exception ex)
950 {
951 throw ex;
952 }
953
954 }
955
956 private void mnuRPMSLogin_Click(object sender, EventArgs e)
957 {
958 //Warn that changing login will close all schedules
959 if (MessageBox.Show("Are you sure you want to close all schedules and login to VistA?", "Clinical Scheduling", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK)
960 return;
961
962 //Reconnect to RPMS and recreate all global recordsets
963 try
964 {
965 m_bExitOK = false;
966 CloseAll();
967 m_bExitOK = true;
968 _current.m_ConnectInfo = new BMXNet.BMXNetConnectInfo();
969 this.InitializeApp(true);
970 //Create a new document
971 CGDocument doc = new CGDocument();
972 doc.DocManager = _current;
973 doc.OnNewDocument();
974 }
975 catch (Exception ex)
976 {
977 throw ex;
978 }
979
980 }
981
982 delegate void CloseAllDelegate(string sMsg);
983
984 private void CloseAll(string sMsg)
985 {
986 if (sMsg == "")
987 {
988 sMsg = "Scheduling System Shutting Down Immediately for Maintenance.";
989 }
990
991 MessageBox.Show(sMsg, "Clinical Scheduling Administrator -- System Shutdown Notification", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
992
993 CloseAll();
994 }
995
996 private void CloseAll()
997 {
998 //Close all documents, views and connections
999 Hashtable h = CGDocumentManager.Current.Views;
1000 int nTempCount = h.Count;
1001 do
1002 {
1003 nTempCount = h.Count;
1004 foreach (CGView v in h.Keys)
1005 {
1006 v.Close();
1007 break;
1008 }
1009 } while ((h.Count > 0) && (nTempCount != h.Count));
1010
1011 h = CGDocumentManager.Current.AvailabilityViews;
1012 nTempCount = h.Count;
1013 do
1014 {
1015 nTempCount = h.Count;
1016 foreach (CGAVView v in h.Keys)
1017 {
1018 v.Close();
1019 break;
1020 }
1021 } while ((h.Count > 0) && (nTempCount != h.Count));
1022
1023 }
1024
1025 delegate DataTable RPMSDataTableDelegate(string CommandString, string TableName);
1026
1027 public DataTable RPMSDataTable(string sSQL, string sTableName)
1028 {
1029 //Retrieves a recordset from RPMS
1030 string sErrorMessage = "";
1031 try
1032 {
1033 System.IntPtr pHandle = this.Handle;
1034 DataTable dtOut;
1035 RPMSDataTableDelegate rdtd = new RPMSDataTableDelegate(ConnectInfo.RPMSDataTable);
1036 dtOut = (DataTable) this.Invoke(rdtd, new object[] {sSQL, sTableName});
1037 return dtOut;
1038 }
1039 catch (Exception ex)
1040 {
1041 sErrorMessage = "CGDocumentManager.RPMSDataTable error: " + ex.Message;
1042 throw ex;
1043 }
1044 }
1045
1046 public void ChangeDivision(System.Windows.Forms.Form frmCaller)
1047 {
1048 this.ConnectInfo.ChangeDivision(frmCaller);
1049 foreach (CGView v in _views.Keys)
1050 {
1051 v.InitializeDocView(v.Document.DocName);
1052 v.Document.RefreshDocument();
1053 }
1054 }
1055
1056 public void ViewRefresh()
1057 {
1058 foreach (CGView v in _views.Keys)
1059 {
1060 try
1061 {
1062 v.Document.RefreshDocument();
1063 }
1064 catch (Exception ex)
1065 {
1066 Debug.Write("CGDocumentManager.ViewRefresh Exception: " + ex.Message + "\n");
1067 }
1068 finally
1069 {
1070 }
1071 }
1072 Debug.Write("DocManager refreshed all views.\n");
1073 }
1074
1075 #endregion Methods & Events
1076
1077 }
1078}
Note: See TracBrowser for help on using the repository browser.