/// <summary> /// Process PID data async manner /// </summary> private void ProcessPIDAsync(object state) { try { var responseData = state as RSP_K21_QUERY_RESPONSE; GIIS.DataLayer.Child child = null; // Now sync patient data if they don't exist // Is there a GIIS identifier in the list of identifiers for this patient? String ecidIdentifier = responseData.PID.GetPatientIdentifierList().Where(id => id.AssigningAuthority.UniversalID.Value == ConfigurationManager.AppSettings["ecid"]).Select(o => o.IDNumber.Value).First(); List <String> localGiisIdentifier = responseData.PID.GetPatientIdentifierList().Where(id => id.AssigningAuthority.UniversalID.Value == ConfigurationManager.AppSettings["giis_child_id_oid"]).Select(o => o.IDNumber.Value).ToList(); // If there is a local GIIS identifier! The patient exists in GIIS if (localGiisIdentifier.Count > 0) { var children = localGiisIdentifier.Select(o => GIIS.DataLayer.Child.GetChildById(Int32.Parse(o))).ToList(); children.RemoveAll(o => o == null); if (children.Count == 0) { Trace.TraceInformation("{0} : No children records found with local ID, maybe they're gone?", this.m_context.JobId); return; } // Find the child that has the ECID using (var dao = new SyncData()) { // Get the survivor or the only child = children.FirstOrDefault(o => o != null && o.IsActive && dao.GetChildEcid(o.Id) == ecidIdentifier); if (child == null && children.Count == 1) { child = children.First(); children.Clear(); } else { children.RemoveAll(o => o.Id == child.Id && child.IsActive); } // Is the record in the CR newer than the record in GIIS? if (((TS)responseData.PID.LastUpdateDateTime.Time.Value).DateValue.Date > child.ModifiedOn.Date.AddDays(1)) { // Register that we've updated this patient in the sync log Trace.TraceInformation("{0} : Updating child record {1}", this.m_context.JobId, child.Id); // Copy fields this.CopyChildRecordFields(child, responseData.PID); // Now update GIIS.DataLayer.Child.Update(child); dao.RegisterPatientSync(child.Id, this.m_context.JobId, ActionType.Update, ecidIdentifier); } else { Trace.TraceWarning("{0} : Child record {1} in GIIS appears to be up to date", this.m_context.JobId, child.Id); //return; } // Merge patient data if (children.Count > 0) { // Load all completed vaccinations/appointments/weights for the survivor var survivorsVaccinationEvents = GIIS.DataLayer.VaccinationEvent.GetImmunizationCard(child.Id).Where(o => o.VaccinationStatus || o.NonvaccinationReasonId != 0).ToList(); var survivorsNonVaccinationAppointments = GIIS.DataLayer.VaccinationEvent.GetImmunizationCard(child.Id).Where(o => !o.VaccinationStatus && o.NonvaccinationReasonId == 0).Select(o => o.Appointment).Distinct(new VaccinationAppointmentComparator()); var survivorsWeightEvents = GIIS.DataLayer.ChildWeight.GetChildWeightByChildId(child.Id); var survivorsSupplements = GIIS.DataLayer.ChildSupplements.GetChildSupplementsByChild(child.Id); // Now we want to add vaccination events foreach (var victim in children) { Trace.TraceInformation("Merging CHILD {0} INTO {1}", victim.Id, child.Id); // GEt all victim's vaccination events that were not given to the survivor IEnumerable victimsVaccinationEvents = GIIS.DataLayer.VaccinationEvent.GetImmunizationCard(victim.Id) .Where(o => (o.VaccinationStatus || o.NonvaccinationReasonId != 0) && !survivorsVaccinationEvents.Exists(s => s.DoseId == o.DoseId)), victimsWeightEvents = GIIS.DataLayer.ChildWeight.GetChildWeightByChildId(victim.Id); var victimSupplements = GIIS.DataLayer.ChildSupplements.GetChildSupplementsByChild(victim.Id); // Now we want to copy from victim to survivor foreach (GIIS.DataLayer.VaccinationEvent victimEvent in victimsVaccinationEvents) { victimEvent.ChildId = child.Id; victimEvent.ModifiedBy = Int32.Parse(ConfigurationManager.AppSettings["giis_authority_user_id"]); victimEvent.ModifiedOn = DateTime.Now; GIIS.DataLayer.VaccinationEvent.Insert(victimEvent); } // Now copy weights over foreach (GIIS.DataLayer.ChildWeight weight in victimsWeightEvents) { weight.ChildId = child.Id; weight.ModifiedBy = Int32.Parse(ConfigurationManager.AppSettings["giis_authority_user_id"]); weight.ModifiedOn = DateTime.Now; GIIS.DataLayer.ChildWeight.Insert(weight); } // Supplements if (survivorsSupplements != null) { survivorsSupplements.Mebendezol = victimSupplements.Mebendezol || survivorsSupplements.Mebendezol; survivorsSupplements.Vita = victimSupplements.Vita || survivorsSupplements.Vita; GIIS.DataLayer.ChildSupplements.Update(survivorsSupplements); } // Obsolete the old version victim.StatusId = GIIS.DataLayer.Status.GetStatusByName("Duplicate").Id; GIIS.DataLayer.Child.Update(victim); GIIS.DataLayer.ChildMerges mergeData = new GIIS.DataLayer.ChildMerges(); mergeData.ChildId = child.Id; mergeData.SubsumedId = victim.Id; mergeData.EffectiveDate = DateTime.Now; GIIS.DataLayer.ChildMerges.Insert(mergeData); } } dao.Commit(); } } else // We need to create the child record in GIIS { Trace.TraceInformation("{0} : Creating child record from ECID {1}", this.m_context.JobId, ecidIdentifier); // Child child = new GIIS.DataLayer.Child(); this.CopyChildRecordFields(child, responseData.PID); try { // Is the child older than the last vaccination? If so we don't really care if (GIIS.DataLayer.Dose.GetDosesByDates(child.Birthdate).Count == 0) { Trace.TraceInformation("Don't care about this child as they don't have any vaccinations required"); return; } child.Id = GIIS.DataLayer.Child.Insert(child); GIIS.DataLayer.VaccinationAppointment.InsertVaccinationsForChild(child.Id, 1); // Register the patient in the PIX manager // Register the fact we create the child in the sync log using (var dao = new SyncData()) { dao.RegisterPatientSync(child.Id, this.m_context.JobId, ActionType.Create, ecidIdentifier); ADT_A01 message = this.CreateADT(child, dao); var response = this.m_sender.SendAndReceive(message) as NHapi.Model.V231.Message.ACK; AuditUtil.SendPIXAudit(message, response); if (!response.MSA.AcknowledgementCode.Value.EndsWith("A")) { Trace.TraceError("{0} : Registration of the patient failed in CR"); foreach (var er in response.ERR.GetErrorCodeAndLocation()) { Trace.TraceError("{0} : ERR {1}", this.m_context.JobId, er.CodeIdentifyingError.Text.Value); } } dao.Commit(); } } catch (Exception e) { Trace.TraceError("{0} : Error registering child record: {1}", this.m_context.JobId, e); } } } catch (Exception e) { Trace.TraceInformation(e.ToString()); this.m_errorState = true; } }
/// <summary> /// Process a response message doing query continuation if needed /// </summary> private void PushPatientsAsync(Object state) { Int32 childId = (Int32)state; // Get the child record try { GIIS.DataLayer.Child child = GIIS.DataLayer.Child.GetChildById(childId); // Determine if this is an update to information (A08) or registration (A04) using (var dao = new SyncData()) { ADT_A01 request = this.CreateADT(child, dao); ActionType action = ActionType.Create; String ecid = dao.GetPatientEcid(childId); if (ecid == null) // no ECID = Register { this.UpdateMSH(request.MSH, "ADT_A01", "ADT", "A04"); } else { this.UpdateMSH(request.MSH, "ADT_A01", "ADT", "A08"); action = ActionType.Update; } // Send the message var response = this.m_sender.SendAndReceive(request) as NHapi.Model.V231.Message.ACK; AuditUtil.SendPIXAudit(request, response); if (response == null || !response.MSA.AcknowledgementCode.Value.EndsWith("A")) { Trace.TraceError("{0}: Error registering the child in HIE (child id#{1})", this.m_context.JobId, childId); foreach (var err in response.ERR.GetErrorCodeAndLocation()) { Trace.TraceError("{0}: CR ERR: {1} ({2})", this.m_context.JobId, err.CodeIdentifyingError.Text, err.CodeIdentifyingError.AlternateText); } // Kill! Trace.TraceError("Stopping sync"); this.m_errorState = true; return; } // Get the ECID if not already got if (action == ActionType.Create) { var pixSearch = this.CreatePIXSearch(child.Id, ConfigurationManager.AppSettings["giis_child_id_oid"], ConfigurationManager.AppSettings["ecid"]); var pixResponse = this.m_sender.SendAndReceive(pixSearch) as RSP_K23; AuditUtil.SendPIXAudit(pixSearch, pixResponse); // Is the response success? if (pixResponse == null || pixResponse.QAK.QueryResponseStatus.Value != "OK") { Trace.TraceError("{0}: Error retrieving the ECID for created patient", this.m_context.JobId); foreach (var err in pixResponse.ERR.GetErrorCodeAndLocation()) { Trace.TraceError("{0}: CR ERR: {1} ({2})", this.m_context.JobId, err.CodeIdentifyingError.Text, err.CodeIdentifyingError.AlternateText); } // Kill! Trace.TraceError("Stopping sync"); this.m_errorState = true; return; } else { var cx = pixResponse.QUERY_RESPONSE.PID.GetPatientIdentifierList(0); // Sanity check if (cx.AssigningAuthority.UniversalID.Value.Equals(ConfigurationManager.AppSettings["ecid"])) { ecid = cx.IDNumber.Value; } else { Trace.TraceError("{0}: Should not be here! CX.4 indicates ECID OID is {1} but configuration is {2}?", this.m_context.JobId, cx.AssigningAuthority.UniversalID.Value, ConfigurationManager.AppSettings["ecid"]); this.m_errorState = true; return; } } } // Update if (String.IsNullOrEmpty(child.TempId)) { child.TempId = ecid; } child.ModifiedOn = DateTime.Now; child.ModifiedBy = Int32.Parse(ConfigurationManager.AppSettings["giis_authority_user_id"]); GIIS.DataLayer.Child.Update(child); dao.RegisterPatientSync(childId, this.m_context.JobId, action, ecid); dao.Commit(); } } catch (Exception e) { Trace.TraceError(e.ToString()); this.m_errorState = true; } }