/// <summary>
        /// Create an ADT message for the child
        /// </summary>
        private ADT_A01 CreateADT(GIIS.DataLayer.Child child, SyncData dao = null)
        {
            ADT_A01 retVal = new ADT_A01();

            retVal.MSH.VersionID.VersionID.Value = "2.3.1";

            this.UpdateMSH(retVal.MSH, "ADT_A01", "ADT", "A01");
            this.UpdatePID(retVal.PID, child, dao);

            return(retVal);
        }
        public void UploadData(OmrPageOutput page)
        {
            if (!Connectivity.CheckForInternetConnection())
            {
                MessageBox.Show(
                    "Username is empty, This is usually caused by lack of internet connectivity. Please try again later");
                Exception e = new Exception("No internet connection");
                Trace.TraceError("Error:{0}", e);
                throw e;
            }

            try
            {
                this.Err = "";
                var restUtil = new RestUtil(new Uri(ConfigurationManager.AppSettings["GIIS_URL"]));
                Trace.TraceInformation("Need to sync {0} children with TIIS at {1}", page.Details.Count, ConfigurationManager.AppSettings["GIIS_URL"]);

                foreach (var dtl in page.Details.OfType <OmrRowData>())
                {
                    // Get the barcode information for this child
                    var barcodes = dtl.Details.OfType <OmrBarcodeData>();
                    if (barcodes.Count() == 0)
                    {
                        throw new InvalidOperationException("No barcode found on row!");
                    }

                    // Child code
                    var childCode = barcodes.FirstOrDefault(o => o.Id == dtl.Id + "_TempId");

                    if (childCode == null)
                    {
                        throw new InvalidOperationException("No GIIS TempId Found on Row!");
                    }

                    GIIS.DataLayer.Child childData = null;

                    // Get the child by barcode id
                    var childDataList = restUtil.Get <List <ChildEntity> >("ChildManagement.svc/GetChildById",
                                                                           new KeyValuePair <string, object>("childId", childCode.BarcodeData.Replace("T", ""))
                                                                           );
                    if (childDataList == null)
                    {
                        throw new InvalidOperationException("Could not deserialize response");
                    }
                    else if (childDataList.Count == 0)
                    {
                        throw new InvalidOperationException("Child with id " + childCode.BarcodeData + " not found!");
                    }
                    childData = childDataList[0].childEntity;

                    var permCode = barcodes.FirstOrDefault(o => o.Id == dtl.Id + "_Barcode");

                    // Permcode == null = no association
                    if (permCode == null)
                    {
                        Err += String.Format("{0}, {1} will not be associated with a barcode sticker; ", childData.Lastname1, childData.Firstname1);
                        continue;
                    }

                    // Now to update the child
                    Trace.TraceInformation("Will associated child id {0} with barcode {1}", childData.Id, permCode.BarcodeData);

                    childData.BarcodeId = permCode.BarcodeData;

                    // Send the update
                    restUtil.Get <RestReturn>("ChildManagement.svc/UpdateChild",
                                              new KeyValuePair <string, object>("barcode", childData.BarcodeId),
                                              new KeyValuePair <string, object>("firstname1", childData.Firstname1),
                                              new KeyValuePair <string, object>("lastname1", childData.Lastname1),
                                              new KeyValuePair <string, object>("birthdate", childData.Birthdate.ToString("yyyy-MM-dd")),
                                              new KeyValuePair <string, object>("gender", childData.Gender),
                                              new KeyValuePair <string, object>("healthFacilityId", childData.HealthcenterId),
                                              new KeyValuePair <string, object>("birthplaceId", childData.BirthplaceId),
                                              new KeyValuePair <string, object>("domicileId", childData.DomicileId),
                                              new KeyValuePair <string, object>("statusId", childData.StatusId),
                                              new KeyValuePair <string, object>("address", childData.Address),
                                              new KeyValuePair <string, object>("phone", childData.Phone),
                                              new KeyValuePair <string, object>("motherFirstname", childData.MotherFirstname),
                                              new KeyValuePair <string, object>("motherLastname", childData.MotherLastname),
                                              new KeyValuePair <string, object>("notes", "Updated by form scanning application"),
                                              new KeyValuePair <string, object>("userId", 1),
                                              new KeyValuePair <string, object>("childId", childData.Id)
                                              );
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }
        /// <summary>
        /// Update PID segment from a child
        /// </summary>
        private void UpdatePID(PID pid, GIIS.DataLayer.Child child, SyncData dao = null)
        {
            pid.AdministrativeSex.Value = child.Gender ? "M" : "F";
            if (child.Birthplace != null)
            {
                pid.BirthPlace.Value = child.Birthplace.Name;
            }
            pid.DateTimeOfBirth.Time.Value = new TS(child.Birthdate, DatePrecision.Day).Value;

            // Ethnic group
            if (child.Community != null)
            {
                pid.GetEthnicGroup(0).Identifier.Value = child.Community.Name;
            }

            if (!String.IsNullOrEmpty(child.Phone))
            {
                pid.GetPhoneNumberHome(0).AnyText.Value = child.Phone;
            }

            if (!String.IsNullOrEmpty(child.MotherFirstname))
            {
                pid.GetMotherSMaidenName(0).GivenName.Value = child.MotherFirstname;
            }
            if (!String.IsNullOrEmpty(child.MotherLastname))
            {
                pid.GetMotherSMaidenName(0).FamilyName.Surname.Value = child.MotherLastname;
            }

            if (!String.IsNullOrEmpty(child.Firstname1))
            {
                pid.GetPatientName(0).GivenName.Value = child.Firstname1;
            }
            if (!String.IsNullOrEmpty(child.Firstname2))
            {
                pid.GetPatientName(0).SecondAndFurtherGivenNamesOrInitialsThereof.Value = child.Firstname2;
            }
            if (!String.IsNullOrEmpty(child.Lastname1))
            {
                pid.GetPatientName(0).FamilyName.Surname.Value = child.Lastname1;
            }
            if (!String.IsNullOrEmpty(child.Lastname2))
            {
                pid.GetPatientName(0).FamilyName.OwnSurname.Value = child.Lastname2;
            }

            // Domicile
            if (child.Domicile != null)
            {
                if (!String.IsNullOrEmpty(child.Domicile.Code))
                {
                    pid.GetPatientAddress(0).CensusTract.Value = child.Domicile.Code;
                }

                Queue <AbstractPrimitive> addressParts = new Queue <AbstractPrimitive>(new AbstractPrimitive[] {
                    pid.GetPatientAddress(0).OtherDesignation,                     // Kitongoji
                    pid.GetPatientAddress(0).StreetAddress.StreetOrMailingAddress, // Street or Village
                    pid.GetPatientAddress(0).City,                                 // Ward
                    pid.GetPatientAddress(0).CountyParishCode,                     // district
                    pid.GetPatientAddress(0).StateOrProvince,                      // Region
                    pid.GetPatientAddress(0).Country                               // National
                });

                // Queue places
                Queue <GIIS.DataLayer.Place> domicileParts = new Queue <GIIS.DataLayer.Place>();
                GIIS.DataLayer.Place         current       = child.Domicile;
                while (current != null)
                {
                    domicileParts.Enqueue(current);
                    current = current.Parent;
                }

                // Now trim
                while (addressParts.Count > domicileParts.Count)
                {
                    addressParts.Dequeue();
                }

                // Now map
                while (domicileParts.Count > 0)
                {
                    addressParts.Dequeue().Value = domicileParts.Dequeue().Name;
                }
            }

            if (child.Status.Name == "Dead")
            {
                pid.PatientDeathIndicator.Value = "Y";
            }

            // Identifiers
            int i = 0;

            pid.GetPatientIdentifierList(i).IDNumber.Value = child.Id.ToString();
            pid.GetPatientIdentifierList(i).AssigningAuthority.UniversalID.Value       = ConfigurationManager.AppSettings["giis_child_id_oid"];
            pid.GetPatientIdentifierList(i++).AssigningAuthority.UniversalIDType.Value = "ISO";

            // 1st alt
            if (!String.IsNullOrEmpty(child.IdentificationNo1) && !String.IsNullOrEmpty(ConfigurationManager.AppSettings["giis_child_alt_id_1_oid"]))
            {
                pid.GetPatientIdentifierList(i).IDNumber.Value = child.IdentificationNo1.ToString();
                pid.GetPatientIdentifierList(i).AssigningAuthority.UniversalID.Value       = ConfigurationManager.AppSettings["giis_child_alt_id_1_oid"];
                pid.GetPatientIdentifierList(i++).AssigningAuthority.UniversalIDType.Value = "ISO";
            }
            // 2nd alt
            if (!String.IsNullOrEmpty(child.IdentificationNo2) && !String.IsNullOrEmpty(ConfigurationManager.AppSettings["giis_child_alt_id_2_oid"]))
            {
                pid.GetPatientIdentifierList(i).IDNumber.Value = child.IdentificationNo2.ToString();
                pid.GetPatientIdentifierList(i).AssigningAuthority.UniversalID.Value       = ConfigurationManager.AppSettings["giis_child_alt_id_2_oid"];
                pid.GetPatientIdentifierList(i++).AssigningAuthority.UniversalIDType.Value = "ISO";
            }
            // 3rd alt
            if (!String.IsNullOrEmpty(child.IdentificationNo3) && !String.IsNullOrEmpty(ConfigurationManager.AppSettings["giis_child_alt_id_3_oid"]))
            {
                pid.GetPatientIdentifierList(i).IDNumber.Value = child.IdentificationNo3.ToString();
                pid.GetPatientIdentifierList(i).AssigningAuthority.UniversalID.Value       = ConfigurationManager.AppSettings["giis_child_alt_id_3_oid"];
                pid.GetPatientIdentifierList(i++).AssigningAuthority.UniversalIDType.Value = "ISO";
            }
            // Barcode
            if (!String.IsNullOrEmpty(child.BarcodeId))
            {
                pid.GetPatientIdentifierList(i).IDNumber.Value = child.BarcodeId.ToString();
                pid.GetPatientIdentifierList(i).AssigningAuthority.UniversalID.Value       = ConfigurationManager.AppSettings["giis_child_barcode_oid"];
                pid.GetPatientIdentifierList(i++).AssigningAuthority.UniversalIDType.Value = "ISO";
            }

            // ECID?
            if (dao == null)
            {
                dao = new SyncData();
            }
            string ecid = dao.GetPatientEcid(child.Id);

            if (ecid != null)
            {
                pid.GetPatientIdentifierList(i).IDNumber.Value = ecid;
                pid.GetPatientIdentifierList(i).AssigningAuthority.UniversalID.Value       = ConfigurationManager.AppSettings["ecid"];
                pid.GetPatientIdentifierList(i++).AssigningAuthority.UniversalIDType.Value = "ISO";
            }
        }
        /// <summary>
        /// Update a child record to match the PID segment
        /// </summary>
        private void CopyChildRecordFields(GIIS.DataLayer.Child child, PID pid)
        {
            // Gender
            if (!String.IsNullOrEmpty(pid.AdministrativeSex.Value))
            {
                child.Gender = pid.AdministrativeSex.Value == "M";
            }

            // Date of birth
            if (!String.IsNullOrEmpty(pid.DateTimeOfBirth.Time.Value))
            {
                child.Birthdate = (DateTime)(TS)pid.DateTimeOfBirth.Time.Value;
            }

            // Is part of a multiple birth?
            if (!String.IsNullOrEmpty(pid.MultipleBirthIndicator.Value))
            {
                child.Notes = "twin";
            }

            // Phone
            if (!String.IsNullOrEmpty(pid.GetPhoneNumberHome(0).TelephoneNumber.Value))
            {
                child.Phone = pid.GetPhoneNumberHome(0).TelephoneNumber.Value;
            }
            else if (!String.IsNullOrEmpty(pid.GetPhoneNumberHome(0).AnyText.Value))
            {
                child.Phone = pid.GetPhoneNumberHome(0).AnyText.Value;
            }

            // Mother's name?
            if (pid.MotherSMaidenNameRepetitionsUsed > 0)
            {
                child.MotherLastname  = pid.GetMotherSMaidenName()[0].FamilyName.Surname.Value;
                child.MotherFirstname = pid.GetMotherSMaidenName()[0].GivenName.Value;
            }

            // Name
            if (pid.PatientNameRepetitionsUsed > 0)
            {
                child.Lastname1  = pid.GetPatientName()[0].FamilyName.Surname.Value;
                child.Lastname2  = pid.GetPatientName()[0].FamilyName.OwnSurname.Value;
                child.Firstname1 = pid.GetPatientName()[0].GivenName.Value;
                child.Firstname2 = pid.GetPatientName()[0].SecondAndFurtherGivenNamesOrInitialsThereof.Value;
            }

            // Identification numbers
            foreach (var id in pid.GetPatientIdentifierList())
            {
                if (id.AssigningAuthority.UniversalID.Value == ConfigurationManager.AppSettings["giis_child_alt_id_1_oid"])
                {
                    child.IdentificationNo1 = id.IDNumber.Value;
                }
                else if (id.AssigningAuthority.UniversalID.Value == ConfigurationManager.AppSettings["giis_child_alt_id_2_oid"])
                {
                    child.IdentificationNo2 = id.IDNumber.Value;
                }
                else if (id.AssigningAuthority.UniversalID.Value == ConfigurationManager.AppSettings["giis_child_alt_id_3_oid"])
                {
                    child.IdentificationNo3 = id.IDNumber.Value;
                }
                else if (id.AssigningAuthority.UniversalID.Value == ConfigurationManager.AppSettings["giis_child_barcode_oid"])
                {
                    child.BarcodeId = id.IDNumber.Value;
                }
                else if (id.AssigningAuthority.UniversalID.Value == ConfigurationManager.AppSettings["ecid"])
                {
                    child.TempId = id.IDNumber.Value;
                }
            }

            // Birthplace -
            // TODO: How does this map to GIIS?
            if (!String.IsNullOrEmpty(pid.BirthPlace.Value))
            {
                var place = GIIS.DataLayer.Birthplace.GetBirthplaceByName(pid.BirthPlace.Value);
                if (place == null)
                {
                    Trace.TraceWarning("{0} : Could not map birthplace {1} for child {2}", this.m_context.JobId, pid.BirthPlace.Value, child.Id);
                }
                else
                {
                    child.BirthplaceId = place.Id;
                }
            }

            // Address information
            // TODO: How does this map to GIIS?
            if (pid.PatientAddressRepetitionsUsed > 0)
            {
                // Domicile = Cascade down the heirarchy
                var xad = pid.GetPatientAddress()[0];
                GIIS.DataLayer.Place current = null;

                if (!String.IsNullOrEmpty(xad.CensusTract.Value)) // prefer census tract
                {
                    current = GIIS.DataLayer.Place.GetPlaceByCode(xad.CensusTract.Value);
                }
                if (current == null)
                {
                    Queue <String> placeSearch = new Queue <string>(new String[] {
                        xad.Country.Value,
                        xad.StateOrProvince.Value,                      // Region
                        xad.CountyParishCode.Value,                     // District
                        xad.City.Value,                                 // Ward
                        xad.StreetAddress.StreetOrMailingAddress.Value, // Village
                        xad.OtherDesignation.Value                      // Kitongoji
                    });
                    while (placeSearch.Count > 0)
                    {
                        var xadPart = placeSearch.Dequeue();
                        if (xadPart == null)
                        {
                            continue;
                        }

                        var candidate = GIIS.DataLayer.Place.GetPlaceByName(xadPart, current == null ? 0 : current.Id);
                        if (candidate == null)
                        {
                            break;
                        }
                        current = candidate;
                    }
                }
                if (current != null)
                {
                    if (child.DomicileId != current.Id)
                    {
                        child.DomicileId = current.Id;
                        if (child.Healthcenter == null)
                        {
                            if (current.HealthFacility != null)
                            {
                                child.HealthcenterId = current.HealthFacility.Id;
                            }
                            else
                            {
                                child.HealthcenterId = Int32.Parse(ConfigurationManager.AppSettings["giis_unknown_facility"]);
                            }
                        }
                        else
                        {
                            Trace.TraceInformation("Will not update child {0} health facility", child.Id);
                        }
                    }
                }
            }

            if (child.Healthcenter == null)
            {
                child.HealthcenterId = Int32.Parse(ConfigurationManager.AppSettings["giis_unknown_facility"]);
            }


            // Death?
            if (pid.PatientDeathIndicator.Value == "Y")
            {
                child.StatusId = GIIS.DataLayer.Status.GetStatusByName("Dead").Id;
                child.IsActive = false;
            }
            else
            {
                child.StatusId = GIIS.DataLayer.Status.GetStatusByName("Active").Id;
                child.IsActive = true;
            }
            child.StatusId = child.Status.Id;

            if (pid.LastUpdateDateTime.Time.Value != null)
            {
                child.ModifiedOn = ((TS)pid.LastUpdateDateTime.Time.Value).DateValue;
            }
            else
            {
                child.ModifiedOn = DateTime.Now;
            }
            child.ModifiedBy = Int32.Parse(ConfigurationManager.AppSettings["giis_authority_user_id"]);

            if (child.SystemId == null)
            {
                lock (this.m_syncState)
                    child.SystemId = String.Format("{0:X16}", BitConverter.ToInt64(Guid.NewGuid().ToByteArray().Take(16).ToArray(), 0), BitConverter.ToInt64(Guid.NewGuid().ToByteArray().Skip(8).Take(8).ToArray(), 0));
            }
        }
        /// <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;
            }
        }
Example #7
0
        public void UploadData(OmrPageOutput page)
        {
            if (!Connectivity.CheckForInternetConnection())
            {
                MessageBox.Show(
                    "Username is empty, This is usually caused by lack of internet connectivity. Please try again later");
                Exception e = new Exception("No internet connection");
                Trace.TraceError("Error:{0}", e);
                throw e;
            }
            try
            {
                this.Err = "";

                var restUtil = new RestUtil(new Uri(ConfigurationManager.AppSettings["GIIS_URL"]));
                Trace.TraceInformation("Need to sync {0} children with TIIS at {1}", page.Details.Count, ConfigurationManager.AppSettings["GIIS_URL"]);

                var refDoses    = restUtil.Get <List <GIIS.DataLayer.Dose> >("DoseManagement.svc/GetDoseList");
                var refVaccines = restUtil.Get <List <GIIS.DataLayer.ScheduledVaccination> >("ScheduledVaccinationManagement.svc/GetScheduledVaccinationList");
                var refItems    = restUtil.Get <List <GIIS.DataLayer.Item> >("ItemManagement.svc/GetItemList");
                var refItemLots = restUtil.Get <List <GIIS.DataLayer.ItemLot> >("StockManagement.svc/GetItemLots");

                foreach (var dtl in page.Details.OfType <OmrRowData>())
                {
                    // Get the barcode information for this child
                    var barcodes = dtl.Details.OfType <OmrBarcodeData>();
                    if (barcodes.Count() > 1)
                    {
                        throw new InvalidOperationException("Only one barcode per row is supported by this template");
                    }
                    else if (barcodes.Count() == 0)
                    {
                        throw new InvalidOperationException("No barcode found on row!");
                    }

                    // Child code
                    var childCode = barcodes.FirstOrDefault();

                    // Output sync
                    Trace.TraceInformation("Syncing child {0} to GIIS - Step 1 - Resolve Barcode ID", childCode.BarcodeData);

                    GIIS.DataLayer.Child childData = null;

                    // Get the child by barcode id
                    if (childCode.BarcodeData.StartsWith("T"))
                    {
                        var childDataList = restUtil.Get <List <ChildEntity> >("ChildManagement.svc/GetChildById",
                                                                               new KeyValuePair <string, object>("childId", childCode.BarcodeData.Replace("T", ""))
                                                                               );
                        if (childDataList == null)
                        {
                            throw new InvalidOperationException("Could not deserialize response");
                        }
                        else if (childDataList.Count == 0)
                        {
                            throw new InvalidOperationException("Child with barcode " + childCode.BarcodeData + " not found!");
                        }
                        childData = childDataList[0].childEntity;
                    }
                    else
                    {
                        var childDataList = restUtil.Get <List <ChildEntity> >("ChildManagement.svc/SearchByBarcode",
                                                                               new KeyValuePair <string, object>("barcodeId", childCode.BarcodeData));
                        if (childDataList == null)
                        {
                            throw new InvalidOperationException("Could not deserialize response");
                        }
                        else if (childDataList.Count == 0)
                        {
                            throw new InvalidOperationException("Child with barcode " + childCode.BarcodeData + " not found!");
                        }
                        childData = childDataList[0].childEntity;
                    }
                    int childId = childData.Id;

                    // Is this child a non-vaccination?
                    var bubbleData = dtl.Details.OfType <OmrBubbleData>();

                    // Load questions
                    OmrBubbleData weight10    = bubbleData.FirstOrDefault(o => o.Key == "weight10"),
                                  weight1     = bubbleData.FirstOrDefault(o => o.Key == "weight"),
                                  weight10ths = bubbleData.FirstOrDefault(o => o.Key == "weightD"),
                                  date10      = bubbleData.FirstOrDefault(o => o.Key == "date10"),
                                  date        = bubbleData.FirstOrDefault(o => o.Key == "date"),
                                  ebfr        = bubbleData.FirstOrDefault(o => o.Key == "ebfr"),
                                  vaccines    = bubbleData.FirstOrDefault(o => o.Key == "vaccines"),
                                  outreach    = bubbleData.FirstOrDefault(o => o.Key == "outreach");

                    // No vaccinations?
                    if (vaccines == null)
                    {
                        Trace.TraceInformation("No vaccines detected!");
                        continue;
                    }

                    // Weight
                    float weight = 0.0f;
                    if (weight10 != null)
                    {
                        weight = weight + weight10.ValueAsFloat;
                    }
                    if (weight1 != null)
                    {
                        weight = weight + weight1.ValueAsFloat;
                    }
                    if (weight10ths != null)
                    {
                        weight = weight + (weight10ths.ValueAsFloat * 0.1f);
                    }

                    // Date
                    int day = 0;
                    if (date10 != null)
                    {
                        day += (int)date10.ValueAsFloat;
                    }
                    if (date != null)
                    {
                        day += (int)date.ValueAsFloat;
                    }

                    int txYear  = DateTime.Now.Year;
                    int txMonth = Int32.Parse(page.Parameters[1]);

                    if (txMonth > DateTime.Now.Month)                    // We got a form whose month (ex: 11) is greater than the current month (ex: 10), since we cannot scan in the future, it must be last year
                    {
                        txYear--;
                    }
                    Trace.TraceInformation("Using Date {0}-{1}-{2}", day, txMonth, txYear);
                    DateTime dateOfTx = new DateTime(txYear, txMonth, day);

                    // Register child weight
                    restUtil.Get <object>("ChildManagement.svc/RegisterChildWeight",
                                          new KeyValuePair <string, object>("childId", childId),
                                          new KeyValuePair <string, object>("date", dateOfTx.ToString("yyyy-MM-dd HH:mm:ss")),
                                          new KeyValuePair <string, object>("weight", weight),
                                          new KeyValuePair <string, object>("modifiedOn", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
                                          new KeyValuePair <string, object>("modifiedBy", 1)
                                          );

                    // Register child vaccinations
                    if (vaccines == null || vaccines.Value == "none")
                    {
                        Trace.TraceInformation(string.Format("Child {0}, {1} was not vaccinated", childData.Lastname1, childData.Firstname1));
                        if (Err == null)
                        {
                            Err = String.Empty;
                        }
                        Err += String.Format("Child {0}, {1} requires manual reconciliation - Not all vaccinations given; ", childData.Lastname1, childData.Firstname1);
                        continue;
                    }
                    else
                    {
                        // Get child's vaccination card
                        var izCard = restUtil.Get <List <GIIS.DataLayer.VaccinationEvent> >("VaccinationEvent.svc/GetImmunizationCard",
                                                                                            new KeyValuePair <string, object>("childId", childId),
                                                                                            new KeyValuePair <string, object>("scheduledDate", dateOfTx.ToString("yyyy-MM-dd HH:MM:ss"))
                                                                                            );
                        foreach (var vacc in izCard.Where(o => o.NonvaccinationReasonId == 0 && !o.VaccinationStatus && o.IsActive && (o.ScheduledDate.Month == txMonth || o.ScheduledDate.AddMonths(1).Month == txMonth) && o.ScheduledDate.Year == txYear))
                        {
                            var dose            = refDoses.Find(o => o.Id == vacc.DoseId);
                            var vaccine         = refVaccines.Find(o => o.Id == dose.ScheduledVaccinationId);
                            var item            = refItems.Find(o => o.Id == vaccine.ItemId);
                            var itemLot         = refItemLots.FindAll(o => o.ItemId == item.Id);
                            var facilityBalance = restUtil.Get <List <GIIS.DataLayer.HealthFacilityBalance> >("StockManagement.svc/GetCurrentStockByLot",
                                                                                                              new KeyValuePair <String, Object>("hfId", page.Parameters[0]));
                            var balance = facilityBalance.FindAll(o => itemLot.Exists(il => il.Gtin == o.Gtin && il.LotNumber == o.LotNumber)).OrderByDescending(p => p.Balance).FirstOrDefault();

                            if (balance == null)
                            {
                                Trace.TraceWarning("Facility has no balance for {0}! Can't determine vaccine lot / gtin", dose.Fullname);
                                Err += String.Format("Child {0} cannot receive immunization {1} because facility has no {1} in stock. Please update stock and retry", childId, dose.Fullname);
                            }

                            Trace.TraceInformation("Giving child {0} immunization {1} (stock GTIN: {2} LN {3})", childId, dose.Fullname, balance.Gtin, balance.LotNumber);
                            restUtil.Get <RestReturn>("VaccinationEvent.svc/UpdateVaccinationEvent",
                                                      new KeyValuePair <String, Object>("vaccineLotId", itemLot.Find(o => o.Gtin == balance.Gtin && o.LotNumber == balance.LotNumber).Id),
                                                      new KeyValuePair <String, Object>("healthFacilityId", page.Parameters[0]),
                                                      new KeyValuePair <String, Object>("vaccinationDate", dateOfTx.ToString("yyyy-MM-dd HH:mm:ss")),
                                                      new KeyValuePair <String, Object>("notes", "From Paper Register"),
                                                      new KeyValuePair <String, Object>("vaccinationStatus", true),
                                                      new KeyValuePair <String, Object>("userId", 1),
                                                      new KeyValuePair <String, Object>("vaccinationEventId", vacc.Id),
                                                      new KeyValuePair <String, Object>("outreach", outreach != null)
                                                      );

                            if (outreach != null)
                            {
                                Trace.TraceInformation("Updating appointment {0} to be outreach", vacc.AppointmentId);
                                restUtil.Get <RestReturn>("VaccinationAppointmentManagement.svc/UpdateVaccinationAppointment",
                                                          new KeyValuePair <String, Object>("childId", childId),
                                                          new KeyValuePair <String, Object>("vaccinationAppointmentId", vacc.AppointmentId),
                                                          new KeyValuePair <String, Object>("outreach", true),
                                                          new KeyValuePair <String, Object>("userId", 1),
                                                          new KeyValuePair <String, Object>("scheduledFacilityId", page.Parameters[0]),
                                                          new KeyValuePair <String, Object>("notes", "From Paper Form")
                                                          );
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Trace.TraceError(e.ToString());
                Err = e.Message;
            }
        }