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

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

Support for different encodings besides ASCII.
Minor bug fixes dealing with internationalization of dates.

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