source: BMXNET_RPMS_dotNET_UTILITIES-BMX/branch/IHS BMX Framework/IndianHealthService.BMXNet.WinForm/WinFramework.cs@ 1146

Last change on this file since 1146 was 1146, checked in by Sam Habiel, 13 years ago

Initial Import of BMX4

File size: 25.7 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Text;
4using IndianHealthService.BMXNet.Model;
5using IndianHealthService.BMXNet.WinForm.Model;
6using IndianHealthService.BMXNet.WinForm.Services;
7using IndianHealthService.BMXNet.WinForm.Configuration;
8using IndianHealthService.BMXNet.Net;
9using System.IO;
10using System.IO.IsolatedStorage;
11using System.Runtime.Serialization;
12using System.Runtime.Serialization.Formatters.Soap;
13using System.Reflection;
14using System.Security.Policy;
15using System.Xml;
16using System.Data;
17using System.Globalization;
18using System.Windows.Forms;
19using IndianHealthService.BMXNet.Forms;
20using IndianHealthService.BMXNet.Ado;
21using System.Threading;
22using IndianHealthService.BMXNet.Services;
23
24namespace IndianHealthService.BMXNet.WinForm
25{
26 /// <summary>
27 /// Instance manages the context/access to RPMS
28 /// - Configuration information
29 /// - Login entry points
30 /// - External changes to patient context
31 /// </summary>
32 ///
33 public class WinFramework : Log
34 {
35 private Log _log = new NullLog();
36
37 /// <summary>
38 /// Logger to be used by all BMX objects.
39 /// </summary>
40 public Log Log
41 {
42 get { return _log; }
43 set { _log = value; }
44 }
45
46 public static WinFramework EasyLogin(IWin32Window aUiOwnerForPositioningDialog, params string[] configKeys)
47 {
48 WinFramework easyFramework = CreateWithNetworkBroker(true, new NullLog());
49 easyFramework.LoadConnectionSpecs(LocalPersistentStore.CreateDefaultStorage(true), configKeys);
50
51 LoginProcess login = easyFramework.CreateLoginProcess();
52
53 if (login.HasDefaultConnectionWithUseWindowsAuth && login.AttemptWindowsAuthLogin())
54 {
55 login.AttemptWindowsAuthLogin();
56 }
57
58 if (!login.WasLoginAttempted || !login.WasSuccessful)
59 {
60 login.AttemptUserInputLogin("RPMS Login", 3, true, aUiOwnerForPositioningDialog);
61 }
62 easyFramework.Login = login;
63
64 return easyFramework;
65 }
66
67
68 public RemoteSessionPool RemoteSessionPool
69 {
70 get { return this.Broker.RemoteSessionPool; }
71 }
72
73
74 public static WinFramework CreateWithNetworkBroker()
75 {
76 return WinFramework.CreateWithNetworkBroker(false, new NullLog());
77 }
78
79 public static WinFramework CreateWithNetworkBroker(bool parseCommandLineArguments)
80 {
81 return WinFramework.CreateWithNetworkBroker(parseCommandLineArguments, new NullLog());
82 }
83
84 public static WinFramework CreateWithNetworkBroker(bool parseCommandLineArguments, Log aLogger)
85 {
86 WinFramework framework = new WinFramework();
87 framework.Log = aLogger;
88
89 framework.HardCodedSettings = new Settings();
90
91 if (parseCommandLineArguments)
92 {
93 Settings commandLineSettings = new CommandLineArguments().ParseSlashKeyValue(Environment.GetCommandLineArgs(), true);
94 commandLineSettings.BackupSettings = framework.HardCodedSettings;
95 framework.BootStrapSettings = commandLineSettings;
96 }
97 else
98 {
99 framework.BootStrapSettings = framework.HardCodedSettings;
100 }
101
102 return framework;
103 }
104
105 /// <summary>
106 /// Ping the server, will reset read-timeout
107 /// </summary>
108 /// <returns></returns>
109 public double ImHereServer()
110 {
111 return this.SocketBroker.ImHereServer();
112 }
113
114 private Settings _hardCodedSettings = null;
115
116 public Settings HardCodedSettings
117 {
118 get { return _hardCodedSettings; }
119 set { _hardCodedSettings = value; }
120 }
121
122 private Settings _bootStrapSettings = new Settings();
123
124 public Settings BootStrapSettings
125 {
126 get { return _bootStrapSettings; }
127 set { _bootStrapSettings = value; }
128 }
129
130 public Settings Settengs
131 {
132 get { return this.BootStrapSettings; }
133 }
134
135 private RpmsConnectionSettings _connectionSettings = null;
136
137 public RpmsConnectionSettings ConnectionSettings
138 {
139 get { return _connectionSettings; }
140 set { _connectionSettings = value; }
141 }
142
143
144 private BMXNetBroker _socketBroker = null;
145
146 internal BMXNetBroker SocketBroker
147 {
148 get
149 {
150 if (_socketBroker == null)
151 {
152 if (this.BootStrapSettings.Get("UseBMXNetSocketBroker", true))
153 {
154 this.SocketBroker = BMXNetBroker.CreateSocketBroker();
155 this.SocketBroker.Log = (Log)this;
156 }
157 }
158 return _socketBroker;
159 }
160 set { _socketBroker = value; }
161 }
162
163
164 private BMXNetBroker _broker = null;
165
166 internal BMXNetBroker Broker
167 {
168 get
169 {
170 if (_broker == null)
171 {
172 return this.SocketBroker;
173 }
174
175 return _broker;
176 }
177 set { _broker = value; }
178 }
179
180
181 private LoginProcess _login = null;
182
183 public LoginProcess Login
184 {
185 get { return _login; }
186 set
187 {
188 if (this.Login != null)
189 {
190 this.Close();
191 }
192
193 _login = value;
194
195 if (this.Login != null)
196 {
197 if (this.Login.WasSuccessful)
198 {
199 this.Start(this.Broker.PrimaryRemoteSession);
200 }
201
202 }
203 }
204 }
205
206
207 private RemoteSession _primaryRemoteSession = null;
208
209 public RemoteSession PrimaryRemoteSession
210 {
211 get { return _primaryRemoteSession; }
212 set { _primaryRemoteSession = value; }
213 }
214
215
216
217
218 public LocalSession LocalSession
219 {
220 get { return (LocalSession)this.FrameworkSession; }
221 }
222
223 private WinSession _brokerSession = null;
224
225 internal WinSession FrameworkSession
226 {
227 get { return _brokerSession; }
228 set { _brokerSession = value; }
229 }
230
231 private List<WinSession> _sessions = new List<WinSession>();
232
233 internal List<WinSession> Sessions
234 {
235 get { return _sessions; }
236 set { _sessions = value; }
237 }
238
239 public static WinFramework OpenOn(RemoteSession aSession)
240 {
241 WinFramework framework = new WinFramework();
242
243 framework.Start(aSession);
244
245 return framework;
246 }
247
248 public void TriggerLocalEvent(String anEvent, String eventInfo)
249 {
250 this.FrameworkSession.TriggerEvent(anEvent, eventInfo);
251 }
252
253 internal void Start(RemoteSession aSession)
254 {
255 this.PrimaryRemoteSession = aSession;
256
257 WinUser user = new WinUser();
258 user.RemoteSession= this.PrimaryRemoteSession;
259 user.Name = ((BMXNetRemoteSession)aSession).AuthenicatedUserName;
260 user.Ien = ((BMXNetRemoteSession)aSession).AuthenicatedDuz;
261
262 this._user = user;
263 this.Broker.User = user;
264
265 WinSession session = new WinSession();
266 session.Framework = this;
267
268 WinContext context = new WinContext();
269 context.User = user;
270
271 session.Open(this, context);
272
273 this.Sessions.Add(session);
274 this.FrameworkSession = session;
275
276 context.ChangePatient(this.FrameworkSession.Context.Patient);
277 context.ChangeVisit(this.FrameworkSession.Context.Visit);
278 }
279
280 private EventRegistry _eventRegistry = new EventRegistry();
281
282 internal EventRegistry EventRegistry
283 {
284 get { return _eventRegistry; }
285 set { _eventRegistry = value; }
286 }
287
288 public bool ChangePatient(Patient aPatient, bool force)
289 {
290 bool canChange = true;
291
292 foreach (WinSession each in this.Sessions)
293 {
294 canChange = canChange && each.DesktopContext.RequestCanChangePatient(aPatient,force);
295 }
296
297 if (canChange)
298 {
299 foreach (WinSession each in this.Sessions)
300 {
301 each.DesktopContext.ChangePatient(aPatient);
302 }
303 }
304
305 return canChange;
306 }
307
308 public bool ChangeVisit(Visit aVisit, bool force)
309 {
310 bool canChange = true;
311
312 foreach (WinSession each in this.Sessions)
313 {
314 canChange = canChange && each.DesktopContext.RequestCanChangeVisit(aVisit, force);
315 }
316
317 if (canChange)
318 {
319 foreach (WinSession each in this.Sessions)
320 {
321 each.DesktopContext.ChangeVisit(aVisit);
322 }
323 }
324 return canChange;
325 }
326
327 public bool ChangeVisit(Visit aVisit)
328 {
329 return this.ChangeVisit(aVisit, false);
330 }
331
332 public bool ChangePatient(Patient aPatient)
333 {
334 return this.ChangePatient(aPatient, false);
335 }
336
337 public Context Context
338 {
339 get
340 {
341 return this.FrameworkSession.Context;
342 }
343 }
344
345 internal ChangableContext ChangableContext
346 {
347 get
348 {
349 return (ChangableContext)this.FrameworkSession.Context;
350 }
351 }
352 private User _user = null;
353
354 public User User
355 {
356 get { return _user; }
357 }
358
359 public DataTable DivisionTable(User aUser)
360 {
361
362 return this.DivisionTable(aUser.Duz);
363 }
364
365 public DataTable DivisionTable(String anIen)
366 {
367 return this.PrimaryRemoteSession.TableFromCommand("BMXGetFacRS^" + anIen);
368 }
369
370 void future_Returned(object sender, DataTableFutureEventArgs e)
371 {
372 DataTable peek = e.Future.Result;
373 }
374
375
376
377 internal List<SelectableDivision> Divisions(User aUser)
378 {
379 return this.Divisions(aUser.Duz);
380 }
381
382 internal List<SelectableDivision> Divisions(String anIen)
383 {
384 DataTable data = this.DivisionTable(anIen);
385 List<SelectableDivision> answer = new List<SelectableDivision>();
386
387 foreach (DataRow each in data.Rows)
388 {
389 WinDivision division = new WinDivision();
390 division.Ien = each["FACILITY_IEN"].ToString();
391 division.Name = each["FACILITY_NAME"].ToString();
392 division.MostRecentLookup = "1".Equals(each["MOST_RECENT_LOOKUP"].ToString());
393 answer.Add((SelectableDivision)division);
394 }
395
396 return answer;
397 }
398
399 public bool SetDivision(String aDivisionIen)
400 {
401
402 DataTable data = this.PrimaryRemoteSession.TableFromCommand("BMXSetFac^" + aDivisionIen);
403
404 if (data.Rows.Count == 1)
405 {
406 String duz2 = data.Rows[0]["FACILITY_IEN"].ToString();
407 if ("0".Equals(duz2))
408 {
409 return false;
410 }
411 else
412 {
413 WinDivision division = new WinDivision();
414 division.Ien = duz2;
415 division.Name = data.Rows[0]["FACILITY_NAME"].ToString();
416 (this.User as WinUser).Division = division;
417
418 this.ChangePatient(null);
419
420 return true;
421 }
422 }
423 else
424 {
425 return false;
426 }
427 }
428
429
430 public bool SetDivision(Division aDivision)
431 {
432 return this.SetDivision(aDivision.Ien);
433 }
434
435 /// <summary>
436 /// Answer true if changed, false if the same
437 /// </summary>
438 /// <param name="aDialogTitle"></param>
439 /// <param name="aUiOwnerForPositioningDialog"></param>
440 /// <returns></returns>
441 public bool AttemptUserInputSetDivision(string aDialogTitle, IWin32Window aUiOwnerForPositioningDialog)
442 {
443 ChangeDivisionDialog dialog = new ChangeDivisionDialog();
444 dialog.Divisions = this.Divisions(this.User);
445
446 if (aDialogTitle != null)
447 {
448 dialog.Text = aDialogTitle;
449 }
450
451 if (aUiOwnerForPositioningDialog == null)
452 {
453 dialog.StartPosition = FormStartPosition.CenterScreen;
454 }
455
456 if (dialog.ShowDialog(aUiOwnerForPositioningDialog) == DialogResult.OK)
457 {
458 //This isn't really an optimization but rather
459 if ((this.User.Division != null) && dialog.SelectedDivision.Equals(this.User.Division))
460 {
461 return true;
462 }
463
464 if (this.SetDivision(dialog.SelectedDivision))
465 {
466 return true;
467 }
468 else
469 {
470 MessageBox.Show(aUiOwnerForPositioningDialog, "Unable to set division. Please try again or contact your helpdesk.", "RPMS RPC Error");
471 return this.AttemptUserInputSetDivision(aDialogTitle, aUiOwnerForPositioningDialog);
472 }
473 }
474 else
475 {
476 return false;
477 }
478
479 }
480 public void Close()
481 {
482 if (this.Broker != null)
483 {
484 this.Broker.Close();
485 }
486 if (this.FrameworkSession != null)
487 {
488 this.FrameworkSession.Close();
489 }
490 }
491
492
493 protected object GetTypeFromEvidence(Evidence evidence, Type aType)
494 {
495 foreach (object each in evidence)
496 {
497 if (each.GetType() == aType)
498 {
499 return each;
500 }
501 }
502 return null;
503 }
504
505 protected object GetAssemblyIdentityFromEvidence(Evidence evidence)
506 {
507 return
508 GetTypeFromEvidence(evidence, typeof(Publisher))
509 ??
510 GetTypeFromEvidence(evidence, typeof(StrongName))
511 ??
512 GetTypeFromEvidence(evidence, typeof(Url));
513 }
514
515 protected RpmsConnectionSpec RetrievePriorBMXConfiguration(Assembly priorAssemblyReadFromFile)
516 {
517 try
518 {
519 object identity = this.GetAssemblyIdentityFromEvidence(priorAssemblyReadFromFile.Evidence);
520
521 using (IsolatedStorageFile isStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, identity))
522 {
523 string sFileName = "mserver0200.dat";
524 String[] peeks = isStore.GetFileNames("*.*");
525 using (Stream stStorage = new IsolatedStorageFileStream(sFileName, FileMode.Open, isStore))
526 {
527 XmlDocument doc = new XmlDocument();
528 doc.Load(stStorage);
529
530 //Deserializing is yucky because SOAP XML is assembly version specific
531 //Peek into doc and grab values
532 RpmsConnectionSpec spec = new RpmsConnectionSpec();
533 spec.Name = "Current Connection";
534 spec.IsDefault = true;
535 spec.Server = doc.GetElementsByTagName("m_sAddress").Item(0).InnerText;
536 int port = 0;
537 int.TryParse(doc.GetElementsByTagName("m_nPort").Item(0).InnerText, out port);
538 spec.Port = port;
539 spec.NameSpace = doc.GetElementsByTagName("m_sNamespace").Item(0).InnerText;
540 return spec;
541 }
542 }
543 }
544 catch
545 {
546 return null;
547 }
548 }
549
550 public void LoadConnectionSpecsAndMergeWithExistingBMXConfiguration(Assembly priorAssemblyReadFromFile, PersistentStore aPersistentStore, params string[] keys)
551 {
552 this.LoadConnectionSpecs(aPersistentStore, keys);
553
554 if (this.ConnectionSettings.ConnectionSpecs.Count == 0)
555 {
556 RpmsConnectionSpec spec = this.RetrievePriorBMXConfiguration(priorAssemblyReadFromFile);
557 if (spec != null)
558 {
559 this.ConnectionSettings.AddConnectionSpec(spec);
560 this.ConnectionSettings.Save();
561 }
562 }
563 }
564
565 public void LoadSettings(PersistentStore aPersistentStore, params string[] keys)
566 {
567 Settings settings = new Settings();
568 settings.Store = aPersistentStore;
569 settings.StorageKeys = keys;
570 settings.WillPersistFutureSets = true;
571 settings.Load();
572
573 settings.BackupSettings = this.HardCodedSettings;
574 this.BootStrapSettings.BackupSettings = settings;
575 }
576
577
578 public void LoadConnectionSpecs(PersistentStore aPersistentStore, params string[] keys)
579 {
580 RpmsConnectionSettings settings = new RpmsConnectionSettings();
581 settings.Store = aPersistentStore;
582 settings.StorageKeys = keys;
583 settings.Load();
584
585 //Look for: /rpms:Server,Port,[Connection Name],[Namespace]
586 String[] commandLineSpecParts = this.BootStrapSettings.Get("rpms", "").Split(new char[] { ',' });
587 if (commandLineSpecParts.Length >= 2)
588 {
589 RpmsConnectionSpec spec = new RpmsConnectionSpec();
590 spec.Name = "[Command-Line Connection]";
591 spec.Server = commandLineSpecParts[0];
592 spec.UseDefaultNamespace = true;
593 spec.UseWindowsAuthentication = false;
594
595 int port = 0;
596 if (int.TryParse(commandLineSpecParts[1], out port))
597 {
598 spec.Port = port;
599 settings.CommandLineConnectionSpec = spec;
600 }
601
602 if (commandLineSpecParts.Length >= 3)
603 {
604 spec.Name = commandLineSpecParts[2];
605
606 if (commandLineSpecParts.Length >= 4)
607 {
608 spec.NameSpace = commandLineSpecParts[3];
609 spec.UseDefaultNamespace = spec.NameSpace.Length == 0;
610 }
611 else
612 {
613 spec.UseDefaultNamespace = true;
614 }
615
616 if (commandLineSpecParts.Length >= 5)
617 {
618 spec.UseWindowsAuthentication= commandLineSpecParts[4].Equals("Win",StringComparison.InvariantCultureIgnoreCase);
619
620 if (commandLineSpecParts.Length >= 6)
621 {
622 int timeOut = 0;
623 if (int.TryParse(commandLineSpecParts[5], out timeOut))
624 {
625 spec.ReceiveTimeout= timeOut;
626 }
627
628 if (commandLineSpecParts.Length >= 7)
629 {
630 if (int.TryParse(commandLineSpecParts[6], out timeOut))
631 {
632 spec.SendTimeout= timeOut;
633 }
634 }
635 }
636 }
637 }
638
639
640 }
641 String connectionName = this.BootStrapSettings.Get("connection", "").Trim();
642 if (connectionName.Length > 0)
643 {
644 foreach (RpmsConnectionSpec each in settings.ConnectionSpecs)
645 {
646 if (each.Name.Equals(connectionName, StringComparison.InvariantCultureIgnoreCase))
647 {
648 settings.DefaultConnectionSpec = each;
649 break;
650 }
651 }
652 }
653
654 this.ConnectionSettings = settings;
655 }
656
657 public LoginProcess CreateLoginProcess()
658 {
659 return new LoginProcess(this);
660
661 }
662
663 public Patient FindPatient(String aSearchString)
664 {
665 this.Log.Log("BMX WIN", "Info", "FindPatient > " + aSearchString);
666 List<Patient> patients = this.FindPatients(aSearchString, 2);
667
668 return patients.Count == 1 ? patients[0] : null;
669 }
670
671
672 public List<Patient> FindPatients(String aSearchString, int max)
673 {
674 this.Log.Log("BMX WIN", "Info", "FindPatients > " + aSearchString + ", " + max.ToString());
675 DataTable data = this.FindPatientsAsTable(aSearchString, max);
676
677 //this.Bmx.TableFromCommand("BMX FIND PATIENT^" + aSearchString.ToUpper() + "|" + max.ToString()); ;
678
679 List<Patient> answer = new List<Patient>();
680
681 foreach (DataRow each in data.Rows)
682 {
683 WinPatient patient = new WinPatient();
684 patient.Ien = each["IEN"].ToString();
685 patient.PatientName = each["PATIENTNAME"].ToString();
686 patient.Sex = each["SEX"].ToString();
687 patient.HealthRecordNumber = each["CHART"].ToString();
688 patient.Age = int.Parse(each["AGE"].ToString());
689 patient.Ssn = each["SSN"].ToString();
690 //patient.????= each["CLASSBEN"].ToString();
691 //patient.????= each["REG"].ToString();
692 //patient.????= each["LASTUPDATE"].ToString();
693
694
695 DateTime dob;
696 if (DateTime.TryParse(each["DOB"].ToString(), out dob))
697 {
698 patient.Dob = dob;
699 };
700
701 answer.Add(patient);
702 }
703
704 return answer;
705 }
706
707 public DataTable FindPatientsAsTable(String aSearchString, int max)
708 {
709 this.Log.Log("BMX WIN", "Info", "FindPatientsAsTable > " + aSearchString + ", " + max.ToString());
710 return this.PrimaryRemoteSession.TableFromCommand("BMX FIND PATIENT^" + aSearchString + "|" + max.ToString());
711 }
712
713 public DataTable VisitsAsTable(Patient aPatient, int aMax)
714 {
715 return this.VisitsAsTable(aPatient.Ien, aMax);
716 }
717
718 public DataTable VisitsAsTable(String aDFN, int aMax)
719 {
720 return this.PrimaryRemoteSession.TableFromCommand("BMX FIND VISIT^" + aDFN + "|" + aMax.ToString()); ;
721 }
722
723 public List<Visit> Visits(Patient aPatient, int aMax)
724 {
725 return this.Visits(aPatient.Ien, aMax);
726 }
727
728
729 public List<Visit> Visits(String aDFN, int aMax)
730 {
731
732 DataTable data = this.VisitsAsTable(aDFN, aMax);
733
734 List<Visit> answer = new List<Visit>();
735
736 foreach (DataRow each in data.Rows)
737 {
738 WinVisit visit = new WinVisit();
739 visit.Ien = each["VISIT_IEN"].ToString();
740 visit.ProviderName = each["PRIMARY_PROVIDER"].ToString();
741 visit.Clinic = each["CLINIC"].ToString();
742 visit.LocationName = each["LOCATION"].ToString();
743 visit.ServiceCategory = each["SERVICE CATEGORY"].ToString();
744 visit.VisitType = each["VISIT_TYPE"].ToString();
745
746 DateTime date;
747
748 String[] formats = new string[] { "MMM dd, yyyy@HH:mm", "MMM d, yyyy@HH:mm", "MMM d,yyyy@HH:mm", "MMM d, yyyy@H:mm", "MMM d,yyyy@H:mm", "MMM dd,yyyy@HH:mm" };
749 String dateText = each["TIMESTAMP"].ToString();
750 if (DateTime.TryParseExact(dateText, formats, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out date))
751 {
752 visit.DateTime = date;
753 }
754 else if (DateTime.TryParse(dateText, out date))
755 {
756 visit.DateTime = date;
757 }
758
759
760 answer.Add(visit);
761 }
762
763 return answer;
764 }
765
766 internal void Close(WinSession winSession)
767 {
768 if (this.Broker != null)
769 {
770 this.Broker.Close();
771 }
772 }
773
774 #region ILog Members
775
776 public bool IsLogging
777 {
778 get
779 {
780 return this.Log.IsLogging;
781 }
782 set
783 {
784 this.Log.IsLogging = value;
785 }
786 }
787
788 void Log.Log(string aClass, string aCategory, params string[] lines)
789 {
790 this.Log.Log(aClass, aCategory, lines);
791 }
792
793 void Log.Log(string aClass, string aCategory, Exception anException, params string[] lines)
794 {
795 this.Log.Log(aClass, aCategory, anException, lines);
796 }
797
798 #endregion
799 }
800}
Note: See TracBrowser for help on using the repository browser.