Esempio n. 1
0
        public void CreateCaseSyncFileStart(Epi.ImportExport.Filters.RowFilters filters, Epi.RecordProcessingScope recordProcessingScope)
        {
            if (IsWaitingOnOtherClients)
            {
                return;
            }

            if (String.IsNullOrEmpty(SyncFilePath.Trim()))
            {
                throw new InvalidOperationException();
            }

            var stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();

            bool includeCases         = IncludeCasesAndContacts || IncludeCasesOnly;
            bool includeCaseExposures = true;
            bool includeContacts      = IncludeCasesAndContacts;
            bool deIdentifyData       = DeIdentifyData;

            #region Remove extraneous data

            int rows = 0;

            OverallSyncStatus = "Deleting extraneous page table rows...";
            IDbDriver db = _project.CollectedData.GetDatabase();

            foreach (View form in _project.Views)
            {
                foreach (Page page in form.Pages)
                {
                    Query deleteQuery = db.CreateQuery("DELETE FROM " + form.Name + " WHERE GlobalRecordId NOT IN (SELECT GlobalRecordId FROM " + page.TableName + ")");
                    rows = db.ExecuteNonQuery(deleteQuery);
                    if (rows > 0)
                    {
                        // report ??
                    }

                    Query pageDeleteQuery = db.CreateQuery("DELETE FROM " + page.TableName + " WHERE GlobalRecordId NOT IN (SELECT GlobalRecordId FROM " + form.Name + ")");
                    rows = db.ExecuteNonQuery(deleteQuery);
                    if (rows > 0)
                    {
                        // report ??
                    }
                }
            }

            Query linksDeleteQuery = db.CreateQuery("DELETE FROM metaLinks WHERE ToViewId = @ToViewId AND ToRecordGuid NOT IN (SELECT GlobalRecordId FROM " + ContactForm.TableName + ")");
            linksDeleteQuery.Parameters.Add(new QueryParameter("@ToViewId", DbType.Int32, ContactFormId));
            rows = db.ExecuteNonQuery(linksDeleteQuery);

            if (db.TableExists("metaHistory"))
            {
                Query historyDeleteQuery = db.CreateQuery("DELETE FROM metaHistory WHERE ContactGUID NOT IN (SELECT GlobalRecordId FROM " + ContactForm.TableName + ")");
                rows = db.ExecuteNonQuery(historyDeleteQuery);
            }

            #endregion // Remove extraneous data

            RecordsExported         = String.Empty;
            IsDataSyncing           = true;
            IsShowingExportProgress = true;

            var doc = new XmlDocument {
                XmlResolver = null
            };

            SendMessageForAwaitAll();

            Task.Factory.StartNew(
                () =>
            {
                doc = CreateCaseSyncFile(includeCases, includeCaseExposures, includeContacts, filters, deIdentifyData, recordProcessingScope);
            },
                System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default).ContinueWith(
                delegate
            {
                try
                {
                    if (!String.IsNullOrEmpty(doc.InnerText))
                    {
                        string compressedText = Epi.ImportExport.ImportExportHelper.Zip(doc.OuterXml);
                        compressedText        = "[[EPIINFO7_VHF_CASE_SYNC_FILE__0937]]" + compressedText;
                        Epi.Configuration.EncryptStringToFile(compressedText, SyncFilePath, "vQ@6L'<J3?)~5=vQnwh(2ic;>.<=dknF&/TZ4Uu!$78", "", "", 1000);
                    }
                }
                catch (Exception)
                {
                    // do nothing... if the XML is invalid, we should have already alerted the user in a different method
                }
                finally
                {
                    SendMessageForUnAwaitAll();
                }

                TaskbarProgressState = System.Windows.Shell.TaskbarItemProgressState.None;
                TaskbarProgressValue = 0;
                ProgressValue        = 0;

                IsDataSyncing = false;

                stopwatch.Stop();
                SyncStatus        = String.Empty;
                OverallSyncStatus = "Finished exporting data to sync file. Elapsed time: " + stopwatch.Elapsed.TotalMinutes.ToString("F1") + " minutes.";
            }, TaskScheduler.FromCurrentSynchronizationContext());
        }
Esempio n. 2
0
        private XmlDocument CreateCaseSyncFile(bool includeCases, bool includeCaseExposures, bool includeContacts, Epi.ImportExport.Filters.RowFilters filters, bool deIdentifyData, Epi.RecordProcessingScope recordProcessingScope)
        {
            TaskbarProgressValue = 0;
            TaskbarProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal;
            ProgressValue        = 0;

            _increment = 0.25;

            if (includeCaseExposures && includeContacts)
            {
                _increment = 0.25;
            }
            else if (includeCaseExposures && !includeContacts)
            {
                _increment = 0.34;
            }
            else if (!includeCaseExposures && !includeContacts)
            {
                _increment = 0.5;
            }

            IDbDriver database = _project.CollectedData.GetDatabase();

            //#region Repair page tables
            //RemoveExtraneousPageTableRecordsCommand.Execute(null);
            //#endregion // Repair page tables

            #region Case and Lab Data
            //var packager = new ContactTracing.ExportView.XmlSqlDataPackager(CaseForm, "sync") //new Epi.ImportExport.ProjectPackagers.XmlDataPackager(CaseForm, "sync")
            var packager = new Epi.ImportExport.ProjectPackagers.XmlDataPackager(CaseForm, "sync")
            {
                RecordProcessingScope = recordProcessingScope
            };

            packager.StatusChanged  += unpackager_StatusChanged;
            packager.UpdateProgress += unpackager_UpdateProgress;

            if (filters == null)
            {
                filters = new Epi.ImportExport.Filters.RowFilters(database, Epi.ImportExport.Filters.ConditionJoinTypes.And);
            }

            if (includeCases == false)
            {
                // filter out all cases
                var tfc = new Epi.ImportExport.TextRowFilterCondition("[EpiCaseDef] = @EpiCaseDef", "EpiCaseDef", "@EpiCaseDef", "1000")
                {
                    Description = "EpiCaseDef is equal to 1000"
                };
                filters.Add(tfc);
            }

            DateTime dateValue = DateTime.MinValue;

            DateTime today    = DateTime.Now;
            TimeSpan ts       = new TimeSpan(int.Parse(Days), 0, 0, 0);
            DateTime nDaysAgo = today - ts;
            dateValue = nDaysAgo;

            var daysAgoFilter = new Epi.ImportExport.DateRowFilterCondition("LastSaveTime >= @LastSaveTime", "LastSaveTime", "@LastSaveTime", dateValue);
            filters.Add(daysAgoFilter);

            packager.Filters = new Dictionary <string, Epi.ImportExport.Filters.RowFilters>
            {
                { "CaseInformationForm", filters }
            };

            if (deIdentifyData)
            {
                if (!IsCountryUS)
                {
                    packager.FieldsToNull.Add(CaseForm.Name, new List <string> {
                        "Surname", "OtherNames", "PhoneNumber", "PhoneOwner", "HeadHouse", "ContactName1", "ContactName2", "ContactName3", "FuneralName1", "FuneralName2", "HospitalBeforeIllPatient", "TradHealerName", "InterviewerName", "InterviewerPhone", "InterviwerEmail", "ProxyName"
                    });
                    packager.FieldsToNull.Add(LabForm.Name, new List <string> {
                        "SurnameLab", "OtherNameLab"
                    });
                }
                else
                {
                    packager.FieldsToNull.Add(CaseForm.Name, new List <string> {
                        "Surname", "OtherNames", "PhoneNumber", "PhoneOwner", "HeadHouse", "ContactName1", "ContactName2", "ContactName3", "FuneralName1", "FuneralName2", "HospitalBeforeIllPatient", "TradHealerName", "InterviewerName", "InterviewerPhone", "InterviwerEmail", "ProxyName", "DOB", "Email", "AddressRes", "AddressOnset", "ProxyPhone", "ProxyEmail"
                    });
                    packager.FieldsToNull.Add(LabForm.Name, new List <string> {
                        "SurnameLab", "OtherNameLab", "PersonLabSubmit", "PhoneLabSubmit", "EmailLabSubmit"
                    });
                }
            }
            packager.IncludeNullFieldData = false;

            var doc = new XmlDocument {
                XmlResolver = null
            };

            bool failed = false;

            try
            {
                OverallSyncStatus = "Packaging case records...";
                doc = packager.PackageForm();
                TaskbarProgressValue = TaskbarProgressValue + _increment;
                OverallSyncStatus    = "Finished packaging case records";

                if (packager.ExportInfo.RecordsPackaged.ContainsKey(LabForm))
                {
                    RecordsExported = "Exported: " + RecordsExported + packager.ExportInfo.RecordsPackaged[CaseForm].ToString() + " cases, " + packager.ExportInfo.RecordsPackaged[LabForm].ToString() + " lab results";
                }
                else
                {
                    RecordsExported = "Exported: " + RecordsExported + packager.ExportInfo.TotalRecordsPackaged.ToString() + " cases";
                }
            }
            catch (Exception ex)
            {
                if (SyncProblemsDetected != null)
                {
                    SyncProblemsDetected(ex, new EventArgs());
                }
                failed = true;
            }
            finally
            {
                packager.StatusChanged  -= unpackager_StatusChanged;
                packager.UpdateProgress -= unpackager_UpdateProgress;
            }

            if (failed)
            {
                return(doc);
            }
            #endregion // Case and Lab Data

            #region Contact Data
            if (includeContacts)
            {
                OverallSyncStatus = "Packaging contact records...";
                //packager = new ContactTracing.ExportView.XmlSqlDataPackager(ContactForm, "sync") //new Epi.ImportExport.ProjectPackagers.XmlSqlDataPackager(ContactForm, "sync");
                packager = new Epi.ImportExport.ProjectPackagers.XmlDataPackager(ContactForm, "sync")
                {
                    RecordProcessingScope = recordProcessingScope
                };

                packager.StatusChanged  += unpackager_StatusChanged;
                packager.UpdateProgress += unpackager_UpdateProgress;

                packager.RecordProcessingScope = recordProcessingScope;

                filters       = new Epi.ImportExport.Filters.RowFilters(database, Epi.ImportExport.Filters.ConditionJoinTypes.And);
                daysAgoFilter = new Epi.ImportExport.DateRowFilterCondition("LastSaveTime >= @LastSaveTime", "LastSaveTime", "@LastSaveTime", dateValue);
                filters.Add(daysAgoFilter);

                packager.Filters = new Dictionary <string, Epi.ImportExport.Filters.RowFilters>
                {
                    { ContactForm.Name, filters }
                };

                if (deIdentifyData)
                {
                    if (!IsCountryUS)
                    {
                        packager.FieldsToNull.Add(ContactForm.Name, new List <string> {
                            "ContactSurname", "ContactOtherNames", "ContactHeadHouse", "ContactPhone", "LC1"
                        });
                    }
                    else
                    {
                        packager.FieldsToNull.Add(ContactForm.Name, new List <string> {
                            "ContactSurname", "ContactOtherNames", "ContactHeadHouse", "ContactPhone", "LC1", "ContactDOB", "ContactAddress", "ContactEmail"
                        });
                    }
                }

                try
                {
                    XmlDocument contactDoc = packager.PackageForm();
                    RecordsExported = RecordsExported + ", " + packager.ExportInfo.TotalRecordsPackaged.ToString() + " contacts";
                    XmlNodeList xnList = contactDoc.SelectNodes("/DataPackage/Form");
                    if (IsCountryUS)
                    {
                        foreach (XmlNode node in contactDoc.GetElementsByTagName("FieldInfo"))
                        {
                            if (node.Attributes[0].Value == "AdminOverride")
                            {
                                node.ParentNode.RemoveChild(node);
                                break;
                            }
                        }
                    }

                    if (xnList.Count == 1)
                    {
                        XmlNode nodeToCopy = doc.ImportNode(contactDoc.SelectSingleNode("/DataPackage/Form"), true); // note: target
                        XmlNode parentNode = doc.SelectSingleNode("/DataPackage");
                        parentNode.AppendChild(nodeToCopy);

                        //doc.Save(@"C:\Temp\ContactTest.xml");
                    }
                }
                catch (Exception ex)
                {
                    //if (SyncProblemsDetected != null)
                    //{
                    //    SyncProblemsDetected(ex, new EventArgs());
                    //}
                    // TODO: Re-work this
                }
                finally
                {
                    packager.StatusChanged  -= unpackager_StatusChanged;
                    packager.UpdateProgress -= unpackager_UpdateProgress;
                }
            }
            TaskbarProgressValue = TaskbarProgressValue + _increment;
            OverallSyncStatus    = "Finished packaging contact records";
            #endregion // Contact Data

            #region Link Data

            if (includeCaseExposures || includeContacts)
            {
                OverallSyncStatus = "Packaging relationship records...";
                #region metaLinks table
                XmlElement links = doc.CreateElement("Links");

                Query     selectQuery = database.CreateQuery("SELECT * FROM [metaLinks] ORDER BY [LastContactDate] DESC");
                DataTable linksTable  = database.Select(selectQuery);

                foreach (DataRow row in linksTable.Rows)
                {
                    XmlElement link = doc.CreateElement("Link");

                    var toViewId   = (int)row["ToViewId"];
                    var fromViewId = (int)row["FromViewId"];

                    if (includeCaseExposures && toViewId == CaseFormId && fromViewId == CaseFormId)
                    {
                        // we have a case-to-case link, add it

                        foreach (DataColumn dc in linksTable.Columns)
                        {
                            XmlElement element = doc.CreateElement(dc.ColumnName);
                            if (row[dc] != DBNull.Value)
                            {
                                if (row[dc] is DateTime || dc.ColumnName.Equals("LastContactDate", StringComparison.OrdinalIgnoreCase))
                                {
                                    var dt = (DateTime)row[dc];
                                    element.InnerText = dt.Ticks.ToString();
                                }
                                else
                                {
                                    element.InnerText = row[dc].ToString();
                                }
                            }
                            else
                            {
                                element.InnerText = String.Empty;
                            }

                            //if (!String.IsNullOrEmpty(element.InnerText) || !element.Name.StartsWith("Day", StringComparison.OrdinalIgnoreCase))
                            //{
                            link.AppendChild(element);
                            //}
                        }
                    }

                    if (includeContacts && toViewId == ContactFormId && fromViewId == CaseFormId)
                    {
                        // we have a case-to-contact link, add it
                        foreach (DataColumn dc in linksTable.Columns)
                        {
                            XmlElement element = doc.CreateElement(dc.ColumnName);
                            if (row[dc] != DBNull.Value)
                            {
                                if (row[dc] is DateTime || dc.ColumnName.Equals("LastContactDate", StringComparison.OrdinalIgnoreCase))
                                {
                                    var dt = (DateTime)row[dc];
                                    element.InnerText = dt.Ticks.ToString();
                                }
                                else
                                {
                                    element.InnerText = row[dc].ToString();
                                }
                            }
                            else
                            {
                                element.InnerText = String.Empty;
                            }
                            //if (!String.IsNullOrEmpty(element.InnerText) || !element.Name.StartsWith("Day", StringComparison.OrdinalIgnoreCase))
                            //{
                            link.AppendChild(element);
                            //}
                        }
                    }

                    links.AppendChild(link);
                }

                doc.ChildNodes[0].AppendChild(links);
                #endregion // metaLinks table
                TaskbarProgressValue = TaskbarProgressValue + _increment;
                RecordsExported      = RecordsExported + ", " + linksTable.Rows.Count.ToString() + " relationships";

                if (includeContacts)
                {
                    if (database.TableExists("metaHistory"))
                    {
                        OverallSyncStatus = "Packaging daily follow-up records...";
                        #region metaHistory table
                        XmlElement followUps = doc.CreateElement("ContactFollowUps");

                        selectQuery = database.CreateQuery("SELECT * FROM [metaHistory] ORDER BY [ContactGUID] DESC, [FollowUpDate] DESC");
                        DataTable followUpsTable = database.Select(selectQuery);

                        foreach (DataRow row in followUpsTable.Rows)
                        {
                            XmlElement followUp = doc.CreateElement("ContactFollowUp");

                            XmlElement guid = doc.CreateElement("ContactGUID");
                            guid.InnerText = row["ContactGUID"].ToString();
                            followUp.AppendChild(guid);

                            CultureInfo format = CultureInfo.InvariantCulture;

                            XmlElement fuDate = doc.CreateElement("FollowUpDate");
                            fuDate.InnerText = Convert.ToDateTime(row["FollowUpDate"]).ToString(format.DateTimeFormat.ShortDatePattern);
                            followUp.AppendChild(fuDate);

                            XmlElement statusOnDate = doc.CreateElement("StatusOnDate");
                            statusOnDate.InnerText = row["StatusOnDate"].ToString();
                            followUp.AppendChild(statusOnDate);

                            XmlElement note = doc.CreateElement("Note");
                            note.InnerText = row["Note"].ToString();
                            followUp.AppendChild(note);

                            if (row.Table.Columns.Contains("Temp1"))
                            {
                                XmlElement temp1 = doc.CreateElement("Temp1");
                                if (row["Temp1"] != DBNull.Value)
                                {
                                    temp1.InnerText = Convert.ToDouble(row["Temp1"]).ToString(System.Globalization.CultureInfo.InvariantCulture);
                                }
                                followUp.AppendChild(temp1);

                                XmlElement temp2 = doc.CreateElement("Temp2");
                                if (row["Temp2"] != DBNull.Value)
                                {
                                    temp2.InnerText = Convert.ToDouble(row["Temp2"]).ToString(System.Globalization.CultureInfo.InvariantCulture);
                                }
                                followUp.AppendChild(temp2);
                            }

                            followUps.AppendChild(followUp);
                        }
                        #endregion // metaHistory table

                        doc.ChildNodes[0].AppendChild(followUps);
                        TaskbarProgressValue = TaskbarProgressValue + _increment;
                        RecordsExported      = RecordsExported + ", " + followUpsTable.Rows.Count.ToString() + " follow-ups";
                    }
                }
            }
            #endregion // Link Data

            return(doc);
        }