예제 #1
0
    public static string Run(bool incDisplay, bool incSending, bool incPtSending, DateTime date)
    {
        date = date.Date;

        string batchEmail = SystemVariableDB.GetByDescr("ServiceSpecificBookingReminderLettersToBatch_EmailAddress").Value;

        // don't actually run it if email empty (ie deactivated)
        incSending = incSending && batchEmail.Length > 0;

        Site[] sites = SiteDB.GetAll();


        string output = string.Empty;

        Hashtable lettersHash = LetterDB.GetHashTable();

        Offering[] offerings = OfferingDB.GetAll(false, -1);
        for (int j = 0; j < offerings.Length; j++)
        {
            if (offerings[j].ReminderLetterMonthsLaterToSend == 0 || offerings[j].ReminderLetterID == -1)
            {
                continue;
            }

            Booking[] bookings = BookingDB.GetWhenLastServiceFromXMonthsAgoToGenerageReminderLetter(offerings[j].OfferingID, date, offerings[j].ReminderLetterMonthsLaterToSend);


            Hashtable distinctPatients = new Hashtable();
            for (int i = 0; i < bookings.Length; i++)
            {
                if (bookings[i].Patient != null && distinctPatients[bookings[i].Patient.PatientID] == null)
                {
                    distinctPatients[bookings[i].Patient.PatientID] = bookings[i].Patient;
                }
            }

            Patient[] patients = (Patient[])(new ArrayList(distinctPatients.Values)).ToArray(typeof(Patient));
            Hashtable patientContactEmailHash = GetPatientEmailCache(patients);



            // Generate Letters

            ArrayList filesToPrint = new ArrayList();
            for (int i = 0; i < bookings.Length; i++)
            {
                Booking curBooking = bookings[i];
                if (curBooking.Patient == null)
                {
                    continue;
                }

                Patient curPatient         = curBooking.Patient;
                string  curPatientEmail    = GetEmail(patientContactEmailHash, curPatient.Person.EntityID);
                bool    curPatientHasEmail = curPatientEmail != null;


                SendMethod sendMethod = incPtSending && curPatientHasEmail ? SendMethod.Email_To_Patient : SendMethod.Batch;

                if (incSending)
                {
                    if (sendMethod == SendMethod.Email_To_Patient)
                    {
                        // generate and send email
                        Letter.FileContents fileContents = GenerteLetter(curBooking, Letter.FileFormat.PDF, lettersHash, sites);
                        fileContents.DocName = "Reminder" + System.IO.Path.GetExtension(fileContents.DocName);
                        if (fileContents != null)
                        {
                            Site site = SiteDB.GetSiteByType(curBooking.Organisation.IsAgedCare ? SiteDB.SiteType.AgedCare : SiteDB.SiteType.Clinic);
                            SendEmail(site.Name, curPatientEmail, "Important Reminder", "Hi " + curBooking.Patient.Person.Firstname + ",<br /><br />Please find attached a review reminder letter for a previous appointment.<br /><br/>Best regards,<br />" + site.Name, true, new Letter.FileContents[] { fileContents });
                        }
                    }
                    else
                    {
                        // generate and add to batch list (if batch email set)
                        if (batchEmail.Length > 0)
                        {
                            Letter.FileContents fileContents = GenerteLetter(curBooking, Letter.FileFormat.Word, lettersHash, sites);
                            if (fileContents != null)
                            {
                                filesToPrint.Add(fileContents);
                            }
                        }
                    }
                }

                string addEditContactListPage;
                if (Utilities.GetAddressType().ToString() == "Contact")
                {
                    addEditContactListPage = "AddEditContactList.aspx";
                }
                else if (Utilities.GetAddressType().ToString() == "ContactAus")
                {
                    addEditContactListPage = "ContactAusListV2.aspx";
                }
                else
                {
                    throw new Exception("Unknown AddressType in config: " + Utilities.GetAddressType().ToString().ToString());
                }

                string allFeatures     = "dialogWidth:555px;dialogHeight:350px;center:yes;resizable:no; scroll:no";
                string onclick         = "onclick=\"javascript:window.showModalDialog('" + addEditContactListPage + "?entity_type=referrer&id=" + curBooking.Patient.Person.EntityID.ToString() + "', '', '" + allFeatures + "');document.getElementById('btnUpdateList').click();return false;\"";
                string hrefUpdateEmail = "<u><a style=\"text-decoration: none\" title=\"Edit\" AlternateText=\"Edit\" " + onclick + " href=\"\">Update PT Email</a></u>";

                output += @"<tr>
                                <td class=""nowrap"">" + curBooking.BookingID + " &nbsp;&nbsp;&nbsp;[" + curBooking.DateStart.ToString("dd-MM-yyyy") + "&nbsp;&nbsp;&nbsp;" + curBooking.DateStart.ToString("HH:mm") + "-" + curBooking.DateEnd.ToString("HH:mm") + "]" + @"</td>
                                <td class=""text_left"">" + curBooking.Organisation.Name + @"</td>
                                <td class=""text_left"">" + curBooking.Offering.Name + @"</td>
                                <td class=""text_left"">" + ((Letter)lettersHash[curBooking.Offering.ReminderLetterID]).Docname + @"</td>
                                <td class=""text_left"">" + curPatient.Person.FullnameWithoutMiddlename + @"</td>
                                <td class=""nowrap"">" + (curPatientHasEmail ? curPatientEmail : "Has No Email") + " (" + hrefUpdateEmail + ")" + @"</td>
                                <td>" + sendMethod.ToString().Replace("_", " ") + @"</td>
                            </tr>";
            }


            // combine and email where the patient had no email
            if (incSending && filesToPrint.Count > 0)
            {
                Letter.FileContents filesContents = Letter.FileContents.Merge((Letter.FileContents[])filesToPrint.ToArray(typeof(Letter.FileContents)), "Reminders.pdf"); // .pdf
                SendEmail(
                    ((SystemVariables)System.Web.HttpContext.Current.Session["SystemVariables"])["Email_FromName"].Value,
                    batchEmail,
                    "Batch Reminder Letters",
                    string.Empty,
                    true,
                    new Letter.FileContents[] { filesContents });
            }
        }


        if (output.Length == 0)
        {
            output += @"<tr>
                            <td colspan=""7"">No Reminders To Send Today</td>
                        </tr>";
        }

        return(@"
            <table class=""table table-bordered table-striped table-grid table-grid-top-bottum-padding-thick auto_width block_center"" style=""border-style:solid;border-width:1px;border-collapse:collapse;padding:4px;"">
            <tr>
              <th>Booking (ID, Date/Time)</th>
              <th>Organisation</th>
              <th>Service</th>
              <th>Letter</th>
              <th>Patient</th>
              <th>PT Email</th>
              <th>Send Method</th>
            </tr>
            " + output + @"
            </table>");
    }
    public static Letter.FileContents Run(SendMethod sendMethod, int siteID, int staffID, int registerReferrerID, bool incBatching, bool incUnsent, bool incWithEmailOrFaxOnly, bool viewListOnly, bool viewFullList, out string outputInfo, out string outputList, string btnViewListClientID)
    {
        int bulkLetterSendingQueueBatchID = !viewListOnly && UseBulkLetterSender ? BulkLetterSendingQueueBatchDB.Insert(DebugEmail, false) : -1;

        RndPageID = (new Random()).Next().ToString();

        bool debugMode = true;

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

        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;
        }

        Hashtable orgHash = OrganisationDB.GetAllHashtable(true, true, false, false, true, true);

        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();
            Hashtable rowIDsToRemove = new Hashtable();
            foreach (DataRow row in bookingsWithUnsetnLettersClinic.Rows)
            {
                numGenerated++;

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

                Tuple<Booking, PatientReferrer, bool, bool, string, string, HealthCard> rowData = LoadClinicRow(row);

                // realod org to get full org data (in particular, org type to get site-type
                if (orgHash[rowData.Item1.Organisation.OrganisationID] != null)
                    rowData.Item1.Organisation = (Organisation)orgHash[rowData.Item1.Organisation.OrganisationID];

                Booking         booking     = rowData.Item1;
                PatientReferrer pr          = rowData.Item2;
                bool            refHasEmail = rowData.Item3;
                bool            refHasFax   = rowData.Item4;
                string          refEmail    = rowData.Item5;
                string          refFax      = rowData.Item6;
                HealthCard      hc          = rowData.Item7;

                bool refHasEmailOrFax = AutoSendFaxesAsEmailsIfNoEmailExistsToGPs ? (refHasEmail || refHasFax) : refHasEmail;
                if (incWithEmailOrFaxOnly && !refHasEmailOrFax)
                {
                    numGenerated--;
                    rowIDsToRemove[booking.BookingID] = 1;
                    continue;
                }

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

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

                bookingsForCurrentReferrer.Add(rowData);
            }

            if (bookingsWithUnsetnLettersClinic.Rows.Count > 0)
                for (int i = bookingsWithUnsetnLettersClinic.Rows.Count - 1; i >= 0; i--)
                    if (rowIDsToRemove[Convert.ToInt32(bookingsWithUnsetnLettersClinic.Rows[i]["booking_booking_id"])] != null)
                        bookingsWithUnsetnLettersClinic.Rows.RemoveAt(i);

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

            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();
            Hashtable rowIDsToRemove = new Hashtable();
            foreach (DataRow row in bookingsWithUnsetnLettersAgedCare.Rows)
            {
                numGenerated++;
                //if (numGenerated % 15 != 1) continue;
                if ((!viewListOnly || !viewFullList) && (numGenerated > MaxSending))
                    continue;
                Tuple<BookingPatient, Offering, PatientReferrer, bool, bool, string, string, Tuple<HealthCard>> rowData = LoadAgedCareRow(row);

                // realod org to get full org data (in particular, org type to get site-type
                if (orgHash[rowData.Item1.Booking.Organisation.OrganisationID] != null)
                    rowData.Item1.Booking.Organisation = (Organisation)orgHash[rowData.Item1.Booking.Organisation.OrganisationID];

                BookingPatient  bp          = rowData.Item1;
                Offering        offering    = rowData.Item2;
                PatientReferrer pr          = rowData.Item3;
                bool            refHasEmail = rowData.Item4;
                bool            refHasFax   = rowData.Item5;
                string          refEmail    = rowData.Item6;
                string          refFax      = rowData.Item7;
                HealthCard      hc          = rowData.Rest.Item1;

                bool refHasEmailOrFax = AutoSendFaxesAsEmailsIfNoEmailExistsToGPs ? (refHasEmail || refHasFax) : refHasEmail;
                if (incWithEmailOrFaxOnly && !refHasEmailOrFax)
                {
                    numGenerated--;
                    rowIDsToRemove[bp.BookingPatientID] = 1;
                    continue;
                }

                //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, allSites, staffID, bookingsForCurrentReferrer, AutoSendFaxesAsEmailsIfNoEmailExistsToGPs, ref debugOutput, btnViewListClientID, bulkLetterSendingQueueBatchID));
                    currentRegReferrerID = pr.RegisterReferrer.RegisterReferrerID;
                    bookingsForCurrentReferrer = new ArrayList();
                }

                bookingsForCurrentReferrer.Add(rowData);
            }

            if (bookingsWithUnsetnLettersAgedCare.Rows.Count > 0)
                for (int i = bookingsWithUnsetnLettersAgedCare.Rows.Count - 1; i >= 0; i--)
                    if (rowIDsToRemove[Convert.ToInt32(bookingsWithUnsetnLettersAgedCare.Rows[i]["bp_booking_patient_id"])] != null)
                        bookingsWithUnsetnLettersAgedCare.Rows.RemoveAt(i);

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

            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=\"9\">No Rows</td></tr>" : debugOutput) +
                                "</table>";
        }

        if (UseBulkLetterSender)
            BulkLetterSendingQueueBatchDB.UpdateReadyToProcess(bulkLetterSendingQueueBatchID, true);

        return zipFileContents;
    }
    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);
    }