Пример #1
0
    protected void btnExport_Click(object sender, EventArgs e)
    {
        Booking booking    = BookingDB.GetByID(GetFormBooking());
        bool    isAgedCare = booking.Organisation.IsAgedCare;


        string tmpLettersDirectory = FileHelper.GetTempDirectoryName(Letter.GetTempLettersDirectory());

        Directory.CreateDirectory(tmpLettersDirectory);

        string templateFileName = isAgedCare ? "ACTreatmentList.docx" : "TreatmentList.docx";
        string originalFile     = Letter.GetLettersDirectory() + templateFileName;
        string tmpOutputFile    = tmpLettersDirectory + "TreatmentList.pdf"; // System.IO.Path.GetExtension(originalFile));

        if (!File.Exists(originalFile))
        {
            SetErrorMessage("Template File '" + templateFileName + "' does not exist.");
            return;
        }

        MergeFile(isAgedCare, originalFile, tmpOutputFile);

        Letter.FileContents fileContents = new Letter.FileContents(System.IO.File.ReadAllBytes(tmpOutputFile), "TreatmentList.pdf");
        File.Delete(tmpOutputFile);
        System.IO.File.SetAttributes(tmpLettersDirectory, FileAttributes.Normal);
        System.IO.Directory.Delete(tmpLettersDirectory, true);

        // Nothing gets past the "DownloadDocument" method because it outputs the file
        // which is writing a response to the client browser and calls Response.End()
        // So make sure any other code that functions goes before this
        Letter.DownloadDocument(Response, fileContents.Contents, fileContents.DocName);
    }
Пример #2
0
    protected void btnGenerateSystemLetters_Click(object sender, EventArgs e)
    {
        System.Collections.ArrayList fileContentsList = new System.Collections.ArrayList();

        Booking[] bookings = BookingDB.GetBookingsToGenerateSystemLetters(DateTime.MinValue, DateTime.MinValue, GetFormID());
        for (int i = 0; i < bookings.Length; i++)
        {
            // send referrer letters

            PatientReferrer[] patientReferrers = PatientReferrerDB.GetActiveEPCPatientReferrersOf(bookings[i].Patient.PatientID);
            if (patientReferrers.Length > 0)
            {
                HealthCard hc = HealthCardDB.GetActiveByPatientID(bookings[i].Patient.PatientID);
                bool       needToGenerateTreatmentLetter = patientReferrers[patientReferrers.Length - 1].RegisterReferrer.ReportEveryVisitToReferrer;

                Letter.FileContents[] bookingFileContentsList = bookings[i].GetSystemLettersList(Letter.FileFormat.Word, bookings[i].Patient, hc, bookings[i].Offering.Field.ID, patientReferrers[patientReferrers.Length - 1].RegisterReferrer.Referrer, true, bookings[i].NeedToGenerateFirstLetter, bookings[i].NeedToGenerateLastLetter, needToGenerateTreatmentLetter, false, Convert.ToInt32(Session["SiteID"]), Convert.ToInt32(Session["StaffID"]), 1);
                fileContentsList.AddRange(bookingFileContentsList);
                BookingDB.UpdateSetGeneratedSystemLetters(bookings[i].BookingID, bookings[i].NeedToGenerateFirstLetter, bookings[i].NeedToGenerateLastLetter, true);
            }
        }

        Letter.FileContents mergedFileContents = Letter.FileContents.Merge((Letter.FileContents[])fileContentsList.ToArray(typeof(Letter.FileContents)), "Treatment Letters.doc"); // .pdf
        if (mergedFileContents != null)
        {
            Session["downloadFile_Contents"] = mergedFileContents.Contents;
            Session["downloadFile_DocName"]  = mergedFileContents.DocName;
            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>");
        }

        UpdateGenerateSystemLetters();
    }
Пример #3
0
    protected static Letter.FileContents GenerteLetter(Booking booking, Letter.FileFormat fileFormat, Hashtable lettersHash, Site[] sites)
    {
        try
        {
            bool isClinic   = booking.Organisation.OrganisationType.OrganisationTypeGroup.ID == 5;
            bool isAgedCare = booking.Organisation.OrganisationType.OrganisationTypeGroup.ID == 6;

            Site site = null;
            for (int i = 0; i < sites.Length; i++)
            {
                if ((isClinic && sites[i].SiteType.ID == 1) || (isAgedCare && sites[i].SiteType.ID == 2))
                {
                    site = sites[i];
                }
            }


            // get letter and make sure it exists
            Letter letter             = (Letter)lettersHash[booking.Offering.ReminderLetterID];
            string sourchTemplatePath = letter.GetFullPath(site.SiteID);
            if (!System.IO.File.Exists(sourchTemplatePath))
            {
                throw new CustomMessageException("File doesn't exist.");
            }

            Letter.FileContents fileContents = Letter.CreateLetter(
                fileFormat,
                site,
                booking.Offering.ReminderLetterID,
                booking.Organisation.OrganisationID,
                booking.Patient.PatientID,
                booking.Provider.StaffID,
                booking.BookingID,
                -1,
                1,
                null,
                false,
                1);


            return(fileContents);
        }
        catch (Exception ex)
        {
            Logger.LogException(ex);
            return(null);
        }
    }
    protected void btnPrintBookingList_Click(object sender, EventArgs e)
    {
        DataTable tblBookingList = SetBookingsList();
        if (tblBookingList == null)
            return;

        try
        {
            string originalFile = Letter.GetLettersDirectory() + @"BookingListForPatient.docx";
            string tmpLettersDirectory = Letter.GetTempLettersDirectory();
            string tmpOutputFile = FileHelper.GetTempFileName(tmpLettersDirectory + "BookingList." + System.IO.Path.GetExtension(originalFile));

            // create table data to populate

            DataTable dt = tblBookingList;
            string[,] tblInfo = null;
            bool tblEmpty = (dt.Rows.Count == 1 && dt.Rows[0][0] == DBNull.Value);
            if (tblEmpty)
            {
                tblInfo = new string[1, 4];
                tblInfo[0, 0] = "No Bookings Found";
                tblInfo[0, 1] = "";
                tblInfo[0, 2] = "";
                tblInfo[0, 3] = "";
            }
            else
            {
                tblInfo = new string[dt.Rows.Count, 4];
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    string inv_type_text = tblBookingList.Rows[i]["inv_type_text"].ToString();
                    if (inv_type_text.Length > 0) inv_type_text = " (" + inv_type_text + ")";

                    Booking booking = BookingDB.LoadFull(dt.Rows[i]);
                    tblInfo[i, 0] = booking.DateStart.ToString("d MMM yyyy") + Environment.NewLine + booking.DateStart.ToString("h:mm") + " - " + booking.DateEnd.ToString("h:mm") + (booking.DateEnd.Hour < 12 ? "am" : "pm");
                    tblInfo[i, 1] = booking.Patient == null ? "" : booking.Patient.Person.FullnameWithoutMiddlename;
                    tblInfo[i, 2] = (booking.Offering == null ? "" : booking.Offering.Name + Environment.NewLine) + booking.Provider.Person.FullnameWithoutMiddlename + " @ " + booking.Organisation.Name;
                    tblInfo[i, 3] = booking.BookingStatus.Descr + Environment.NewLine + inv_type_text;
                }
            }

            // create empty dataset

            System.Data.DataSet sourceDataSet = new System.Data.DataSet();
            sourceDataSet.Tables.Add("MergeIt");

            // merge

            string errorString = null;
            WordMailMerger.Merge(

                originalFile,
                tmpOutputFile,
                sourceDataSet,

                tblInfo,
                1,
                true,

                false,
                null,
                true,
                null,
                out errorString);

            if (errorString != string.Empty)
                throw new CustomMessageException(errorString);

            Letter.FileContents fileContents = new Letter.FileContents(System.IO.File.ReadAllBytes(tmpOutputFile), "BookingList." + System.IO.Path.GetExtension(originalFile));
            System.IO.File.Delete(tmpOutputFile);

            // Nothing gets past the "DownloadDocument" method because it outputs the file
            // which is writing a response to the client browser and calls Response.End()
            // So make sure any other code that functions goes before this
            Letter.DownloadDocument(Response, fileContents.Contents, fileContents.DocName);
        }
        catch (CustomMessageException cmEx)
        {
            SetErrorMessage(cmEx.Message);
        }
        catch (Exception ex)
        {
            SetErrorMessage(ex.ToString());
        }
    }
    protected void btnPrint_Click(object sender, EventArgs e)
    {
        // re-fill grid in case two broswer windows are open with 2 different booking lists and only the one on the other page is in the session memory...
        FillGrid();

        try
        {
            string originalFile        = Letter.GetLettersDirectory() + @"BookingList.docx";
            string tmpLettersDirectory = Letter.GetTempLettersDirectory();
            string tmpOutputFile       = FileHelper.GetTempFileName(tmpLettersDirectory + "BookingList." + System.IO.Path.GetExtension(originalFile));


            // create table data to populate

            DataTable dt = Session["bookinglist_data"] as DataTable;
            string[,] tblInfo = null;
            bool tblEmpty = (dt.Rows.Count == 1 && dt.Rows[0][0] == DBNull.Value);
            if (tblEmpty)
            {
                tblInfo       = new string[1, 4];
                tblInfo[0, 0] = "No Bookings Found";
                tblInfo[0, 1] = "";
                tblInfo[0, 2] = "";
                tblInfo[0, 3] = "";
            }
            else
            {
                tblInfo = new string[dt.Rows.Count, 4];
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    Booking booking = BookingDB.LoadFull(dt.Rows[i]);
                    tblInfo[i, 0] = booking.DateStart.ToString("d MMM") + " " + booking.DateStart.ToString("h:mm") + " - " + booking.DateEnd.ToString("h:mm") + (booking.DateEnd.Hour < 12 ? "am" : "pm");
                    tblInfo[i, 1] = booking.Patient == null ? "" : booking.Patient.Person.FullnameWithoutMiddlename;
                    tblInfo[i, 2] = booking.Provider.Person.FullnameWithoutMiddlename;
                    tblInfo[i, 3] = booking.Organisation.Name;
                }
            }


            // create empty dataset

            System.Data.DataSet sourceDataSet = new System.Data.DataSet();
            sourceDataSet.Tables.Add("MergeIt");


            // merge

            string errorString = null;
            WordMailMerger.Merge(

                originalFile,
                tmpOutputFile,
                sourceDataSet,

                tblInfo,
                1,
                true,

                true,
                null,
                true,
                null,
                out errorString);

            if (errorString != string.Empty)
            {
                throw new CustomMessageException(errorString);
            }

            Letter.FileContents fileContents = new Letter.FileContents(System.IO.File.ReadAllBytes(tmpOutputFile), "BookingList." + System.IO.Path.GetExtension(originalFile));
            System.IO.File.Delete(tmpOutputFile);


            // Nothing gets past the "DownloadDocument" method because it outputs the file
            // which is writing a response to the client browser and calls Response.End()
            // So make sure any other code that functions goes before this
            Letter.DownloadDocument(Response, fileContents.Contents, fileContents.DocName);
        }
        catch (CustomMessageException cmEx)
        {
            SetErrorMessage(cmEx.Message);
        }
        catch (Exception ex)
        {
            SetErrorMessage(ex.ToString());
        }
    }
    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;
    }
Пример #7
0
    public static void GenerateAllInvoicesAndTypes(int[] invoiceIDs, HttpResponse response)
    {
        Site site = SiteDB.GetByID(Convert.ToInt32(System.Web.HttpContext.Current.Session["SiteID"]));

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

        Invoice[] invoices        = InvoiceDB.GetByIDs(invoiceIDs);
        Hashtable invoiceLineHash = InvoiceLineDB.GetBulkInvoiceLinesByInvoiceID(invoices);
        Hashtable receiptHash     = ReceiptDB.GetBulkReceiptsByInvoiceID(invoices);
        Hashtable creditNoteHash  = CreditNoteDB.GetBulkCreditNotesByInvoiceID(invoices);

        ArrayList entityIDsList = new ArrayList();
        foreach (Invoice invoice in invoices)
        {
            if (invoice.Booking != null && invoice.Booking.Patient != null)
                entityIDsList.Add(invoice.Booking.Patient.Person.EntityID);
            if (invoice.Booking != null && invoice.Booking.Organisation != null)
                entityIDsList.Add(invoice.Booking.Organisation.EntityID);
            if (invoice.PayerPatient != null)
                entityIDsList.Add(invoice.PayerPatient.Person.EntityID);
            if (invoice.PayerOrganisation != null)
                entityIDsList.Add(invoice.PayerOrganisation.EntityID);
        }
        entityIDsList.Add(site.EntityID);
        int[] entityIDs = (int[])entityIDsList.ToArray(typeof(int));

        Hashtable addressHash     = PatientsContactCacheDB.GetBullk("1",  null,  entityIDs, -1);
        Hashtable phoneHash       = PatientsContactCacheDB.GetBullk(null, "30,33,34",  entityIDs, -1);
        Hashtable faxHash         = PatientsContactCacheDB.GetBullk(null, "29",  entityIDs, -1);
        Hashtable webHash         = PatientsContactCacheDB.GetBullk(null, "28",  entityIDs, -1);
        Hashtable emailHash       = PatientsContactCacheDB.GetBullk(null, "27",  entityIDs, -1);
        Hashtable acPtBedroomHash = PatientsContactCacheDB.GetBullk(null, "166", entityIDs, -1);

        object siteAddressList = addressHash[site.EntityID] == null ? null : addressHash[site.EntityID];
        object sitePhoneList   = phoneHash[site.EntityID]   == null ? null : phoneHash[site.EntityID];
        object siteFaxList     = faxHash[site.EntityID]     == null ? null : faxHash[site.EntityID];
        object siteWebList     = webHash[site.EntityID]     == null ? null : webHash[site.EntityID];
        object siteEmailList   = emailHash[site.EntityID]   == null ? null : emailHash[site.EntityID];

        object siteAddress = siteAddressList == null ? null : (Utilities.GetAddressType().ToString() == "ContactAus" ? (object)((ContactAus[])siteAddressList)[0] : (object)((Contact[])siteAddressList)[0]);
        object sitePhone   = sitePhoneList   == null ? null : (Utilities.GetAddressType().ToString() == "ContactAus" ? (object)((ContactAus[])sitePhoneList)[0]   : (object)((Contact[])sitePhoneList)[0]);
        object siteFax     = siteFaxList     == null ? null : (Utilities.GetAddressType().ToString() == "ContactAus" ? (object)((ContactAus[])siteFaxList)[0]     : (object)((Contact[])siteFaxList)[0]);
        object siteWeb     = siteWebList     == null ? null : (Utilities.GetAddressType().ToString() == "ContactAus" ? (object)((ContactAus[])siteWebList)[0]     : (object)((Contact[])siteWebList)[0]);
        object siteEmail   = siteEmailList   == null ? null : (Utilities.GetAddressType().ToString() == "ContactAus" ? (object)((ContactAus[])siteEmailList)[0]   : (object)((Contact[])siteEmailList)[0]);

        string tmpLettersDirectory                 = FileHelper.GetTempDirectoryName(Letter.GetTempLettersDirectory());
        Directory.CreateDirectory(tmpLettersDirectory);
        string tmpLettersDirectory2                = FileHelper.GetTempDirectoryName(Letter.GetTempLettersDirectory());
        Directory.CreateDirectory(tmpLettersDirectory2);
        string originalFile_BookingClinicInvoices  = Letter.GetLettersDirectory() + @"InvoiceTemplate.docx";
        string originalFile_BookingACInvoices      = Letter.GetLettersDirectory() + @"InvoiceTemplateAC.docx";
        string originalFile_PrivateInvoices        = Letter.GetLettersDirectory() + @"PrivateInvoiceTemplate.docx";

        ArrayList filePaths_BookingClinicInvoices = new ArrayList();
        ArrayList filePaths_BookingACInvoices     = new ArrayList();
        ArrayList filePaths_PrivateInvoices       = new ArrayList();

        foreach (Invoice invoice in invoices)
        {
            InvoiceLine[] lines       = invoiceLineHash[invoice.InvoiceID] == null ? new InvoiceLine[]{} : (InvoiceLine[])invoiceLineHash[invoice.InvoiceID];
            Receipt[]     receipts    = receiptHash[invoice.InvoiceID]     == null ? new Receipt[]{}     : (Receipt[])    receiptHash[invoice.InvoiceID];
            CreditNote[]  creditNotes = creditNoteHash[invoice.InvoiceID]  == null ? new CreditNote[]{}  : (CreditNote[]) creditNoteHash[invoice.InvoiceID];

            bool isClinicInvoice  = invoice.Site.SiteType.ID == 1;
            bool isBookingInvoice = invoice.Booking != null;

            string originalFile = !isBookingInvoice ? originalFile_PrivateInvoices : (isClinicInvoice ? originalFile_BookingClinicInvoices : originalFile_BookingACInvoices);
            string outputFile   = FileHelper.GetTempFileName(tmpLettersDirectory + "Invoice_" + invoice.InvoiceID + "." + System.IO.Path.GetExtension(originalFile));

            // 1. change address/phone section below to use hashes
            // 2. just use one table to see if it works
            // 3. if works .. send in multiple tables as an array .. prob just add to arraylist of arrays

            bool isMedicareInvoice  = invoice.PayerOrganisation != null && (invoice.PayerOrganisation.OrganisationID == -1 || invoice.PayerOrganisation.OrganisationID == -2);
            bool isTACInvoice       = invoice.PayerOrganisation != null && invoice.PayerOrganisation.OrganisationType.OrganisationTypeID == 150;

            // was rejected when
            // - pt pays invoice, and
            // - booking has a medicare/dva invoice that has been rejected
            //      ie  payer org = -1/-2 and single adj/cr note equal to total, and single inv line with same offering as this one single inv line)
            //
            bool wasRejectedMedicareInvoice = false;
            if (!isMedicareInvoice && lines.Length == 1 && invoice.Booking != null)
            {
                foreach (Invoice curInvoice in InvoiceDB.GetByBookingID(invoice.Booking.BookingID, false))
                {
                    // make sure is medicare/dva booking
                    if (curInvoice.PayerOrganisation == null || (curInvoice.PayerOrganisation.OrganisationID != -1 && curInvoice.PayerOrganisation.OrganisationID != -2))
                        continue;

                    // make sure is wiped (paid, nothing due, no receipts, credit notes == total of bill)
                    if (!curInvoice.IsPaID || curInvoice.TotalDue != 0 || curInvoice.ReceiptsTotal != 0 || curInvoice.CreditNotesTotal != curInvoice.Total)
                        continue;

                    // if only one invoice line on both this and the non-mediare/dva invoice and same offering
                    InvoiceLine[] curInvLines = InvoiceLineDB.GetByInvoiceID(curInvoice.InvoiceID);
                    if (curInvLines.Length == 1                                            &&
                        lines.Length       == 1                                            &&
                        curInvLines[0].Offering.OfferingID == lines[0].Offering.OfferingID &&
                        curInvLines[0].Price               == lines[0].Price               &&
                        curInvLines[0].Quantity            == lines[0].Quantity            &&
                        curInvLines[0].Tax                 == lines[0].Tax)
                            wasRejectedMedicareInvoice = true;
                }
            }

            string message = invoice.Message.Length > 0 ? invoice.Message : (wasRejectedMedicareInvoice ? "*Claim rejected by Medicare" : "");

            //
            // merge the invoice fields
            //

            // create dataset of merge fields from invoice
            System.Data.DataSet sourceDataSet = new System.Data.DataSet();
            sourceDataSet.Tables.Add("MergeIt");

            if (invoice.Booking != null)
            {
                sourceDataSet.Tables[0].Columns.Add("curr_date");
                sourceDataSet.Tables[0].Columns.Add("inv_nbr");
                sourceDataSet.Tables[0].Columns.Add("inv_date");
                sourceDataSet.Tables[0].Columns.Add("inv_debtor_name");
                sourceDataSet.Tables[0].Columns.Add("inv_debtor_addr");
                sourceDataSet.Tables[0].Columns.Add("inv_debtor_addr_tabbedx1");
                sourceDataSet.Tables[0].Columns.Add("bk_pt_fullname");
                sourceDataSet.Tables[0].Columns.Add("bk_pt_addr");
                sourceDataSet.Tables[0].Columns.Add("bk_pt_addr_tabbedx1");
                sourceDataSet.Tables[0].Columns.Add("bk_prov_fullname");
                sourceDataSet.Tables[0].Columns.Add("bk_prov_number");
                sourceDataSet.Tables[0].Columns.Add("bk_date");
                sourceDataSet.Tables[0].Columns.Add("bk_next_info");
                sourceDataSet.Tables[0].Columns.Add("bk_purchase_order_nbr");

                sourceDataSet.Tables[0].Columns.Add("pt_name");           // depricated as same as bk_pt_fullname
                sourceDataSet.Tables[0].Columns.Add("pt_addr");           // depricated as same as bk_addr
                sourceDataSet.Tables[0].Columns.Add("pt_addr_tabbedx1");  // depricated as same as bk_addr_tabbedx1
                //sourceDataSet.Tables[0].Columns.Add("pt_addr_line1");
                //sourceDataSet.Tables[0].Columns.Add("pt_addr_line2");
                //sourceDataSet.Tables[0].Columns.Add("pt_addr_street");
                //sourceDataSet.Tables[0].Columns.Add("pt_addr_suburb");
                //sourceDataSet.Tables[0].Columns.Add("pt_addr_postcode");
                //sourceDataSet.Tables[0].Columns.Add("pt_addr_country");

                sourceDataSet.Tables[0].Columns.Add("bk_org_name");
                sourceDataSet.Tables[0].Columns.Add("bk_org_abn");
                sourceDataSet.Tables[0].Columns.Add("bk_org_acn");
                sourceDataSet.Tables[0].Columns.Add("bk_org_bpay_account");
                sourceDataSet.Tables[0].Columns.Add("bk_org_addr");
                sourceDataSet.Tables[0].Columns.Add("bk_org_addr_tabbedx1");
                sourceDataSet.Tables[0].Columns.Add("bk_org_phone");
                sourceDataSet.Tables[0].Columns.Add("bk_org_office_fax");
                sourceDataSet.Tables[0].Columns.Add("bk_org_web");
                sourceDataSet.Tables[0].Columns.Add("bk_org_email");
            }
            else // private non-booking invoice
            {
                sourceDataSet.Tables[0].Columns.Add("curr_date");
                sourceDataSet.Tables[0].Columns.Add("inv_nbr");
                sourceDataSet.Tables[0].Columns.Add("inv_date");
                sourceDataSet.Tables[0].Columns.Add("pt_fullname");
                sourceDataSet.Tables[0].Columns.Add("org_name");

                sourceDataSet.Tables[0].Columns.Add("org_abn");
                sourceDataSet.Tables[0].Columns.Add("org_acn");
                sourceDataSet.Tables[0].Columns.Add("org_bpay_account");
                sourceDataSet.Tables[0].Columns.Add("org_addr");
                sourceDataSet.Tables[0].Columns.Add("org_addr_tabbedx1");
                sourceDataSet.Tables[0].Columns.Add("org_phone");
                sourceDataSet.Tables[0].Columns.Add("org_office_fax");
                sourceDataSet.Tables[0].Columns.Add("org_web");
                sourceDataSet.Tables[0].Columns.Add("org_email");
            }

            Booking nextBooking = invoice.Booking == null || invoice.Booking.Patient == null ? null : BookingDB.GetNextAfterToday(invoice.Booking.Patient.PatientID, false);
            string nextBookingText = nextBooking == null ? " " : "Next appointment: " + Environment.NewLine + nextBooking.DateStart.ToString("h:mm") + (nextBooking.DateStart.Hour < 12 ? "am" : "pm") + " " + nextBooking.DateStart.ToString("d MMMM, yyyy") + " at " + nextBooking.Organisation.Name;

            RegisterStaff registerStaff = invoice.Booking == null ? null         : RegisterStaffDB.GetByStaffIDAndOrganisationID(invoice.Booking.Provider.StaffID, invoice.Booking.Organisation.OrganisationID);
            string providerNbrThisOrg   = registerStaff   == null ? string.Empty : registerStaff.ProviderNumber;
            string providerNbrThisStaff = invoice.Booking == null ? string.Empty : invoice.Booking.Provider.ProviderNumber;

            int    debtorEntityID = -1;
            string debtorName = "No debtor name found";
            bool?  debtorIsPatient = null;
            if (invoice.PayerOrganisation != null)
            {
                debtorEntityID = invoice.PayerOrganisation.EntityID;
                debtorName = invoice.PayerOrganisation.Name;
                debtorIsPatient = false;
            }
            else if (invoice.PayerPatient != null)
            {
                debtorEntityID = invoice.PayerPatient.Person.EntityID;
                debtorName = invoice.PayerPatient.Person.FullnameWithoutMiddlename;
                debtorIsPatient = true;
            }
            else
            {
                if (invoice.Booking != null && invoice.Booking.Patient != null)
                {
                    debtorEntityID = invoice.Booking.Patient.Person.EntityID;
                    debtorName = invoice.Booking.Patient.Person.FullnameWithoutMiddlename;
                    debtorIsPatient = true;
                }
                else // no debtor for some cash invoices
                    ;
            }

            string patientAddressText, patientAddressTabbedText;
            string orgAddressText    , orgAddressTabbedText      , orgPhoneText , orgFaxText, orgWebText, orgEmailText;
            string debtorAddressText , debtorAddressTabbedText;
            if (Utilities.GetAddressType().ToString() == "Contact")
            {
                Contact patientAddress = invoice.Booking == null || invoice.Booking.Patient == null || addressHash[invoice.Booking.Organisation.EntityID] == null ? null : ((Contact[])addressHash[invoice.Booking.Organisation.EntityID])[0];
                patientAddressText       = patientAddress != null ? patientAddress.GetFormattedAddress("No address found")    : "No address found";
                patientAddressTabbedText = patientAddress != null ? patientAddress.GetFormattedAddress("No address found", 1) : "No address found";

                Contact orgAddress = invoice.Booking == null || invoice.Booking.Organisation == null || addressHash[invoice.Booking.Organisation.EntityID] == null ? (Contact)siteAddress : ((Contact[])addressHash[invoice.Booking.Organisation.EntityID])[0];
                Contact orgPhone   = invoice.Booking == null || invoice.Booking.Organisation == null || phoneHash  [invoice.Booking.Organisation.EntityID] == null ? (Contact)sitePhone   : ((Contact[])phoneHash  [invoice.Booking.Organisation.EntityID])[0];
                Contact orgFax     = invoice.Booking == null || invoice.Booking.Organisation == null || faxHash    [invoice.Booking.Organisation.EntityID] == null ? (Contact)siteFax     : ((Contact[])faxHash    [invoice.Booking.Organisation.EntityID])[0];
                Contact orgWeb     = invoice.Booking == null || invoice.Booking.Organisation == null || webHash    [invoice.Booking.Organisation.EntityID] == null ? (Contact)siteWeb     : ((Contact[])webHash    [invoice.Booking.Organisation.EntityID])[0];
                Contact orgEmail   = invoice.Booking == null || invoice.Booking.Organisation == null || emailHash  [invoice.Booking.Organisation.EntityID] == null ? (Contact)siteEmail   : ((Contact[])emailHash  [invoice.Booking.Organisation.EntityID])[0];

                orgAddressText            = orgAddress     == null    ? "No address found"      : orgAddress.GetFormattedAddress("No address found");
                orgAddressTabbedText      = orgAddress     == null    ? "No address found"      : orgAddress.GetFormattedAddress("No address found", 1);
                orgPhoneText              = orgPhone       == null    ? "No phone number found" : orgPhone.GetFormattedPhoneNumber("No phone number found");
                orgFaxText                = orgFax         == null    ? "No fax number found"   : orgFax.GetFormattedPhoneNumber("No fax number found");
                orgWebText                = orgWeb         == null    ? "No website found"      : orgWeb.AddrLine1;
                orgEmailText              = orgEmail       == null    ? "No email found"        : orgEmail.AddrLine1;

                Contact debtorAddress     = debtorEntityID == -1 || addressHash[debtorEntityID] == null ? null : ((Contact[])addressHash[debtorEntityID])[0];
                debtorAddressText         = debtorAddress != null ? debtorAddress.GetFormattedAddress("No address found")    : "No address found";
                debtorAddressTabbedText   = debtorAddress != null ? debtorAddress.GetFormattedAddress("No address found", 1) : "No address found";

                // if AC && debtor is PT && no address found for PT .. then use fac address
                if (!isClinicInvoice && debtorIsPatient != null && debtorIsPatient.Value == true && debtorAddress == null)
                {
                    debtorAddressText       = orgAddressText;
                    debtorAddressTabbedText = orgAddressTabbedText;
                }
            }
            else if (Utilities.GetAddressType().ToString() == "ContactAus")
            {
                ContactAus patientAddress = invoice.Booking == null || invoice.Booking.Patient == null || addressHash[invoice.Booking.Organisation.EntityID] == null ? null : ((ContactAus[])addressHash[invoice.Booking.Organisation.EntityID])[0];
                patientAddressText       = patientAddress != null ? patientAddress.GetFormattedAddress("No address found")    : "No address found";
                patientAddressTabbedText = patientAddress != null ? patientAddress.GetFormattedAddress("No address found", 1) : "No address found";

                ContactAus orgAddress = invoice.Booking == null || invoice.Booking.Organisation == null || addressHash[invoice.Booking.Organisation.EntityID] == null ? (ContactAus)siteAddress : ((ContactAus[])addressHash[invoice.Booking.Organisation.EntityID])[0];
                ContactAus orgPhone   = invoice.Booking == null || invoice.Booking.Organisation == null || phoneHash  [invoice.Booking.Organisation.EntityID] == null ? (ContactAus)sitePhone   : ((ContactAus[])phoneHash  [invoice.Booking.Organisation.EntityID])[0];
                ContactAus orgFax     = invoice.Booking == null || invoice.Booking.Organisation == null || faxHash    [invoice.Booking.Organisation.EntityID] == null ? (ContactAus)siteFax     : ((ContactAus[])faxHash    [invoice.Booking.Organisation.EntityID])[0];
                ContactAus orgWeb     = invoice.Booking == null || invoice.Booking.Organisation == null || webHash    [invoice.Booking.Organisation.EntityID] == null ? (ContactAus)siteWeb     : ((ContactAus[])webHash    [invoice.Booking.Organisation.EntityID])[0];
                ContactAus orgEmail   = invoice.Booking == null || invoice.Booking.Organisation == null || emailHash  [invoice.Booking.Organisation.EntityID] == null ? (ContactAus)siteEmail   : ((ContactAus[])emailHash  [invoice.Booking.Organisation.EntityID])[0];

                orgAddressText            = orgAddress     == null    ? "No address found"      : orgAddress.GetFormattedAddress("No address found");
                orgAddressTabbedText      = orgAddress     == null    ? "No address found"      : orgAddress.GetFormattedAddress("No address found", 1);
                orgPhoneText              = orgPhone       == null    ? "No phone number found" : orgPhone.GetFormattedPhoneNumber("No phone number found");
                orgFaxText                = orgFax         == null    ? "No fax number found"   : orgFax.GetFormattedPhoneNumber("No fax number found");
                orgWebText                = orgWeb         == null    ? "No website found"      : orgWeb.AddrLine1;
                orgEmailText              = orgEmail       == null    ? "No email found"        : orgEmail.AddrLine1;

                ContactAus debtorAddress     = debtorEntityID == -1 || addressHash[debtorEntityID] == null ? null : ((ContactAus[])addressHash[debtorEntityID])[0];
                debtorAddressText         = debtorAddress != null ? debtorAddress.GetFormattedAddress("No address found")    : "No address found";
                debtorAddressTabbedText   = debtorAddress != null ? debtorAddress.GetFormattedAddress("No address found", 1) : "No address found";

                // if AC && debtor is PT && no address found for PT .. then use fac address
                if (!isClinicInvoice && debtorIsPatient != null && debtorIsPatient.Value == true && debtorAddress == null)
                {
                    debtorAddressText       = orgAddressText;
                    debtorAddressTabbedText = orgAddressTabbedText;
                }
            }
            else
                throw new Exception("Unknown AddressType in config: " + Utilities.GetAddressType().ToString().ToString());

            if (invoice.Booking != null)
            {
                string ptName = string.Empty;
                if (invoice.Booking != null && invoice.Booking.Patient != null)
                    ptName = invoice.Booking.Patient.Person.FullnameWithoutMiddlename;
                if (invoice.Booking == null && invoice.PayerPatient != null)
                    ptName = invoice.PayerPatient.Person.FullnameWithoutMiddlename;

                sourceDataSet.Tables[0].Rows.Add(
                    DateTime.Now.ToString("d MMMM, yyyy"),
                    invoice.InvoiceID.ToString() + (invoice.HealthcareClaimNumber.Trim().Length > 0 ? "  (Claim No. " + invoice.HealthcareClaimNumber.Trim() + ")" : ""),
                    invoice.InvoiceDateAdded.ToString("d MMMM, yyyy"),
                    debtorName,
                    debtorAddressText,
                    debtorAddressTabbedText,
                    ptName,
                    patientAddressText,
                    patientAddressTabbedText,
                    invoice.Booking == null ? string.Empty : invoice.Booking.Provider.Person.FullnameWithoutMiddlename,
                    isClinicInvoice ? providerNbrThisOrg : providerNbrThisStaff,
                    invoice.Booking == null ? string.Empty : invoice.Booking.DateStart.ToString("d MMMM, yyyy"),
                    nextBookingText,
                    invoice.Booking != null && invoice.Booking.Patient != null && invoice.Booking.Patient.IsCompany ? "Purchase Order Nbr. " + invoice.Booking.SterilisationCode : " ",

                    ptName,
                    patientAddressText,
                    patientAddressTabbedText,
                    //patientAddress == null || patientAddress.AddrLine1.Length == 0  ? "No address found" : patientAddress.AddrLine1,
                    //patientAddress == null || patientAddress.AddrLine2.Length == 0  ? " " : patientAddress.AddrLine2,
                    //patientAddress == null || patientAddress.AddressChannel == null ? " " : (patientAddress.AddressChannel.AddressChannelID == 1 ? " " : patientAddress.AddressChannel.DisplayName),
                    //patientAddress == null || patientAddress.Suburb  == null        ? " " : patientAddress.Suburb.Name,
                    //patientAddress == null || patientAddress.Suburb  == null        ? " " : patientAddress.Suburb.Postcode,
                    //patientAddress == null || patientAddress.Country == null        ? " " : patientAddress.Country.Descr

                    invoice.Booking == null ? invoice.NonBookinginvoiceOrganisation.Name : invoice.Booking.Organisation.Name,
                    invoice.Booking == null ? invoice.NonBookinginvoiceOrganisation.Abn : invoice.Booking.Organisation.Abn,
                    invoice.Booking == null ? invoice.NonBookinginvoiceOrganisation.Acn : invoice.Booking.Organisation.Acn,
                    invoice.Booking == null ? invoice.NonBookinginvoiceOrganisation.BpayAccount : invoice.Booking.Organisation.BpayAccount,
                    orgAddressText,
                    orgAddressTabbedText,
                    orgPhoneText,
                    orgFaxText,
                    orgWebText,
                    orgEmailText
                    );
            }
            else
            {
                sourceDataSet.Tables[0].Rows.Add(
                    DateTime.Now.ToString("d MMMM, yyyy"),
                    invoice.InvoiceID.ToString(),
                    invoice.InvoiceDateAdded.ToString("d MMMM, yyyy"),
                    invoice.PayerPatient == null ? "--" : invoice.PayerPatient.Person.FullnameWithTitleWithoutMiddlename,

                    invoice.NonBookinginvoiceOrganisation.Name,
                    invoice.NonBookinginvoiceOrganisation.Abn,
                    invoice.NonBookinginvoiceOrganisation.Acn,
                    invoice.NonBookinginvoiceOrganisation.BpayAccount,
                    orgAddressText,
                    orgAddressTabbedText,
                    orgPhoneText,
                    orgFaxText,
                    orgWebText,
                    orgEmailText
                    );
            }

            // create table data to populate from invoice lines

            string[,] tblInfo;

            if (isMedicareInvoice)
            {
                tblInfo = new string[lines.Length + 2, 4];

                int row = 0;
                for (int i = 0; i < lines.Length; i++, row++)
                {
                    tblInfo[row, 0] = lines[i].Offering.Name + (invoiceGapPayments ? " - bulk billed to Medicare" : " - normally $" + lines[i].Offering.DefaultPrice.ToString() + " but bulk billed to Medicare");
                    tblInfo[row, 1] = ((lines[i].Quantity % 1) == 0) ? Convert.ToInt32(lines[i].Quantity).ToString() : lines[i].Quantity.ToString();
                    tblInfo[row, 2] = string.Empty;
                    tblInfo[row, 3] = "0.00";
                }

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = string.Empty;
                tblInfo[row, 3] = string.Empty;
                row++;

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = "<align=right><b>Balance Due: </b></align>";
                tblInfo[row, 3] = "<b>0.00</b>";
                row++;
            }
            else if (isTACInvoice)
            {
                tblInfo = new string[lines.Length + 2, 4];

                int row = 0;
                for (int i = 0; i < lines.Length; i++, row++)
                {
                    tblInfo[row, 0] = lines[i].Offering.Name;
                    tblInfo[row, 1] = ((lines[i].Quantity % 1) == 0) ? Convert.ToInt32(lines[i].Quantity).ToString() : lines[i].Quantity.ToString();
                    tblInfo[row, 2] = string.Empty;
                    tblInfo[row, 3] = lines[i].Price.ToString();
                }

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = string.Empty;
                tblInfo[row, 3] = string.Empty;
                row++;

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = "<align=right><b>Balance Due: </b></align>";
                tblInfo[row, 3] = "<b>" + invoice.TotalDue.ToString() + "</b>";
                row++;
            }
            else if (invoice.Booking == null)  // private invoice
            {
                tblInfo = new string[lines.Length + receipts.Length + creditNotes.Length + 4, 4];

                int row = 0;
                for (int i = 0; i < lines.Length; i++, row++)
                {
                    tblInfo[row, 0] = lines[i].Offering.Name;
                    tblInfo[row, 1] = ((lines[i].Quantity % 1) == 0) ? Convert.ToInt32(lines[i].Quantity).ToString() : lines[i].Quantity.ToString();
                    tblInfo[row, 2] = string.Empty;
                    tblInfo[row, 3] = lines[i].Price.ToString();
                }
                for (int i = 0; i < receipts.Length; i++, row++)
                {
                    tblInfo[row, 0] = "Receipt " + receipts[i].ReceiptID + " - " + receipts[i].ReceiptPaymentType.Descr;
                    tblInfo[row, 1] = "1";
                    tblInfo[row, 2] = string.Empty;
                    tblInfo[row, 3] = receipts[i].Total.ToString();
                }
                for (int i = 0; i < creditNotes.Length; i++, row++)
                {
                    tblInfo[row, 0] = "Adjustment Note  " + creditNotes[i].CreditNoteID;
                    tblInfo[row, 1] = "1";
                    tblInfo[row, 2] = string.Empty;
                    tblInfo[row, 3] = creditNotes[i].Total.ToString();
                }

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = string.Empty;
                tblInfo[row, 3] = string.Empty;
                row++;

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = "<align=right><b>GST: </b></align>";
                tblInfo[row, 3] = invoice.Gst.ToString();
                row++;

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = "<align=right><b>Payments & Adjustments: </b></align>";
                tblInfo[row, 3] = (invoice.ReceiptsTotal + invoice.CreditNotesTotal).ToString();
                row++;

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = "<align=right><b>Balance Due: </b></align>";
                tblInfo[row, 3] = "<b>" + invoice.TotalDue.ToString() + "</b>";
                row++;
            }
            else if (isClinicInvoice)
            {
                tblInfo = new string[lines.Length + receipts.Length + creditNotes.Length + 4, 4];

                int row = 0;
                for (int i = 0; i < lines.Length; i++, row++)
                {
                    tblInfo[row, 0] = lines[i].Offering.Name + (i == lines.Length - 1 && message.Length > 0 ? Environment.NewLine + message : "");
                    tblInfo[row, 1] = ((lines[i].Quantity % 1) == 0) ? Convert.ToInt32(lines[i].Quantity).ToString() : lines[i].Quantity.ToString();
                    tblInfo[row, 2] = string.Empty;
                    tblInfo[row, 3] = lines[i].Price.ToString();
                }
                for (int i = 0; i < receipts.Length; i++, row++)
                {
                    tblInfo[row, 0] = "Receipt " + receipts[i].ReceiptID + " - " + receipts[i].ReceiptPaymentType.Descr;
                    tblInfo[row, 1] = "1";
                    tblInfo[row, 2] = string.Empty;
                    tblInfo[row, 3] = receipts[i].Total.ToString();
                }
                for (int i = 0; i < creditNotes.Length; i++, row++)
                {
                    tblInfo[row, 0] = "Adjustment Note  " + creditNotes[i].CreditNoteID;
                    tblInfo[row, 1] = "1";
                    tblInfo[row, 2] = string.Empty;
                    tblInfo[row, 3] = creditNotes[i].Total.ToString();
                }

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = string.Empty;
                tblInfo[row, 3] = string.Empty;
                row++;

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = "<align=right><b>GST: </b></align>";
                tblInfo[row, 3] = invoice.Gst.ToString();
                row++;

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = "<align=right><b>Payments & Adjustments: </b></align>";
                tblInfo[row, 3] = (invoice.ReceiptsTotal + invoice.CreditNotesTotal).ToString();
                row++;

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = "<align=right><b>Balance Due: </b></align>";
                tblInfo[row, 3] = "<b>" + invoice.TotalDue.ToString() + "</b>";
                row++;
            }
            else // isAgedCareInvoice (private)
            {
                tblInfo = new string[lines.Length + receipts.Length + creditNotes.Length + 4, 6];

                int row = 0;
                for (int i = 0; i < lines.Length; i++, row++)
                {

                    // 0 = i (row nbr)
                    // 1 = room (addr1 of patient)
                    // 2 = patient name
                    // 3 = offering
                    // 4 = qty
                    // 5 = space
                    // 6 = price

                    string ptBedroom = PatientsContactCacheDB.GetBedroom(isClinicInvoice ? null : acPtBedroomHash, lines[i].Patient.Person.EntityID);

                    tblInfo[row, 0] = (row + 1).ToString();
                    tblInfo[row, 1] = ptBedroom == null ? string.Empty : ptBedroom;
                    tblInfo[row, 2] = lines[i].Patient.Person.FullnameWithoutMiddlename;
                    tblInfo[row, 3] = (lines[i].Offering == null ? "" : lines[i].Offering.Name) + (i == lines.Length - 1 && message.Length > 0 ? Environment.NewLine + Environment.NewLine + message : "");
                    tblInfo[row, 4] = ((lines[i].Quantity % 1) == 0) ? Convert.ToInt32(lines[i].Quantity).ToString() : lines[i].Quantity.ToString(); ;
                    tblInfo[row, 5] = lines[i].Price.ToString();
                }
                for (int i = 0; i < receipts.Length; i++, row++)
                {
                    tblInfo[row, 0] = string.Empty;
                    tblInfo[row, 1] = string.Empty;
                    tblInfo[row, 2] = string.Empty;
                    tblInfo[row, 3] = "Receipt " + receipts[i].ReceiptID + " - " + receipts[i].ReceiptPaymentType.Descr;
                    tblInfo[row, 4] = string.Empty;
                    tblInfo[row, 5] = receipts[i].Total.ToString();
                }
                for (int i = 0; i < creditNotes.Length; i++, row++)
                {
                    tblInfo[row, 0] = string.Empty;
                    tblInfo[row, 1] = string.Empty;
                    tblInfo[row, 2] = string.Empty;
                    tblInfo[row, 3] = "Adjustment Note  " + creditNotes[i].CreditNoteID;
                    tblInfo[row, 4] = string.Empty;
                    tblInfo[row, 5] = creditNotes[i].Total.ToString();
                }

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = string.Empty;
                tblInfo[row, 3] = string.Empty;
                tblInfo[row, 4] = string.Empty;
                tblInfo[row, 5] = string.Empty;
                row++;

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = string.Empty;
                tblInfo[row, 3] = "<align=right><b>GST: </b></align>";
                tblInfo[row, 4] = string.Empty;
                tblInfo[row, 5] = invoice.Gst.ToString();
                row++;

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = string.Empty;
                tblInfo[row, 3] = "<align=right><b>Payments & Adjustments: </b></align>";
                tblInfo[row, 4] = string.Empty;
                tblInfo[row, 5] = (invoice.ReceiptsTotal + invoice.CreditNotesTotal).ToString();
                row++;

                tblInfo[row, 0] = string.Empty;
                tblInfo[row, 1] = string.Empty;
                tblInfo[row, 2] = string.Empty;
                tblInfo[row, 3] = "<align=right><b>Balance Due: </b></align>";
                tblInfo[row, 4] = string.Empty;
                tblInfo[row, 5] = "<b>" + invoice.TotalDue.ToString() + "</b>";
                row++;
            }

            // merge

            string errorString = null;
            WordMailMerger.Merge(

                originalFile,
                outputFile,
                sourceDataSet,

                tblInfo,
                1,
                true,

                true,
                null,
                true,
                ((SystemVariables)System.Web.HttpContext.Current.Session["SystemVariables"])["EziDebit_Enabled"].Value != "1" ? null : @"https://portal.mediclinic.com.au/InvoicePaymentV2.aspx?id=" + Invoice.EncodeInvoiceHash(invoice.InvoiceID, System.Web.HttpContext.Current.Session["DB"].ToString()),
                out errorString);

            if (errorString != string.Empty)
                throw new Exception(errorString);

            if (!isBookingInvoice)
                filePaths_PrivateInvoices.Add(outputFile);
            else if (isClinicInvoice)
                filePaths_BookingClinicInvoices.Add(outputFile);
            else
                filePaths_BookingACInvoices.Add(outputFile);
        }

        // then merge them all into pdfs of each template type
        if (filePaths_BookingClinicInvoices.Count > 0)
            MergeInvoices((string[])filePaths_BookingClinicInvoices.ToArray(typeof(string)), tmpLettersDirectory + @"InvoiceTemplate.pdf",        true);
        if (filePaths_BookingACInvoices.Count > 0)
            MergeInvoices((string[])filePaths_BookingACInvoices.ToArray(typeof(string)),     tmpLettersDirectory + @"InvoiceTemplateAC.pdf",      true);
        if (filePaths_PrivateInvoices.Count > 0)
            MergeInvoices((string[])filePaths_PrivateInvoices.ToArray(typeof(string)),       tmpLettersDirectory + @"PrivateInvoiceTemplate.pdf", true);

        // zip em
        string zipFileName = "Invoices.zip";
        string zipFilePath = tmpLettersDirectory2 + zipFileName;
        ICSharpCode.SharpZipLib.Zip.FastZip zip = new ICSharpCode.SharpZipLib.Zip.FastZip();
        zip.CreateEmptyDirectories = true;
        zip.CreateZip(zipFilePath, tmpLettersDirectory, true, "");

        // get filecontents of zip here
        Letter.FileContents zipFileContents = new Letter.FileContents(zipFilePath, zipFileName);

        // delete files
        if (filePaths_BookingClinicInvoices.Count > 0)
            File.Delete(tmpLettersDirectory + @"InvoiceTemplate.pdf");
        if (filePaths_BookingACInvoices.Count > 0)
            File.Delete(tmpLettersDirectory + @"InvoiceTemplateAC.pdf");
        if (filePaths_PrivateInvoices.Count > 0)
            File.Delete(tmpLettersDirectory + @"PrivateInvoiceTemplate.pdf");

        System.IO.File.SetAttributes(zipFilePath, FileAttributes.Normal);
        System.IO.File.Delete(zipFilePath);
        System.IO.File.SetAttributes(tmpLettersDirectory, FileAttributes.Normal);
        System.IO.Directory.Delete(tmpLettersDirectory, true);
        System.IO.File.SetAttributes(tmpLettersDirectory2, FileAttributes.Normal);
        System.IO.Directory.Delete(tmpLettersDirectory2, true);

        // Nothing gets past the "DownloadDocument" method because it outputs the file
        // which is writing a response to the client browser and calls Response.End()
        // So make sure any other code that functions goes before this
        Letter.DownloadDocument(response, zipFileContents.Contents, zipFileContents.DocName);
    }
    protected void btnPrint_Click(object sender, EventArgs e)
    {
        // re-fill grid in case two broswer windows are open with 2 different booking lists and only the one on the other page is in the session memory...
        FillGrid();

        try
        {
            string originalFile        = Letter.GetLettersDirectory() + @"BookingList.docx";
            string tmpLettersDirectory = Letter.GetTempLettersDirectory();
            string tmpOutputFile       = FileHelper.GetTempFileName(tmpLettersDirectory + "BookingList." + System.IO.Path.GetExtension(originalFile));

            // create table data to populate

            DataTable dt      = Session["bookinglist_data"] as DataTable;
            string[,] tblInfo = null;
            bool tblEmpty = (dt.Rows.Count == 1 && dt.Rows[0][0] == DBNull.Value);
            if (tblEmpty)
            {
                tblInfo = new string[1, 4];
                tblInfo[0, 0] = "No Bookings Found";
                tblInfo[0, 1] = "";
                tblInfo[0, 2] = "";
                tblInfo[0, 3] = "";
            }
            else
            {
                tblInfo = new string[dt.Rows.Count, 4];
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    Booking booking = BookingDB.LoadFull(dt.Rows[i]);
                    tblInfo[i, 0] = booking.DateStart.ToString("d MMM") + " " + booking.DateStart.ToString("h:mm") + " - " + booking.DateEnd.ToString("h:mm") + (booking.DateEnd.Hour < 12 ? "am" : "pm");
                    tblInfo[i, 1] = booking.Patient == null ? "" : booking.Patient.Person.FullnameWithoutMiddlename;
                    tblInfo[i, 2] = booking.Provider.Person.FullnameWithoutMiddlename;
                    tblInfo[i, 3] = booking.Organisation.Name;
                }
            }

            // create empty dataset

            System.Data.DataSet sourceDataSet = new System.Data.DataSet();
            sourceDataSet.Tables.Add("MergeIt");

            // merge

            string errorString = null;
            WordMailMerger.Merge(

                originalFile,
                tmpOutputFile,
                sourceDataSet,

                tblInfo,
                1,
                true,

                true,
                null,
                true,
                null,
                out errorString);

            if (errorString != string.Empty)
                throw new CustomMessageException(errorString);

            Letter.FileContents fileContents = new Letter.FileContents(System.IO.File.ReadAllBytes(tmpOutputFile), "BookingList." + System.IO.Path.GetExtension(originalFile));
            System.IO.File.Delete(tmpOutputFile);

            // Nothing gets past the "DownloadDocument" method because it outputs the file
            // which is writing a response to the client browser and calls Response.End()
            // So make sure any other code that functions goes before this
            Letter.DownloadDocument(Response, fileContents.Contents, fileContents.DocName);
        }
        catch(CustomMessageException cmEx)
        {
            SetErrorMessage(cmEx.Message);
        }
        catch(Exception ex)
        {
            SetErrorMessage(ex.ToString());
        }
    }
    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 btnExport_Click(object sender, EventArgs e)
    {
        Booking booking    = BookingDB.GetByID(GetFormBooking());
        bool    isAgedCare = booking.Organisation.IsAgedCare;

        string tmpLettersDirectory = FileHelper.GetTempDirectoryName(Letter.GetTempLettersDirectory());
        Directory.CreateDirectory(tmpLettersDirectory);

        string templateFileName = isAgedCare ? "ACTreatmentList.docx" : "TreatmentList.docx";
        string originalFile = Letter.GetLettersDirectory() + templateFileName;
        string tmpOutputFile = tmpLettersDirectory + "TreatmentList.pdf"; // System.IO.Path.GetExtension(originalFile));

        if (!File.Exists(originalFile))
        {
            SetErrorMessage("Template File '" + templateFileName + "' does not exist.");
            return;
        }

        MergeFile(isAgedCare, originalFile, tmpOutputFile);

        Letter.FileContents fileContents = new Letter.FileContents(System.IO.File.ReadAllBytes(tmpOutputFile), "TreatmentList.pdf");
        File.Delete(tmpOutputFile);
        System.IO.File.SetAttributes(tmpLettersDirectory, FileAttributes.Normal);
        System.IO.Directory.Delete(tmpLettersDirectory, true);

        // Nothing gets past the "DownloadDocument" method because it outputs the file
        // which is writing a response to the client browser and calls Response.End()
        // So make sure any other code that functions goes before this
        Letter.DownloadDocument(Response, fileContents.Contents, fileContents.DocName);
    }
Пример #11
0
    protected void Run(bool incDisplay, bool incSending)
    {
        // 1. get all fields from systemvariables

        bool   EnableEmails = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_SendEmail").Value) == 1;
        string EmailAddress = SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_EmailAddress").Value;

        bool IncClinicsAuto  = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_IncClinic").Value) == 1;
        bool IncAgedCareAuto = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_IncAgedCare").Value) == 1;

        bool IncUnsentAuto  = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_IncUnsent").Value) == 1;
        bool IncBatchedAuto = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_IncBatched").Value) == 1;

        ReferrerEPCLettersSending.SendMethod sendMethod = SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_SendMethod").Value == "Email" ?
                                                          ReferrerEPCLettersSending.SendMethod.Email_To_Referrer :
                                                          ReferrerEPCLettersSending.SendMethod.Batch;

        bool SendMondays    = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_SendMondays").Value) == 1;
        bool SendTuesdays   = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_SendTuesdays").Value) == 1;
        bool SendWednesdays = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_SendWednesdays").Value) == 1;
        bool SendThursdays  = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_SendThursdays").Value) == 1;
        bool SendFridays    = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_SendFridays").Value) == 1;
        bool SendSaturdays  = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_SendSaturdays").Value) == 1;
        bool SendSundays    = Convert.ToInt32(SystemVariableDB.GetByDescr("ReferrerEPCAutoGenerateLettersEmail_SendSundays").Value) == 1;



        // 2. validate

        if (!EnableEmails)
        {
            return;
        }
        if (!Utilities.IsValidEmailAddresses(EmailAddress, false))
        {
            return;
        }
        if (!IncClinicsAuto && !IncAgedCareAuto)
        {
            return;
        }

        if (DateTime.Today.DayOfWeek == DayOfWeek.Monday && !SendMondays)
        {
            return;
        }
        if (DateTime.Today.DayOfWeek == DayOfWeek.Tuesday && !SendTuesdays)
        {
            return;
        }
        if (DateTime.Today.DayOfWeek == DayOfWeek.Wednesday && !SendWednesdays)
        {
            return;
        }
        if (DateTime.Today.DayOfWeek == DayOfWeek.Thursday && !SendThursdays)
        {
            return;
        }
        if (DateTime.Today.DayOfWeek == DayOfWeek.Friday && !SendFridays)
        {
            return;
        }
        if (DateTime.Today.DayOfWeek == DayOfWeek.Saturday && !SendSaturdays)
        {
            return;
        }
        if (DateTime.Today.DayOfWeek == DayOfWeek.Sunday && !SendSundays)
        {
            return;
        }



        // 3. run it

        int siteID = -1;

        if (IncClinicsAuto && IncAgedCareAuto)
        {
            siteID = -1;
        }
        else if (IncClinicsAuto && !IncAgedCareAuto)
        {
            foreach (Site s in SiteDB.GetAll())
            {
                if (s.SiteType.ID == 1)
                {
                    siteID = s.SiteID;
                }
            }
        }
        else if (!IncClinicsAuto && IncAgedCareAuto)
        {
            foreach (Site s in SiteDB.GetAll())
            {
                if (s.SiteType.ID == 2)
                {
                    siteID = s.SiteID;
                }
            }
        }


        string outputInfo;
        string outputList;

        Letter.FileContents fileContents = ReferrerEPCLettersSending.Run(
            sendMethod,
            siteID,
            -1,
            -1,
            IncBatchedAuto,
            IncUnsentAuto,
            !incSending,
            false,
            out outputInfo,
            out outputList,
            string.Empty
            );

        if (incDisplay)
        {
            Response.Write(outputInfo + "<br /><br />" + outputList);
        }



        // 4. Put in file and email it

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

            string tmpDir = FileHelper.GetTempDirectoryName(tmpLettersDirectory);
            System.IO.Directory.CreateDirectory(tmpDir);
            string tmpFileName = tmpDir + fileContents.DocName;
            System.IO.File.WriteAllBytes(tmpFileName, fileContents.Contents);

            Emailer.SimpleEmail(EmailAddress, "Automated Referral Letters [" + ((SystemVariables)Session["SystemVariables"])["Site"].Value + "]", "Please find attached referral letters to send to referrers.<br /><br />Regards,<br />Mediclinic", true, new string[] { tmpFileName }, null);

            System.IO.File.Delete(tmpFileName);
            System.IO.Directory.Delete(tmpDir);
        }
    }
Пример #12
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 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);
    }
    protected void btnPrintBookingList_Click(object sender, EventArgs e)
    {
        DataTable tblBookingList = SetBookingsList();

        if (tblBookingList == null)
        {
            return;
        }

        try
        {
            string originalFile        = Letter.GetLettersDirectory() + @"BookingListForPatient.docx";
            string tmpLettersDirectory = Letter.GetTempLettersDirectory();
            string tmpOutputFile       = FileHelper.GetTempFileName(tmpLettersDirectory + "BookingList." + System.IO.Path.GetExtension(originalFile));


            // create table data to populate

            DataTable dt = tblBookingList;
            string[,] tblInfo = null;
            bool tblEmpty = (dt.Rows.Count == 1 && dt.Rows[0][0] == DBNull.Value);
            if (tblEmpty)
            {
                tblInfo       = new string[1, 4];
                tblInfo[0, 0] = "No Bookings Found";
                tblInfo[0, 1] = "";
                tblInfo[0, 2] = "";
                tblInfo[0, 3] = "";
            }
            else
            {
                tblInfo = new string[dt.Rows.Count, 4];
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    string inv_type_text = tblBookingList.Rows[i]["inv_type_text"].ToString();
                    if (inv_type_text.Length > 0)
                    {
                        inv_type_text = " (" + inv_type_text + ")";
                    }

                    Booking booking = BookingDB.LoadFull(dt.Rows[i]);
                    tblInfo[i, 0] = booking.DateStart.ToString("d MMM yyyy") + Environment.NewLine + booking.DateStart.ToString("h:mm") + " - " + booking.DateEnd.ToString("h:mm") + (booking.DateEnd.Hour < 12 ? "am" : "pm");
                    tblInfo[i, 1] = booking.Patient == null ? "" : booking.Patient.Person.FullnameWithoutMiddlename;
                    tblInfo[i, 2] = (booking.Offering == null ? "" : booking.Offering.Name + Environment.NewLine) + booking.Provider.Person.FullnameWithoutMiddlename + " @ " + booking.Organisation.Name;
                    tblInfo[i, 3] = booking.BookingStatus.Descr + Environment.NewLine + inv_type_text;
                }
            }


            // create empty dataset

            System.Data.DataSet sourceDataSet = new System.Data.DataSet();
            sourceDataSet.Tables.Add("MergeIt");


            // merge

            string errorString = null;
            WordMailMerger.Merge(

                originalFile,
                tmpOutputFile,
                sourceDataSet,

                tblInfo,
                1,
                true,

                false,
                null,
                true,
                null,
                out errorString);

            if (errorString != string.Empty)
            {
                throw new CustomMessageException(errorString);
            }

            Letter.FileContents fileContents = new Letter.FileContents(System.IO.File.ReadAllBytes(tmpOutputFile), "BookingList." + System.IO.Path.GetExtension(originalFile));
            System.IO.File.Delete(tmpOutputFile);


            // Nothing gets past the "DownloadDocument" method because it outputs the file
            // which is writing a response to the client browser and calls Response.End()
            // So make sure any other code that functions goes before this
            Letter.DownloadDocument(Response, fileContents.Contents, fileContents.DocName);
        }
        catch (CustomMessageException cmEx)
        {
            SetErrorMessage(cmEx.Message);
        }
        catch (Exception ex)
        {
            SetErrorMessage(ex.ToString());
        }
    }
    private void InvoiceItemsControl_SubmitButtonClicked(object sender, EventArgs e)
    {
        bool showDownloadPopup = false;
        bool refresh_on_close = (Request.QueryString["refresh_on_close"] != null && Request.QueryString["refresh_on_close"] == "1");

        try
        {
            ///////////////
            // validation
            ///////////////

            Booking booking = GetFormBooking();
            if (booking == null)
                throw new CustomMessageException("Invalid booking");
            if (booking.BookingStatus.ID != 0)
                throw new CustomMessageException("Booking already set as : " + BookingDB.GetStatusByID(booking.BookingStatus.ID).Descr);
            if (InvoiceDB.GetCountByBookingID(booking.BookingID) > 0) // shouldnt get here since should have been set as completed and thrown in error above
                throw new CustomMessageException("Booking already has an invoice");

            ///////////////////
            // create invoice
            ///////////////////

            // keep id's to delete if exception and need to roll back
            int     hcInvID       = -2;
            int     nonHcInvID    = -2;
            decimal nonHcInvTotal =  0;
            ArrayList  invLineIDs = new ArrayList();
            ArrayList  offeringOrderIDs = new ArrayList();
            HealthCard hc = HealthCardDB.GetActiveByPatientID(booking.Patient.PatientID);
            HealthCardEPCRemaining[] epcsRemaining = hc == null ? new HealthCardEPCRemaining[] { } : HealthCardEPCRemainingDB.GetByHealthCardID(hc.HealthCardID, booking.Offering.Field.ID);
            HealthCardEPCRemaining[] epcsRemainingOriginal = HealthCardEPCRemaining.CloneList(epcsRemaining);

            // used to check update stock and check warning level emails sent
            ArrayList invoiceLines = new ArrayList();

            try
            {
                DataTable dt_selected_list = invoiceItemsControl.GetSelectedList();

                bool isCancelation = GetFormIsCancelation();
                Booking.InvoiceType invType = isCancelation || GetFormIsPrivateInv() ? Booking.InvoiceType.None : GetInvoiceType();
                int orgID = Booking.GetInvoiceTypeOrgID(invType);  // "org id"  -- clinic inv:  medicare, dva, or null for non medicare/dva (ie patient) booking ...

                // [107='Clinic Invoice', 363='Aged Care Invoice', 108='Standard Invoice']
                int docType = booking.Organisation.OrganisationType.OrganisationTypeID == 218 ? 107 : 363;

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

                decimal ptTotal     = 0;
                decimal hcTotal     = 0;
                decimal ptGST       = 0;
                decimal hcGST       = 0;
                int     ptItemCount = 0;
                int     hcItemCount = 0;
                for (int i = 0; i < dt_selected_list.Rows.Count; i++)
                {
                    decimal total_hc_price = Convert.ToDecimal(dt_selected_list.Rows[i]["total_hc_price"]);
                    decimal total_pt_price = Convert.ToDecimal(dt_selected_list.Rows[i]["total_pt_price"]);
                    decimal total_hc_gst   = Convert.ToDecimal(dt_selected_list.Rows[i]["total_hc_gst"]);
                    decimal total_pt_gst   = Convert.ToDecimal(dt_selected_list.Rows[i]["total_pt_gst"]);
                    bool    totalZero = total_hc_price + total_pt_price == 0;
                    bool    hcPaid    = Convert.ToBoolean(dt_selected_list.Rows[i]["hc_paid"]);

                    if (total_hc_price > 0 || (totalZero && hcPaid))
                    {
                        hcTotal += total_hc_price;
                        hcGST   += total_hc_gst;
                        hcItemCount++;
                    }
                    if (total_pt_price > 0 || (totalZero && !hcPaid))
                    {
                        ptTotal += total_pt_price;
                        ptGST   += total_pt_gst;
                        ptItemCount++;
                    }
                }

                // add healthcare invoice
                if (hcItemCount > 0)
                {
                    hcInvID = InvoiceDB.Insert(docType, booking.BookingID, (invType != Booking.InvoiceType.Insurance ? orgID : hc.Organisation.OrganisationID), -1, 0, (invType != Booking.InvoiceType.Insurance ? "" : hc.CardNbr), "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), hcTotal + hcGST, hcGST, false, false, false, DateTime.MinValue);

                    //if (Convert.ToInt32(SystemVariableDB.GetByDescr("AutoMedicareClaiming").Value) == 1)
                    //    MedicareClaimNbrDB.InsertIntoInvoice(hcInvID, DateTime.Now.Date);

                    for (int i = 0; i < dt_selected_list.Rows.Count; i++)
                    {
                        decimal total_hc_price   = Convert.ToDecimal(dt_selected_list.Rows[i]["total_hc_price"]);
                        decimal total_pt_price   = Convert.ToDecimal(dt_selected_list.Rows[i]["total_pt_price"]);
                        bool    totalZero        = total_hc_price + total_pt_price == 0;
                        bool    hcPaid           = Convert.ToBoolean(dt_selected_list.Rows[i]["hc_paid"]);
                        string  areaTreated      = dt_selected_list.Rows[i]["area_treated"].ToString().Trim();
                        string  serviceReference = dt_selected_list.Rows[i]["service_reference"].ToString().Trim();

                        if (total_hc_price > 0 || (totalZero && hcPaid))
                        {

                            int offeringOrderID = -1;
                            if (Convert.ToBoolean(dt_selected_list.Rows[i]["on_order"]))
                            {
                                offeringOrderID = OfferingOrderDB.Insert(
                                    Convert.ToInt32(dt_selected_list.Rows[i]["offering_id"]),
                                    booking.Organisation.OrganisationID,
                                    booking.Provider.StaffID,
                                    booking.Patient.PatientID,
                                    Convert.ToInt32(dt_selected_list.Rows[i]["quantity"]),
                                    DateTime.Today,
                                    DateTime.MinValue,
                                    DateTime.MinValue,
                                    string.Empty
                                    );
                                offeringOrderIDs.Add(offeringOrderID);
                            }

                            int invoiceLineID = InvoiceLineDB.Insert(hcInvID, booking.Patient.PatientID, Convert.ToInt32(dt_selected_list.Rows[i]["offering_id"]), Convert.ToInt32(dt_selected_list.Rows[i]["quantity"]), Convert.ToDecimal(dt_selected_list.Rows[i]["total_hc_price"]) + Convert.ToDecimal(dt_selected_list.Rows[i]["total_hc_gst"]), Convert.ToDecimal(dt_selected_list.Rows[i]["total_hc_gst"]), areaTreated, serviceReference, offeringOrderID);
                            invLineIDs.Add(invoiceLineID);
                            invoiceLines.Add(new InvoiceLine(invoiceLineID, hcInvID, booking.Patient.PatientID, Convert.ToInt32(dt_selected_list.Rows[i]["offering_id"]), Convert.ToInt32(dt_selected_list.Rows[i]["quantity"]), Convert.ToDecimal(dt_selected_list.Rows[i]["total_hc_price"]) + Convert.ToDecimal(dt_selected_list.Rows[i]["total_hc_gst"]), Convert.ToDecimal(dt_selected_list.Rows[i]["total_hc_gst"]), areaTreated, serviceReference, offeringOrderID));

                            // update their epcs remaining
                            if (invType == Booking.InvoiceType.Medicare)
                            {
                                Offering offering = OfferingDB.GetByID(Convert.ToInt32(dt_selected_list.Rows[i]["offering_id"]));
                                for (int j = 0; j < epcsRemaining.Length; j++)
                                {
                                    if (epcsRemaining[j].Field.ID == offering.Field.ID)
                                    {
                                        epcsRemaining[j].NumServicesRemaining -= 1;
                                        HealthCardEPCRemainingDB.UpdateNumServicesRemaining(epcsRemaining[j].HealthCardEpcRemainingID, epcsRemaining[j].NumServicesRemaining);
                                    }
                                }
                            }
                        }
                    }
                }

                // add non-healthcare invoice
                if (ptItemCount > 0)
                {
                    nonHcInvID = InvoiceDB.Insert(docType, booking.BookingID, 0, booking.Patient.PatientID, 0, "", "", Convert.ToInt32(Session["StaffID"]), Convert.ToInt32(Session["SiteID"]), ptTotal + ptGST, ptGST, false, false, false, DateTime.MinValue);
                    for (int i = 0; i < dt_selected_list.Rows.Count; i++)
                    {
                        decimal total_hc_price   = Convert.ToDecimal(dt_selected_list.Rows[i]["total_hc_price"]);
                        decimal total_pt_price   = Convert.ToDecimal(dt_selected_list.Rows[i]["total_pt_price"]);
                        bool    totalZero        = total_hc_price + total_pt_price == 0;
                        bool    hcPaid           = Convert.ToBoolean(dt_selected_list.Rows[i]["hc_paid"]);
                        string  areaTreated      = dt_selected_list.Rows[i]["area_treated"].ToString().Trim();
                        string  serviceReference = dt_selected_list.Rows[i]["service_reference"].ToString().Trim();

                        if (total_pt_price > 0 || (totalZero && !hcPaid))
                        {

                            int offeringOrderID = -1;
                            if (Convert.ToBoolean(dt_selected_list.Rows[i]["on_order"]))
                            {
                                offeringOrderID = OfferingOrderDB.Insert(
                                    Convert.ToInt32(dt_selected_list.Rows[i]["offering_id"]),
                                    booking.Organisation.OrganisationID,
                                    booking.Provider.StaffID,
                                    booking.Patient.PatientID,
                                    Convert.ToInt32(dt_selected_list.Rows[i]["quantity"]),
                                    DateTime.Today,
                                    DateTime.MinValue,
                                    DateTime.MinValue,
                                    string.Empty
                                    );
                                offeringOrderIDs.Add(offeringOrderID);
                            }

                            int invoiceLineID = InvoiceLineDB.Insert(nonHcInvID, booking.Patient.PatientID, Convert.ToInt32(dt_selected_list.Rows[i]["offering_id"]), Convert.ToInt32(dt_selected_list.Rows[i]["quantity"]), Convert.ToDecimal(dt_selected_list.Rows[i]["total_pt_price"]) + Convert.ToDecimal(dt_selected_list.Rows[i]["total_pt_gst"]), Convert.ToDecimal(dt_selected_list.Rows[i]["total_pt_gst"]), areaTreated, serviceReference, offeringOrderID);
                            invLineIDs.Add(invoiceLineID);
                            invoiceLines.Add(new InvoiceLine(invoiceLineID, nonHcInvID, booking.Patient.PatientID, Convert.ToInt32(dt_selected_list.Rows[i]["offering_id"]), Convert.ToInt32(dt_selected_list.Rows[i]["quantity"]), Convert.ToDecimal(dt_selected_list.Rows[i]["total_pt_price"]) + Convert.ToDecimal(dt_selected_list.Rows[i]["total_pt_gst"]), Convert.ToDecimal(dt_selected_list.Rows[i]["total_pt_gst"]), areaTreated, serviceReference, offeringOrderID));

                            nonHcInvTotal += Convert.ToDecimal(dt_selected_list.Rows[i]["total_pt_price"]);
                        }
                   }

                    if (nonHcInvTotal == 0) // for free services
                        InvoiceDB.UpdateIsPaid(null, nonHcInvID, true);
               }

                // set booking as completed (or cancelled)
                booking.BookingStatus.ID = GetFormIsCancelation() ? 188 : 187;
                BookingDB.UpdateSetBookingStatusID(booking.BookingID, booking.BookingStatus.ID);

                if (GetFormIsCancelation())
                    BookingDB.UpdateSetCancelledByPatient(booking.BookingID, Convert.ToInt32(Session["StaffID"]));

                if (!isCancelation)
                {
                    // send referrer letters
                    //
                    // NB: FIRST/LAST letters ONLY FOR MEDICARE - DVA doesn't need letters
                    // Treatment letters for anyone with epc though -- even for private invoices
                    PatientReferrer[] patientReferrers = PatientReferrerDB.GetActiveEPCPatientReferrersOf(booking.Patient.PatientID);
                    if (patientReferrers.Length == 0 && (invType == Booking.InvoiceType.Medicare || invType == Booking.InvoiceType.DVA))
                    {
                        // Marcus: let it create the invoice for medicare/dva and they will pick it up in the HINX sending rejection
                        ; //throw new CustomMessageException("Medicare/DVA invoice requires a referrering doctor - none found for this patient.");
                    }
                    else if (patientReferrers.Length > 0 && (invType == Booking.InvoiceType.Medicare || invType == Booking.InvoiceType.DVA))
                    {
                        bool needToGenerateFirstLetter = false;
                        bool needToGenerateLastLetter  = false;
                        bool needToGenerateTreatmentLetter = patientReferrers[patientReferrers.Length-1].RegisterReferrer.ReportEveryVisitToReferrer; // send treatment letter whether privately paid or not

                        if (invType == Booking.InvoiceType.Medicare)  // create first/last letters only if medicare
                        {
                            int nPodTreatmentsThisEPC = (int)InvoiceDB.GetMedicareCountByPatientAndDateRange(booking.Patient.PatientID, hc.DateReferralSigned.Date, DateTime.Now, -1, booking.Offering.Field.ID);
                            needToGenerateFirstLetter = (nPodTreatmentsThisEPC == 1);
                            needToGenerateLastLetter = (epcsRemaining[0].NumServicesRemaining == 0);
                        }

                        // if already generating first or last letter, don't generate treatement letter also
                        if (needToGenerateFirstLetter || needToGenerateLastLetter)
                            needToGenerateTreatmentLetter = false;

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

                        string[] emails = ContactDB.GetEmailsByEntityID(patientReferrers[patientReferrers.Length - 1].RegisterReferrer.Organisation.EntityID);
                        string[] faxes  = ContactDB.GetFaxesByEntityID (patientReferrers[patientReferrers.Length - 1].RegisterReferrer.Organisation.EntityID);

                        bool generateSystemLetters = !patientReferrers[patientReferrers.Length-1].RegisterReferrer.BatchSendAllPatientsTreatmentNotes && (emails.Length > 0 || chkGenerateSystemLetters.Checked);
                        int letterPrintHistorySendMethodID = emails.Length == 0 ? 1 : 2;

                        ArrayList fileContentsListToPopup = new ArrayList();

                        if (generateSystemLetters)
                        {
                            Letter.FileContents[] fileContentsList = booking.GetSystemLettersList(emails.Length > 0 ? Letter.FileFormat.PDF : Letter.FileFormat.Word, booking.Patient, hc, booking.Offering.Field.ID, patientReferrers[patientReferrers.Length - 1].RegisterReferrer.Referrer, true, needToGenerateFirstLetter, needToGenerateLastLetter, needToGenerateTreatmentLetter, false, Convert.ToInt32(Session["SiteID"]), Convert.ToInt32(Session["StaffID"]), letterPrintHistorySendMethodID);
                            if (fileContentsList != null && fileContentsList.Length > 0)
                            {

                                bool sendViaEmail = AutoSendFaxesAsEmailsIfNoEmailExistsToGPs ? (emails.Length > 0 || faxes.Length > 0) : emails.Length > 0;
                                if (sendViaEmail)
                                {
                                    string toEmail = AutoSendFaxesAsEmailsIfNoEmailExistsToGPs ?
                                                                (emails.Length > 0 ? string.Join(",", emails) : faxes[0] + "@fax.houseofit.com.au")
                                                                :
                                                                string.Join(",", emails);

                                    if (!Utilities.IsDev())
                                        Letter.EmailSystemLetter((string)Session["SiteName"], toEmail, fileContentsList);
                                }
                                else
                                {

                                    // generate pt letter
                                    if (needToGenerateLastLetter)
                                    {
                                        Letter.FileContents[] ptLastLetterFileContents = booking.GetSystemLettersList(Letter.FileFormat.Word, booking.Patient, hc, booking.Offering.Field.ID, patientReferrers[patientReferrers.Length - 1].RegisterReferrer.Referrer, true, false, false, false, true, Convert.ToInt32(Session["SiteID"]), Convert.ToInt32(Session["StaffID"]), letterPrintHistorySendMethodID);
                                        Letter.FileContents[] newFileContentsList = new Letter.FileContents[fileContentsList.Length + 1];
                                        fileContentsList.CopyTo(newFileContentsList, 0);
                                        newFileContentsList[newFileContentsList.Length - 1] = ptLastLetterFileContents[0];
                                        fileContentsList = newFileContentsList;
                                    }

                                    //Letter.FileContents fileContents = Letter.FileContents.Merge(fileContentsList, "Treatment Letters.pdf"); // change here to create as pdf
                                    //Session["downloadFile_Contents"] = fileContents.Contents;
                                    //Session["downloadFile_DocName"] = fileContents.DocName;
                                    //showDownloadPopup = true;

                                    fileContentsListToPopup.AddRange(fileContentsList);
                                }
                            }
                        }

                        // generate pt letter
                        if (needToGenerateLastLetter && !showDownloadPopup)
                        {
                                Letter.FileContents[] ptLastLetterFileContents = booking.GetSystemLettersList(Letter.FileFormat.Word, booking.Patient, hc, booking.Offering.Field.ID, patientReferrers[patientReferrers.Length - 1].RegisterReferrer.Referrer, true, false, false, false, true, Convert.ToInt32(Session["SiteID"]), Convert.ToInt32(Session["StaffID"]), letterPrintHistorySendMethodID);
                                //Letter.FileContents fileContents = Letter.FileContents.Merge(ptLastLetterFileContents, "Treatment Letters.pdf"); // change here to create as pdf
                                //Session["downloadFile_Contents"] = fileContents.Contents;
                                //Session["downloadFile_DocName"] = fileContents.DocName;
                                //showDownloadPopup = true;
                                fileContentsListToPopup.AddRange(ptLastLetterFileContents);
                        }

                        if (fileContentsListToPopup.Count == 1) // download the file
                        {
                            Letter.FileContents fc = (Letter.FileContents)fileContentsListToPopup[0];
                            fc = Letter.FileContents.Merge((Letter.FileContents[])fileContentsListToPopup.ToArray(typeof(Letter.FileContents)), Path.ChangeExtension(fc.DocName, ".pdf")); // change here to create as pdf
                            Session["downloadFile_Contents"] = fc.Contents;
                            Session["downloadFile_DocName"]  = fc.DocName;
                            showDownloadPopup = true;
                        }
                        else if (fileContentsListToPopup.Count > 1)  // Create Zip as we can not merge word docs from different templates
                        {
                            string tmpLettersDirectory = Letter.GetTempLettersDirectory();
                            if (!Directory.Exists(tmpLettersDirectory))
                                throw new CustomMessageException("Temp letters directory doesn't exist");

                            // put into temp dir
                            string baseTmpDir = FileHelper.GetTempDirectoryName(tmpLettersDirectory);
                            string tmpDir = baseTmpDir + "Treatment Letters" + @"\";
                            Directory.CreateDirectory(tmpDir);

                            string[] tmpFiles = new string[fileContentsListToPopup.Count];
                            for (int i = 0; i < fileContentsListToPopup.Count; i++)
                            {
                                Letter.FileContents fc = (Letter.FileContents)fileContentsListToPopup[i];
                                string tmpFileName = tmpDir + fc.DocName;
                                System.IO.File.WriteAllBytes(tmpFileName, fc.Contents);
                                tmpFiles[i] = tmpFileName;
                            }

                            // zip em
                            string zipFileName = "Treatment 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);

                            showDownloadPopup = true;
                        }

                        if (needToGenerateLastLetter && !Utilities.IsDev())  // send SMS/Email to patient
                        {
                            bool EnableLastEPCReminderSMS    = Convert.ToInt32(SystemVariableDB.GetByDescr("EnableLastEPCReminderSMS").Value) == 1;
                            bool EnableLastEPCReminderEmails = Convert.ToInt32(SystemVariableDB.GetByDescr("EnableLastEPCReminderEmails").Value) == 1;

                            string[] ptMobiles;
                            if (Utilities.GetAddressType().ToString() == "Contact")
                                ptMobiles = ContactDB.GetByEntityID(-1, booking.Patient.Person.EntityID, 30).Select(r => r.AddrLine1).ToArray();
                            else if (Utilities.GetAddressType().ToString() == "ContactAus")
                                ptMobiles = ContactAusDB.GetByEntityID(-1, booking.Patient.Person.EntityID, 30).Select(r => r.AddrLine1).ToArray();
                            else
                                throw new Exception("Unknown AddressType in config: " + Utilities.GetAddressType().ToString().ToString());

                            string[] ptEmails = ContactDB.GetEmailsByEntityID(booking.Patient.Person.EntityID);

                            decimal balance = SMSCreditDataDB.GetTotal() - SMSHistoryDataDB.GetTotal();
                            decimal cost    = Convert.ToDecimal(SystemVariableDB.GetByDescr("SMSPrice").Value);

                            string  callerId    = System.Configuration.ConfigurationManager.AppSettings["SMSTech_callerId"];  // not here used as the callerId will be the org name
                            callerId = booking.Organisation.Name;
                            string  countryCode = System.Configuration.ConfigurationManager.AppSettings["SMSTech_CountryCode"];

                            string smsMessage   = @"Hi " + booking.Patient.Person.Firstname + @",

        Please be advised that you have used your last visit under your current EPC referral.
        Please consult your doctor about a new referral to cover future consultations.

        Regards,
        " + booking.Organisation.Name;

                            string emailSubject = @"EPC Referral Used Up.";
                            string emailMessage = @"Hi " + booking.Patient.Person.Firstname + @",<br /><br />Please be advised that you have used your last visit under the current EPC referral.<br />Plase consult your doctor about a new referral to cover future consultations.<br /><br />Regards, <br />" + booking.Organisation.Name;

                            if (ptMobiles.Length > 0)
                                ptMobiles[0] = ptMobiles[0].StartsWith("0") ? countryCode + ptMobiles[0].Substring(1) : ptMobiles[0];

                            bool sendingAlready = false;
                            if (EnableLastEPCReminderSMS && ptMobiles.Length > 0 && balance >= cost)
                            {
                                try
                                {
                                    TransmitSMSAPIWrapper sms = new TransmitSMSAPIWrapper(
                                        System.Configuration.ConfigurationManager.AppSettings["SMSTech_Key"],
                                        System.Configuration.ConfigurationManager.AppSettings["SMSTech_Secret"],
                                        System.Configuration.ConfigurationManager.AppSettings["SMSTech_RequestURL"]);

                                    string xmlResponse = sms.MessageSingle(ptMobiles[0], smsMessage, callerId);

                                    if (Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["LogSMSSending"]))
                                        Logger.LogSMSSend(
                                            System.Web.HttpContext.Current.Session["DB"].ToString() + Environment.NewLine + Environment.NewLine +
                                            ptMobiles[0] + Environment.NewLine + Environment.NewLine +
                                            smsMessage   + Environment.NewLine + Environment.NewLine +
                                            callerId     + Environment.NewLine + Environment.NewLine +
                                            xmlResponse,
                                            true);

                                    string SMSTechMessageID = GetSMSTechMessageID(xmlResponse);
                                    SMSHistoryDataDB.Insert(1, booking.Patient.PatientID, -1, ptMobiles[0], smsMessage, cost, SMSTechMessageID);

                                    sendingAlready = true;
                                }
                                catch (Exception ex)
                                {
                                    Logger.LogException(ex, true);
                                }
                            }
                            if (EnableLastEPCReminderEmails && ptEmails.Length > 0)
                            {
                                if (!sendingAlready)  // if not already added for sms sending
                                {
                                    try
                                    {
                                        string fromEmail = ((SystemVariables)System.Web.HttpContext.Current.Session["SystemVariables"])["Email_FromEmail"].Value;
                                        EmailerNew.SimpleEmail(
                                            fromEmail,
                                            booking.Organisation.Name,
                                            string.Join(",", ptEmails),
                                            emailSubject,
                                            emailMessage,
                                            true,
                                            null,
                                            false,
                                            null
                                            );

                                        EmailHistoryDataDB.Insert(1, booking.Patient.PatientID, -1, string.Join(",", ptEmails), emailMessage);
                                    }
                                    catch (Exception ex)
                                    {
                                        Logger.LogException(ex, true);
                                    }
                                }
                            }

                        }

                        BookingDB.UpdateSetGeneratedSystemLetters(booking.BookingID, needToGenerateFirstLetter, needToGenerateLastLetter, generateSystemLetters);

                        /*
                        if (showEPCTreatmentDownloadPopup && !showStandardTreatmentDownloadPopup)
                        {
                            Session["downloadFile_Contents"] = fileContentsEPCTreatment.Contents;
                            Session["downloadFile_DocName"]  = fileContentsEPCTreatment.DocName;
                            showDownloadPopup = true;
                        }
                        else if (!showEPCTreatmentDownloadPopup && showStandardTreatmentDownloadPopup)
                        {
                            Session["downloadFile_Contents"] = fileContentsStandardTreatment.Contents;
                            Session["downloadFile_DocName"]  = fileContentsStandardTreatment.DocName;
                            showDownloadPopup = true;
                        }
                        else if (showEPCTreatmentDownloadPopup && showStandardTreatmentDownloadPopup)
                        {
                            // merge

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

                            string tmpFileName_EPCTreatment = FileHelper.GetTempFileName(tmpLettersDirectory + fileContentsEPCTreatment.DocName);
                            File.WriteAllBytes(tmpFileName_EPCTreatment, fileContentsEPCTreatment.Contents);
                            string tmpFileName_StandardTreatment = FileHelper.GetTempFileName(tmpLettersDirectory + fileContentsStandardTreatment.DocName);
                            File.WriteAllBytes(tmpFileName_StandardTreatment, fileContentsStandardTreatment.Contents);

                            string tmpFinalFileName = Letter.MergeMultipleDocuments(new string[] { tmpFileName_EPCTreatment, tmpFileName_StandardTreatment }, tmpLettersDirectory + Path.GetFileName(fileContentsEPCTreatment.DocName));
                            byte[] fileContents = System.IO.File.ReadAllBytes(tmpFinalFileName);

                            File.Delete(tmpFileName_EPCTreatment);
                            File.Delete(tmpFileName_StandardTreatment);
                            File.Delete(tmpFinalFileName);

                            Session["downloadFile_Contents"] = fileContents;
                            Session["downloadFile_DocName"] = fileContentsEPCTreatment.DocName;
                            showDownloadPopup = true;
                        }
                        */

                    }
                }

                // clear in memory (ie session) list
                Session.Remove("data_selected");

                // successfully completed, so update and check warning level for stocks
                foreach (InvoiceLine invoiceLine in invoiceLines)
                    if (invoiceLine.OfferingOrder == null) // stkip counting down if item is on order
                        StockDB.UpdateAndCheckWarning(booking.Organisation.OrganisationID, invoiceLine.Offering.OfferingID, (int)invoiceLine.Quantity);

                if (nonHcInvID > 0 && nonHcInvTotal > 0)  // go to pay screen - but pass in "showDownloadPopup" somehow .. and close window with same as below script...
                {
                    System.Drawing.Size size = Receipt.GetPopupWindowAddSize();
                    size = new System.Drawing.Size(size.Width + 15, size.Height + 60);
                    Response.Redirect("~/Invoice_ReceiptAndCreditNoteAddV2.aspx?id=" + nonHcInvID + "&returnValue=" + (showDownloadPopup ? "true" : "false") + "&window_size=" + size.Width + "_" + size.Height + (refresh_on_close ? "&refresh_on_close=1" : ""), false);
                    return;
                }

            }
            catch (Exception ex)
            {
                if (ex is CustomMessageException == false)
                    Logger.LogException(ex);

                // roll back...
                BookingDB.UpdateSetBookingStatusID(booking.BookingID, 0);
                BookingDB.UpdateSetGeneratedSystemLetters(booking.BookingID, booking.NeedToGenerateFirstLetter, booking.NeedToGenerateLastLetter, booking.HasGeneratedSystemLetters);
                foreach (int invLineID in invLineIDs)
                    InvoiceLineDB.Delete(invLineID);
                foreach (int offeringOrderID in offeringOrderIDs)
                    OfferingOrderDB.Delete(offeringOrderID);
                InvoiceDB.Delete(hcInvID);
                InvoiceDB.Delete(nonHcInvID);
                for (int j = 0; j < epcsRemainingOriginal.Length; j++)
                    HealthCardEPCRemainingDB.UpdateNumServicesRemaining(epcsRemainingOriginal[j].HealthCardEpcRemainingID, epcsRemainingOriginal[j].NumServicesRemaining);

                throw;
            }

            // close this window
            Page.ClientScript.RegisterStartupScript(this.GetType(), "close", "<script language=javascript>window.returnValue=" + (showDownloadPopup ? "true" : "false") + ";" + (refresh_on_close ? "window.opener.location.href = window.opener.location.href;" : "") + "self.close();</script>");

        }
        catch (CustomMessageException cmEx)
        {
            SetErrorMessage(cmEx.Message);
            return;
        }
        catch (System.Data.SqlClient.SqlException sqlEx)
        {
            if (sqlEx.Message.StartsWith("No claim numbers left") || sqlEx.Message.StartsWith("Error: Claim number already in use"))
                SetErrorMessage(sqlEx.Message);
            else
                SetErrorMessage(Utilities.IsDev() ? sqlEx.ToString() : "");
            return;
        }
        catch (Exception ex)
        {
            SetErrorMessage("", ex.ToString());
            return;
        }
    }
    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());
        }
    }
Пример #17
0
    protected static void SyncGenerateInvoicesToEmail(int[] invoiceIDs, string emailTo, bool isClinicInvoice, bool isBookingInvoice = true)
    {
        string originalFile = null;
        if (isClinicInvoice)
            originalFile = Letter.GetLettersDirectory() + (isBookingInvoice ? @"InvoiceTemplate.docx" : @"PrivateInvoiceTemplate.docx");
        else
            originalFile = Letter.GetLettersDirectory() + (isBookingInvoice ? @"InvoiceTemplateAC.docx" : @"PrivateInvoiceTemplateAC.docx");

        string tmpLettersDirectory = Letter.GetTempLettersDirectory();

        Letter.FileContents[] fileContentsList = new Letter.FileContents[invoiceIDs.Length];
        for (int i = 0; i < invoiceIDs.Length; i++)
        {
            string tmpOutputFile = FileHelper.GetTempFileName(tmpLettersDirectory + "Invoice_" + invoiceIDs[i] + "." + "pdf");
            if (isBookingInvoice)
                GenerateInvoice(invoiceIDs[i], isClinicInvoice, originalFile, tmpOutputFile);
            else
                GeneratePrivateInvoice(invoiceIDs[i], isClinicInvoice, originalFile, tmpOutputFile);
            fileContentsList[i] = new FileContents(System.IO.File.ReadAllBytes(tmpOutputFile), "Invoice_" + invoiceIDs[i] + "." + "pdf");
            File.Delete(tmpOutputFile);
        }

        Site site = SiteDB.GetSiteByType(!isClinicInvoice ? SiteDB.SiteType.AgedCare : SiteDB.SiteType.Clinic);
        Email(
            site.Name,
            emailTo,
            "Invoice" + (fileContentsList.Length == 0 ? "" : "s") + " From " + site.Name,
            "Please find invoice" + (fileContentsList.Length == 0 ? "" : "s") + " attached.<br /><br />Best regards,<br />" + site.Name,
            true,
            fileContentsList
            );
    }
Пример #18
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());
        }
    }