public static Letter.FileContents Run(SendMethod sendMethod, int siteID, int staffID, int registerReferrerID, bool incBatching, bool incUnsent, bool viewListOnly, bool viewFullList, out string outputInfo, out string outputList, string btnViewListClientID)
    {
        RndPageID = (new Random()).Next().ToString();

        bool debugMode = true;

        string tmpLettersDirectory = Letter.GetTempLettersDirectory();

        if (!Directory.Exists(tmpLettersDirectory))
        {
            throw new CustomMessageException("Temp letters directory doesn't exist");
        }


        int    startTime = 0;
        double queryExecutionTimeClinic = 0;
        double generateFilesToPrintExecutionTimeClinic = 0;
        double queryExecutionTimeAgedCare = 0;
        double generateFilesToPrintExecutionTimeAgedCare = 0;

        outputInfo = string.Empty;
        outputList = string.Empty;


        //
        //  We can not send email all their patients in one email - will be too big with attachments and rejected by their mail provider
        //  So if via email - need to send one at a time
        //  Then if cuts out or times out, it has processed some so don't need to re-process those when it's run again
        //
        //  remember to process the emails first ... so if any interruptions/errors ... at least some will have been processed
        //


        Site[] allSites    = SiteDB.GetAll();
        bool   runAllSites = siteID == -1;

        Site agedCareSite = null;
        Site clinicSite   = null;

        Site[] sitesToRun = runAllSites ? allSites : new Site[] { SiteDB.GetByID(siteID) };
        foreach (Site s in sitesToRun)
        {
            if (s.SiteType.ID == 1)
            {
                clinicSite = s;
            }
            else if (s.SiteType.ID == 2)
            {
                agedCareSite = s;
            }
        }


        ArrayList filesToPrintClinic   = new ArrayList();
        ArrayList filesToPrintAgedCare = new ArrayList();
        string    debugOutput          = string.Empty;
        int       numGenerated         = 0;

        DataTable bookingsWithUnsetnLettersClinic   = null;
        DataTable bookingsWithUnsetnLettersAgedCare = null;

        if (clinicSite != null)
        {
            startTime = Environment.TickCount;

            bookingsWithUnsetnLettersClinic = BookingDB.GetBookingsWithEPCLetters(DateTime.MinValue, DateTime.MinValue, registerReferrerID, -1, false, true, incBatching, incUnsent);

            queryExecutionTimeClinic = (double)(Environment.TickCount - startTime) / 1000.0;
            startTime = Environment.TickCount;


            int       currentRegReferrerID       = -1;
            ArrayList bookingsForCurrentReferrer = new ArrayList();
            foreach (DataRow row in bookingsWithUnsetnLettersClinic.Rows)
            {
                numGenerated++;

                //if (numGenerated % 15 != 1) continue;
                if ((!viewListOnly || !viewFullList) && (numGenerated > MaxSending))
                {
                    continue;
                }

                Tuple <Booking, PatientReferrer, bool, string, string, HealthCard> rowData = LoadClinicRow(row);
                Booking         booking     = rowData.Item1;
                PatientReferrer pr          = rowData.Item2;
                bool            refHasEmail = rowData.Item3;
                string          refEmail    = rowData.Item4;
                string          refFax      = rowData.Item5;
                HealthCard      hc          = rowData.Item6;


                //if (booking.Patient == null || (booking.Patient.PatientID != 31522 && booking.Patient.PatientID != 27654))
                //{
                //    numGenerated--;
                //    continue;
                //}



                if (pr.RegisterReferrer.RegisterReferrerID != currentRegReferrerID)
                {
                    filesToPrintClinic.AddRange(ProcessReferrersClinicLetters(sendMethod, viewListOnly, clinicSite, staffID, bookingsForCurrentReferrer, ref debugOutput, btnViewListClientID));
                    currentRegReferrerID       = pr.RegisterReferrer.RegisterReferrerID;
                    bookingsForCurrentReferrer = new ArrayList();
                }

                bookingsForCurrentReferrer.Add(rowData);
            }

            // process last group
            filesToPrintClinic.AddRange(ProcessReferrersClinicLetters(sendMethod, viewListOnly, clinicSite, staffID, bookingsForCurrentReferrer, ref debugOutput, btnViewListClientID));

            generateFilesToPrintExecutionTimeClinic = (double)(Environment.TickCount - startTime) / 1000.0;
        }
        if (agedCareSite != null)
        {
            startTime = Environment.TickCount;

            bookingsWithUnsetnLettersAgedCare = BookingPatientDB.GetBookingsPatientOfferingsWithEPCLetters(DateTime.MinValue, DateTime.MinValue, registerReferrerID, -1, false, true, incBatching, incUnsent);

            queryExecutionTimeAgedCare = (double)(Environment.TickCount - startTime) / 1000.0;
            startTime = Environment.TickCount;


            int       currentRegReferrerID       = -1;
            ArrayList bookingsForCurrentReferrer = new ArrayList();
            foreach (DataRow row in bookingsWithUnsetnLettersAgedCare.Rows)
            {
                numGenerated++;
                //if (numGenerated % 15 != 1) continue;
                if ((!viewListOnly || !viewFullList) && (numGenerated > MaxSending))
                {
                    continue;
                }
                Tuple <BookingPatient, Offering, PatientReferrer, bool, string, string, HealthCard> rowData = LoadAgedCareRow(row);
                BookingPatient  bp          = rowData.Item1;
                Offering        offering    = rowData.Item2;
                PatientReferrer pr          = rowData.Item3;
                bool            refHasEmail = rowData.Item4;
                string          refEmail    = rowData.Item5;
                string          refFax      = rowData.Item6;
                HealthCard      hc          = rowData.Item7;

                //if (bp.Booking.Patient == null || (bp.Booking.Patient.PatientID != 31522 && bp.Booking.Patient.PatientID != 27654))
                //{
                //    numGenerated--;
                //    continue;
                //}

                if (pr.RegisterReferrer.RegisterReferrerID != currentRegReferrerID)
                {
                    filesToPrintAgedCare.AddRange(ProcessReferrersAgedCareLetters(sendMethod, viewListOnly, agedCareSite, staffID, bookingsForCurrentReferrer, ref debugOutput, btnViewListClientID));
                    currentRegReferrerID       = pr.RegisterReferrer.RegisterReferrerID;
                    bookingsForCurrentReferrer = new ArrayList();
                }

                bookingsForCurrentReferrer.Add(rowData);
            }

            // process last group
            filesToPrintAgedCare.AddRange(ProcessReferrersAgedCareLetters(sendMethod, viewListOnly, agedCareSite, staffID, bookingsForCurrentReferrer, ref debugOutput, btnViewListClientID));

            generateFilesToPrintExecutionTimeAgedCare = (double)(Environment.TickCount - startTime) / 1000.0;
        }

        startTime = Environment.TickCount;


        bool zipSeperately = true;

        Letter.FileContents zipFileContents = null;

        if (zipSeperately && (filesToPrintClinic.Count + filesToPrintAgedCare.Count) > 0)
        {
            // if 2 sites exist in the system - change doc names to have "[AgedCare]" or "[Clinics]" before docname
            if (allSites.Length > 1)
            {
                for (int i = 0; i < filesToPrintClinic.Count; i++)
                {
                    ((Letter.FileContents)filesToPrintClinic[i]).DocName = "[Clinics] " + ((Letter.FileContents)filesToPrintClinic[i]).DocName;
                }
                for (int i = 0; i < filesToPrintAgedCare.Count; i++)
                {
                    ((Letter.FileContents)filesToPrintAgedCare[i]).DocName = "[AgedCare] " + ((Letter.FileContents)filesToPrintAgedCare[i]).DocName;
                }
            }

            ArrayList filesToPrint = new ArrayList();
            filesToPrint.AddRange(filesToPrintClinic);
            filesToPrint.AddRange(filesToPrintAgedCare);



            // seperate into doc types because can only merge docs with docs of same template (ie docname)
            Hashtable filesToPrintHash = new Hashtable();
            for (int i = 0; i < filesToPrint.Count; i++)
            {
                Letter.FileContents curFileContents = (Letter.FileContents)filesToPrint[i];
                if (filesToPrintHash[curFileContents.DocName] == null)
                {
                    filesToPrintHash[curFileContents.DocName] = new ArrayList();
                }
                ((ArrayList)filesToPrintHash[curFileContents.DocName]).Add(curFileContents);
            }

            // merge and put merged files into temp dir
            string baseTmpDir = FileHelper.GetTempDirectoryName(tmpLettersDirectory);
            string tmpDir     = baseTmpDir + "Referral Letters" + @"\";
            Directory.CreateDirectory(tmpDir);
            string[] tmpFiles = new string[filesToPrintHash.Keys.Count];
            IDictionaryEnumerator enumerator = filesToPrintHash.GetEnumerator();
            for (int i = 0; enumerator.MoveNext(); i++)
            {
                ArrayList files   = (ArrayList)enumerator.Value;
                string    docName = (string)enumerator.Key;


                // last file is screwing up, so just re-add the last file again for a temp fix
                files.Add(files[files.Count - 1]);


                Letter.FileContents fileContents = Letter.FileContents.Merge((Letter.FileContents[])files.ToArray(typeof(Letter.FileContents)), docName); // .pdf

                string tmpFileName = tmpDir + fileContents.DocName;
                System.IO.File.WriteAllBytes(tmpFileName, fileContents.Contents);
                tmpFiles[i] = tmpFileName;
            }

            // zip em
            string zipFileName = "Referral Letters.zip";
            string zipFilePath = baseTmpDir + zipFileName;
            ICSharpCode.SharpZipLib.Zip.FastZip zip = new ICSharpCode.SharpZipLib.Zip.FastZip();
            zip.CreateEmptyDirectories = true;
            zip.CreateZip(zipFilePath, tmpDir, true, "");

            // get filecontents of zip here
            zipFileContents = new Letter.FileContents(zipFilePath, zipFileName);
            //Letter.FileContents zipFileContents = new Letter.FileContents(zipFilePath, zipFileName);
            //System.Web.HttpContext.Current.Session["downloadFile_Contents"] = zipFileContents.Contents;
            //System.Web.HttpContext.Current.Session["downloadFile_DocName"]  = zipFileContents.DocName;

            // delete files
            for (int i = 0; i < tmpFiles.Length; i++)
            {
                System.IO.File.SetAttributes(tmpFiles[i], FileAttributes.Normal);
                System.IO.File.Delete(tmpFiles[i]);
            }
            System.IO.File.SetAttributes(zipFilePath, FileAttributes.Normal);
            System.IO.File.Delete(zipFilePath);
            System.IO.Directory.Delete(tmpDir, false);
            System.IO.Directory.Delete(baseTmpDir, false);

            // put in session variables so when it reloads to this page, we can popup the download window
            //Page.ClientScript.RegisterStartupScript(this.GetType(), "download", "<script language=javascript>window.open('DownloadFile.aspx','_blank','status=1,toolbar=0,menubar=0,location=1,scrollbars=1,resizable=1,width=30,height=30');</script>");
        }

        if (!zipSeperately && (filesToPrintClinic.Count + filesToPrintAgedCare.Count) > 0)
        {
            ArrayList filesToPrint = new ArrayList();
            filesToPrint.AddRange(filesToPrintClinic);
            filesToPrint.AddRange(filesToPrintAgedCare);

            zipFileContents = Letter.FileContents.Merge((Letter.FileContents[])filesToPrint.ToArray(typeof(Letter.FileContents)), "Referral Letters.doc"); // .pdf
            //Letter.FileContents fileContents = Letter.FileContents.Merge((Letter.FileContents[])filesToPrint.ToArray(typeof(Letter.FileContents)), "Referral Letters.doc"); // .pdf
            //System.Web.HttpContext.Current.Session["downloadFile_Contents"] = fileContents.Contents;
            //System.Web.HttpContext.Current.Session["downloadFile_DocName"]  = fileContents.DocName;

            // put in session variables so when it reloads to this page, we can popup the download window
            //Page.ClientScript.RegisterStartupScript(this.GetType(), "download", "<script language=javascript>window.open('DownloadFile.aspx','_blank','status=1,toolbar=0,menubar=0,location=1,scrollbars=1,resizable=1,width=30,height=30');</script>");
        }


        if (!viewListOnly && registerReferrerID == -1 && incBatching)
        {
            SetLastDateBatchSendTreatmentNotesAllReferrers(DateTime.Now);
        }


        double restExecutionTime = (double)(Environment.TickCount - startTime) / 1000.0;

        if (debugMode)
        {
            int    total         = (bookingsWithUnsetnLettersClinic == null ? 0 : bookingsWithUnsetnLettersClinic.Rows.Count) + (bookingsWithUnsetnLettersAgedCare == null ? 0 : bookingsWithUnsetnLettersAgedCare.Rows.Count);
            string countGenrated = total > MaxSending ? MaxSending + " of " + total + " generated" : total.ToString() + " generated";
            string countShowing  = total > MaxSending ? MaxSending + " of " + total + " showing to generate. <br />* If there are more than " + MaxSending + ", the next " + MaxSending + " will have to be generated seperately after this." : total.ToString();
            if (total > MaxSending && viewFullList)
            {
                countShowing = total + " showing to generate. <br />* If there are more than " + MaxSending + ", only the first " + MaxSending + " will be generated and batches of " + MaxSending + " will have to be generated seperately after.";
            }

            string queryExecutionTimeText = string.Empty;
            if (agedCareSite == null && clinicSite == null)
            {
                queryExecutionTimeText = "0";
            }
            if (agedCareSite == null && clinicSite != null)
            {
                queryExecutionTimeText = queryExecutionTimeClinic.ToString();
            }
            if (agedCareSite != null && clinicSite == null)
            {
                queryExecutionTimeText = queryExecutionTimeAgedCare.ToString();
            }
            if (agedCareSite != null && clinicSite != null)
            {
                queryExecutionTimeText = "[Clinics: " + queryExecutionTimeClinic + "] [AgedCare: " + queryExecutionTimeAgedCare + "]";
            }

            string restExecutionTimeText = string.Empty;
            if (agedCareSite == null && clinicSite == null)
            {
                restExecutionTimeText = "0";
            }
            if (agedCareSite == null && clinicSite != null)
            {
                restExecutionTimeText = (generateFilesToPrintExecutionTimeClinic + restExecutionTime).ToString();
            }
            if (agedCareSite != null && clinicSite == null)
            {
                restExecutionTimeText = (generateFilesToPrintExecutionTimeAgedCare + restExecutionTime).ToString();
            }
            if (agedCareSite != null && clinicSite != null)
            {
                restExecutionTimeText = "[Clinics: " + generateFilesToPrintExecutionTimeClinic + "] [AgedCare: " + generateFilesToPrintExecutionTimeAgedCare + "] [Merging" + restExecutionTime + "]";
            }

            if (!viewListOnly)
            {
                outputInfo = @"<table cellpadding=""0"">
                                <tr><td><b>Send Method</b></td><td style=""width:10px;""></td><td>" + sendMethod.ToString() + @"</td><td style=""width:25px;""></td><td><b>Query Time</b></td><td style=""width:10px;""></td><td>" + queryExecutionTimeText + @" seconds</td></tr>
                                <tr><td><b>Count</b></td><td style=""width:10px;""></td><td>" + countGenrated + @"</td><td style=""width:25px;""></td><td><b>Runing Time</b></td><td style=""width:10px;""></td><td>" + restExecutionTimeText + @" seconds</td></tr>
                                </table>";
            }

            if (viewListOnly)
            {
                outputInfo = @"<table cellpadding=""0"">
                                <tr><td valign=""top""><b>Count</b></td><td style=""width:10px;""></td><td>" + countShowing + @"</td></tr>
                                </table>";
            }

            if (viewListOnly)
            {
                outputList = @"<table class=""table table-bordered table-striped table-grid table-grid-top-bottum-padding-thick auto_width block_center"" border=""1"">
                                    <tr>
                                        <th>Site</th>
                                        <th>Send By</th>
                                        <th>Booking</th>
                                        <th>Generate</th>
                                        <th>Referrer</th>
                                        <th>Email</th>
                                        <th>Fax</th>
                                        <th>Update Email/Fax</th>
                                        <th>Patient</th>
                                    </tr>" +
                             (debugOutput.Length == 0 ? "<tr><td colspan=\"6\">No Rows</td></tr>" : debugOutput) +
                             "</table>";
            }
        }

        return(zipFileContents);
    }
Beispiel #2
0
    protected void Run(bool viewListOnly)
    {
        try
        {
            if (SelectedSendMethod == SendMethod.None)
            {
                throw new CustomMessageException("Send method not selected");
            }


            int staffID = Session != null && Session["StaffID"] != null?Convert.ToInt32(Session["StaffID"]) : -1;

            int siteID = -1;

            if (!chkIncClinics.Checked && !chkIncAgedCare.Checked)
            {
                throw new CustomMessageException("Plese check to generate for Clinics and/or Aged Care");
            }
            else if (chkIncClinics.Checked && chkIncAgedCare.Checked)
            {
                siteID = -1;
            }
            else if (chkIncClinics.Checked)
            {
                foreach (Site s in SiteDB.GetAll())
                {
                    if (s.SiteType.ID == 1)
                    {
                        siteID = s.SiteID;
                    }
                }
            }
            else if (chkIncAgedCare.Checked)
            {
                foreach (Site s in SiteDB.GetAll())
                {
                    if (s.SiteType.ID == 2)
                    {
                        siteID = s.SiteID;
                    }
                }
            }



            /*
             * // if called by automated settings there will be no session setting for SiteID or StaffID
             * // but siteID is needed to know which letter template to use for generation
             * if (siteID == null)
             * {
             *  Site[] sites = SiteDB.GetAll();
             *  siteID = (sites.Length == 1) ? sites[0].SiteID : sites[sites.Length - 1].SiteID; // if one site, use that -- else choose last one since clinics site developed first and exists
             * }
             */


            string outputInfo;
            string outputList;

            Letter.FileContents fileContents = ReferrerEPCLettersSendingV2.Run(
                SelectedSendMethod == SendMethod.Email ? ReferrerEPCLettersSendingV2.SendMethod.Email_To_Referrer : ReferrerEPCLettersSendingV2.SendMethod.Batch,
                siteID,
                staffID,
                Convert.ToInt32(registerReferrerID.Value),
                chkIncBatching.Checked,
                chkIncUnsent.Checked,
                chkIncWithEmailOrFaxOnly.Checked,
                viewListOnly,
                chkShowFullList.Checked,
                out outputInfo,
                out outputList,
                btnViewList.ClientID
                );

            lblInfo.Text = outputInfo;
            lblList.Text = outputList;

            if (fileContents != null)
            {
                System.Web.HttpContext.Current.Session["downloadFile_Contents"] = fileContents.Contents;
                System.Web.HttpContext.Current.Session["downloadFile_DocName"]  = fileContents.DocName;

                // put in session variables so when it reloads to this page, we can popup the download window
                Page.ClientScript.RegisterStartupScript(this.GetType(), "download", "<script language=javascript>window.open('DownloadFile.aspx','_blank','status=1,toolbar=0,menubar=0,location=1,scrollbars=1,resizable=1,width=30,height=30');</script>");
            }
        }
        catch (CustomMessageException cmEx)
        {
            SetErrorMessage(cmEx.Message);
        }
        catch (Exception ex)
        {
            SetErrorMessage("", ex.ToString());
        }

        return;



        bool debugMode = true;


        //
        //  We can not send email all their patients in one email - will be too big with attachments and rejected by their mail provider
        //  So if via email - need to send one at a time
        //  Then if cuts out or times out, it has processed some so don't need to re-process those when it's run again
        //
        //  remember to process the emails first ... so if any interruptions/errors ... at least some will have been processed
        //



        try
        {
            string sendMethod = rdioSendType.SelectedValue;
            if (!viewListOnly && SelectedSendMethod == SendMethod.None)
            {
                throw new CustomMessageException("Send method not selected");
            }

            string tmpLettersDirectory = Letter.GetTempLettersDirectory();
            if (!Directory.Exists(tmpLettersDirectory))
            {
                throw new CustomMessageException("Temp letters directory doesn't exist");
            }


            string debugOutput = string.Empty;
            int    startTime   = Environment.TickCount;

            DataTable bookingsWithUnsetnLetters = BookingDB.GetBookingsWithEPCLetters(DateTime.MinValue, DateTime.MinValue, Convert.ToInt32(registerReferrerID.Value), -1, false, true, chkIncBatching.Checked, chkIncUnsent.Checked);

            double queryExecutionTime = (double)(Environment.TickCount - startTime) / 1000.0;
            startTime = Environment.TickCount;

            ArrayList filesToPrint = new ArrayList();

            int       c = 0;
            int       currentRegReferrerID       = -1;
            ArrayList bookingsForCurrentReferrer = new ArrayList();
            foreach (DataRow row in bookingsWithUnsetnLetters.Rows)
            {
                //c++; if (c % 15 != 1) continue;
                if (c > ReferrerEPCLettersSendingV2.MaxSending)
                {
                    continue;
                }
                Tuple <Booking, PatientReferrer, bool, string, HealthCard> rowData = LoadRow(row);
                Booking         booking     = rowData.Item1;
                PatientReferrer pr          = rowData.Item2;
                bool            refHasEmail = rowData.Item3;
                string          refEmail    = rowData.Item4;
                HealthCard      hc          = rowData.Item5;


                if (pr.RegisterReferrer.RegisterReferrerID != currentRegReferrerID)
                {
                    filesToPrint.AddRange(ProcessReferrersLetters(viewListOnly, bookingsForCurrentReferrer, ref debugOutput));
                    currentRegReferrerID       = pr.RegisterReferrer.RegisterReferrerID;
                    bookingsForCurrentReferrer = new ArrayList();
                }

                bookingsForCurrentReferrer.Add(rowData);
            }

            // process last group
            filesToPrint.AddRange(ProcessReferrersLetters(viewListOnly, bookingsForCurrentReferrer, ref debugOutput));



            bool zipSeperately = true;

            if (zipSeperately && filesToPrint.Count > 0)
            {
                // seperate into doc types because can only merge docs with docs of same template (ie docname)
                Hashtable filesToPrintHash = new Hashtable();
                for (int i = 0; i < filesToPrint.Count; i++)
                {
                    Letter.FileContents curFileContents = (Letter.FileContents)filesToPrint[i];
                    if (filesToPrintHash[curFileContents.DocName] == null)
                    {
                        filesToPrintHash[curFileContents.DocName] = new ArrayList();
                    }
                    ((ArrayList)filesToPrintHash[curFileContents.DocName]).Add(curFileContents);
                }

                // merge and put merged files into temp dir
                string baseTmpDir = FileHelper.GetTempDirectoryName(tmpLettersDirectory);
                string tmpDir     = baseTmpDir + "EPC Letters" + @"\";
                Directory.CreateDirectory(tmpDir);
                string[] tmpFiles = new string[filesToPrintHash.Keys.Count];
                IDictionaryEnumerator enumerator = filesToPrintHash.GetEnumerator();
                for (int i = 0; enumerator.MoveNext(); i++)
                {
                    ArrayList files   = (ArrayList)enumerator.Value;
                    string    docName = (string)enumerator.Key;


                    // last file is screwing up, so just re-add the last file again for a temp fix
                    files.Add(files[files.Count - 1]);


                    Letter.FileContents fileContents = Letter.FileContents.Merge((Letter.FileContents[])files.ToArray(typeof(Letter.FileContents)), docName); // .pdf

                    string tmpFileName = tmpDir + fileContents.DocName;
                    System.IO.File.WriteAllBytes(tmpFileName, fileContents.Contents);
                    tmpFiles[i] = tmpFileName;
                }

                // zip em
                string zipFileName = "EPC Letters.zip";
                string zipFilePath = baseTmpDir + zipFileName;
                ICSharpCode.SharpZipLib.Zip.FastZip zip = new ICSharpCode.SharpZipLib.Zip.FastZip();
                zip.CreateEmptyDirectories = true;
                zip.CreateZip(zipFilePath, tmpDir, true, "");

                // get filecontents of zip here
                Letter.FileContents zipFileContents = new Letter.FileContents(zipFilePath, zipFileName);
                Session["downloadFile_Contents"] = zipFileContents.Contents;
                Session["downloadFile_DocName"]  = zipFileContents.DocName;

                // delete files
                for (int i = 0; i < tmpFiles.Length; i++)
                {
                    System.IO.File.SetAttributes(tmpFiles[i], FileAttributes.Normal);
                    System.IO.File.Delete(tmpFiles[i]);
                }
                System.IO.File.SetAttributes(zipFilePath, FileAttributes.Normal);
                System.IO.File.Delete(zipFilePath);
                System.IO.Directory.Delete(tmpDir, false);
                System.IO.Directory.Delete(baseTmpDir, false);

                // put in session variables so when it reloads to this page, we can popup the download window
                Page.ClientScript.RegisterStartupScript(this.GetType(), "download", "<script language=javascript>window.open('DownloadFile.aspx','_blank','status=1,toolbar=0,menubar=0,location=1,scrollbars=1,resizable=1,width=30,height=30');</script>");
            }

            if (!zipSeperately && filesToPrint.Count > 0)
            {
                Letter.FileContents fileContents = Letter.FileContents.Merge((Letter.FileContents[])filesToPrint.ToArray(typeof(Letter.FileContents)), "Referral Letters.doc"); // .pdf
                Session["downloadFile_Contents"] = fileContents.Contents;
                Session["downloadFile_DocName"]  = fileContents.DocName;

                // put in session variables so when it reloads to this page, we can popup the download window
                Page.ClientScript.RegisterStartupScript(this.GetType(), "download", "<script language=javascript>window.open('DownloadFile.aspx','_blank','status=1,toolbar=0,menubar=0,location=1,scrollbars=1,resizable=1,width=30,height=30');</script>");
            }


            if (!viewListOnly && Convert.ToInt32(registerReferrerID.Value) == -1 && chkIncBatching.Checked)
            {
                SetLastDateBatchSendTreatmentNotesAllReferrers(DateTime.Now);
            }


            double restExecutionTime = (double)(Environment.TickCount - startTime) / 1000.0;

            if (debugMode)
            {
                string countGenrated = bookingsWithUnsetnLetters.Rows.Count > ReferrerEPCLettersSendingV2.MaxSending ? ReferrerEPCLettersSendingV2.MaxSending + " of " + bookingsWithUnsetnLetters.Rows.Count + " generated" : bookingsWithUnsetnLetters.Rows.Count.ToString() + " generated";
                string countShowing  = bookingsWithUnsetnLetters.Rows.Count > ReferrerEPCLettersSendingV2.MaxSending ? ReferrerEPCLettersSendingV2.MaxSending + " of " + bookingsWithUnsetnLetters.Rows.Count + " showing to generate. <br />* If there are more than " + ReferrerEPCLettersSendingV2.MaxSending + ", the next " + ReferrerEPCLettersSendingV2.MaxSending + " will have to be generated seperately after this." : bookingsWithUnsetnLetters.Rows.Count.ToString();

                if (!viewListOnly)
                {
                    lblInfo.Text = @"<table cellpadding=""0"">
                                    <tr><td><b>Send Method</b></td><td style=""width:10px;""></td><td>" + SelectedSendMethod.ToString() + @"</td><td style=""width:25px;""></td><td><b>Query Time</b></td><td style=""width:10px;""></td><td>" + queryExecutionTime + @" seconds</td></tr>
                                    <tr><td><b>Count</b></td><td style=""width:10px;""></td><td>" + countGenrated + @"</td><td style=""width:25px;""></td><td><b>Runing Time</b></td><td style=""width:10px;""></td><td>" + restExecutionTime + @" seconds</td></tr>
                                 </table>" + "<br />";
                }

                if (viewListOnly)
                {
                    lblInfo.Text = @"<table cellpadding=""0"">
                                    <tr><td valign=""top""><b>Count</b></td><td style=""width:10px;""></td><td>" + countShowing + @"</td></tr>
                                 </table>" + "<br />";
                }

                if (viewListOnly)
                {
                    lblList.Text = @"<table class=""table table-bordered table-striped table-grid table-grid-top-bottum-padding-thick auto_width block_center"" border=""1"">
                                        <tr>
                                            <th>Send By</th>
                                            <th>Booking</th>
                                            <th>Generate</th>
                                            <th>Referrer</th>
                                            <th>Email</th>
                                            <th>Patient</th>
                                        </tr>" +
                                   (debugOutput.Length == 0 ? "<tr><td colspan=\"6\">No Rows</td></tr>" : debugOutput) +
                                   "</table>";
                }
            }
        }
        catch (CustomMessageException cmEx)
        {
            SetErrorMessage(cmEx.Message);
        }
        catch (Exception ex)
        {
            SetErrorMessage(ex.ToString());
        }
    }
    protected void Run(bool viewListOnly)
    {
        bool debugMode = true;

        int bulkLetterSendingQueueBatchID = !viewListOnly && UseBulkLetterSender?BulkLetterSendingQueueBatchDB.Insert(DebugEmail, false) : -1;

        //
        //  We can not send email all their patients in one email - will be too big with attachments and rejected by their mail provider
        //  So if via email - need to send one at a time
        //  Then if cuts out or times out, it has processed some so don't need to re-process those when it's run again
        //
        //  just remember to process the emails first ... so if any interruptions/errors ... at least some will have been processed
        //



        try
        {
            bool AutoSendFaxesAsEmailsIfNoEmailExistsToGPs = Convert.ToInt32(SystemVariableDB.GetByDescr("AutoSendFaxesAsEmailsIfNoEmailExistsToGPs").Value) == 1;

            string sendMethod = rdioSendType.SelectedValue;
            if (!viewListOnly && SelectedSendMethod == SendMethod.None)
            {
                throw new CustomMessageException("Send method not selected");
            }

            string tmpLettersDirectory = Letter.GetTempLettersDirectory();
            if (!Directory.Exists(tmpLettersDirectory))
            {
                throw new CustomMessageException("Temp letters directory doesn't exist");
            }


            string debugOutput = string.Empty;
            int    startTime   = Environment.TickCount;



            // NB.
            // start/emd date time __must__ refer to the treatment date because
            // as a letter can be generated any time (days or weeks) after a treatment, there is no way
            // to be sure which invoice it is attached to, only which booking
            if (txtStartDate.Text.Length > 0 && !Utilities.IsValidDate(txtStartDate.Text, "dd-mm-yyyy"))
            {
                throw new CustomMessageException("Start date must be empty or valid and of the format dd-mm-yyyy");
            }
            if (txtEndDate.Text.Length > 0 && !Utilities.IsValidDate(txtEndDate.Text, "dd-mm-yyyy"))
            {
                throw new CustomMessageException("End date must be empty or valid and of the format dd-mm-yyyy");
            }
            DateTime startDate = txtStartDate.Text.Length == 0 ? DateTime.MinValue : Utilities.GetDate(txtStartDate.Text, "dd-mm-yyyy");
            DateTime endDate   = txtEndDate.Text.Length == 0 ? DateTime.MinValue : Utilities.GetDate(txtEndDate.Text, "dd-mm-yyyy");


            DataTable bookingsWithSentLetters = BookingDB.GetBookingsWithEPCLetters(startDate, endDate, Convert.ToInt32(registerReferrerID.Value), Convert.ToInt32(patientID.Value), true, false);

            if (!viewListOnly && bookingsWithSentLetters.Rows.Count > MaxSending)
            {
                throw new CustomMessageException("Can not generate more than " + MaxSending + " letters at a time. Please narrow your date range.");
            }

            double queryExecutionTime = (double)(Environment.TickCount - startTime) / 1000.0;
            startTime = Environment.TickCount;


            ArrayList filesToPrint = new ArrayList();

            int       currentRegReferrerID       = -1;
            ArrayList bookingsForCurrentReferrer = new ArrayList();
            foreach (DataRow row in bookingsWithSentLetters.Rows)
            {
                Tuple <Booking, PatientReferrer, bool, bool, HealthCard> rowData = LoadRow(row);
                Booking         booking     = rowData.Item1;
                PatientReferrer pr          = rowData.Item2;
                bool            refHasEmail = rowData.Item3;
                bool            refHasFax   = rowData.Item4;
                HealthCard      hc          = rowData.Item5;


                if (pr.RegisterReferrer.RegisterReferrerID != currentRegReferrerID)
                {
                    filesToPrint.AddRange(ProcessReferrersLetters(viewListOnly, bookingsForCurrentReferrer, AutoSendFaxesAsEmailsIfNoEmailExistsToGPs, ref debugOutput, bulkLetterSendingQueueBatchID));
                    currentRegReferrerID       = pr.RegisterReferrer.RegisterReferrerID;
                    bookingsForCurrentReferrer = new ArrayList();
                }

                bookingsForCurrentReferrer.Add(rowData);
            }

            // process last group
            filesToPrint.AddRange(ProcessReferrersLetters(viewListOnly, bookingsForCurrentReferrer, AutoSendFaxesAsEmailsIfNoEmailExistsToGPs, ref debugOutput, bulkLetterSendingQueueBatchID));



            bool zipSeperately = true;

            if (zipSeperately && filesToPrint.Count > 0)
            {
                // seperate into doc types because can only merge docs with docs of same template (ie docname)
                Hashtable filesToPrintHash = new Hashtable();
                for (int i = 0; i < filesToPrint.Count; i++)
                {
                    Letter.FileContents curFileContents = (Letter.FileContents)filesToPrint[i];
                    if (filesToPrintHash[curFileContents.DocName] == null)
                    {
                        filesToPrintHash[curFileContents.DocName] = new ArrayList();
                    }
                    ((ArrayList)filesToPrintHash[curFileContents.DocName]).Add(curFileContents);
                }

                // merge and put merged files into temp dir
                string baseTmpDir = FileHelper.GetTempDirectoryName(tmpLettersDirectory);
                string tmpDir     = baseTmpDir + "EPC Letters" + @"\";
                Directory.CreateDirectory(tmpDir);
                string[] tmpFiles = new string[filesToPrintHash.Keys.Count];
                IDictionaryEnumerator enumerator = filesToPrintHash.GetEnumerator();
                for (int i = 0; enumerator.MoveNext(); i++)
                {
                    ArrayList files   = (ArrayList)enumerator.Value;
                    string    docName = (string)enumerator.Key;


                    // last file is screwing up, so just re-add the last file again for a temp fix
                    files.Add(files[files.Count - 1]);


                    Letter.FileContents fileContents = Letter.FileContents.Merge((Letter.FileContents[])files.ToArray(typeof(Letter.FileContents)), docName); // .pdf

                    string tmpFileName = tmpDir + fileContents.DocName;
                    System.IO.File.WriteAllBytes(tmpFileName, fileContents.Contents);
                    tmpFiles[i] = tmpFileName;
                }

                // zip em
                string zipFileName = "EPC Letters.zip";
                string zipFilePath = baseTmpDir + zipFileName;
                ICSharpCode.SharpZipLib.Zip.FastZip zip = new ICSharpCode.SharpZipLib.Zip.FastZip();
                zip.CreateEmptyDirectories = true;
                zip.CreateZip(zipFilePath, tmpDir, true, "");

                // get filecontents of zip here
                Letter.FileContents zipFileContents = new Letter.FileContents(zipFilePath, zipFileName);
                Session["downloadFile_Contents"] = zipFileContents.Contents;
                Session["downloadFile_DocName"]  = zipFileContents.DocName;

                // delete files
                for (int i = 0; i < tmpFiles.Length; i++)
                {
                    System.IO.File.SetAttributes(tmpFiles[i], FileAttributes.Normal);
                    System.IO.File.Delete(tmpFiles[i]);
                }
                System.IO.File.SetAttributes(zipFilePath, FileAttributes.Normal);
                System.IO.File.Delete(zipFilePath);
                System.IO.Directory.Delete(tmpDir, false);
                System.IO.Directory.Delete(baseTmpDir, false);

                // put in session variables so when it reloads to this page, we can popup the download window
                Page.ClientScript.RegisterStartupScript(this.GetType(), "download", "<script language=javascript>window.open('DownloadFile.aspx','_blank','status=1,toolbar=0,menubar=0,location=1,scrollbars=1,resizable=1,width=30,height=30');</script>");
            }

            if (!zipSeperately && filesToPrint.Count > 0)
            {
                Letter.FileContents fileContents = Letter.FileContents.Merge((Letter.FileContents[])filesToPrint.ToArray(typeof(Letter.FileContents)), "Referral Letters.doc");  // .pdf
                Session["downloadFile_Contents"] = fileContents.Contents;
                Session["downloadFile_DocName"]  = fileContents.DocName;

                // put in session variables so when it reloads to this page, we can popup the download window
                Page.ClientScript.RegisterStartupScript(this.GetType(), "download", "<script language=javascript>window.open('DownloadFile.aspx','_blank','status=1,toolbar=0,menubar=0,location=1,scrollbars=1,resizable=1,width=30,height=30');</script>");
            }


            double restExecutionTime = (double)(Environment.TickCount - startTime) / 1000.0;

            if (debugMode)
            {
                if (!viewListOnly)
                {
                    lblInfo.Text = @"<table cellpadding=""0"">
                                    <tr><td><b>Send Method</b></td><td style=""width:10px;""></td><td>" + SelectedSendMethod.ToString() + @"</td><td style=""width:25px;""></td><td><b>Query Time</b></td><td style=""width:10px;""></td><td>" + queryExecutionTime + @" seconds</td></tr>
                                    <tr><td><b>Count</b></td><td style=""width:10px;""></td><td>" + bookingsWithSentLetters.Rows.Count + @"</td><td style=""width:25px;""></td><td><b>Runing Time</b></td><td style=""width:10px;""></td><td>" + restExecutionTime + @" seconds</td></tr>
                                 </table>";
                }

                string countShowing = bookingsWithSentLetters.Rows.Count > MaxSending ? bookingsWithSentLetters.Rows.Count + " showing to re-generate. <br /><font color=red>* You can not generate more than 175 at a time. Please narrow your search before printing.</font>" : bookingsWithSentLetters.Rows.Count.ToString();
                if (viewListOnly)
                {
                    lblInfo.Text = @"<table cellpadding=""0"">
                                    <tr><td valign=""top""><b>Count</b></td><td style=""width:10px;""></td><td>" + countShowing + @"</td></tr>
                                 </table>";
                }


                if (viewListOnly)
                {
                    lblList.Text = @"<table class=""table table-bordered table-striped table-grid table-grid-top-bottum-padding-thick auto_width block_center"" cellpadding=""4"" border=""1"">
                                        <tr>
                                            <th style=""white-space:nowrap;"">Send By</th>
                                            <th>Booking</th>
                                            <th>Generate</th>
                                            <th>Referrer</th>
                                            <th>Email</th>
                                            <th>Fax</th>
                                            <th>Patient</th>
                                        </tr>" +
                                   (debugOutput.Length == 0 ? "<tr><td colspan=\"7\">No Rows</td></tr>" : debugOutput) +
                                   "</table>";
                }
            }
        }
        catch (CustomMessageException cmEx)
        {
            SetErrorMessage(cmEx.Message);
        }
        catch (Exception ex)
        {
            SetErrorMessage("", ex.ToString());
        }
    }