public static string Run(bool incDisplay, bool incSending, DateTime date)
    {
        date = date.Date;


        bool   EnableDailyBookingReminderSMS             = Convert.ToInt32(SystemVariableDB.GetByDescr("EnableDailyBookingReminderSMS").Value) == 1;
        bool   EnableDailyBookingReminderEmails          = Convert.ToInt32(SystemVariableDB.GetByDescr("EnableDailyBookingReminderEmails").Value) == 1;
        int    NbrDaysAheadToSendDailyBookingReminderSMS = Convert.ToInt32(SystemVariableDB.GetByDescr("NbrDaysAheadToSendDailyBookingReminderSMS").Value);
        string SendDailyBookingReminderText_SMS          = SystemVariableDB.GetByDescr("SendDailyBookingReminderText_SMS").Value;
        string SendDailyBookingReminderText_Email        = SystemVariableDB.GetByDescr("SendDailyBookingReminderText_Email").Value;
        string SendDailyBookingReminderText_EmailSubject = SystemVariableDB.GetByDescr("SendDailyBookingReminderText_EmailSubject").Value;
        string PT_Reminders_HasBothSMSandEmail           = SystemVariableDB.GetByDescr("PT_Reminders_HasBothSMSandEmail").Value;

        date = date.AddDays(NbrDaysAheadToSendDailyBookingReminderSMS - 1);


        Booking[] bookings = BookingDB.GetBetween(date, date.AddDays(1).AddMinutes(-1), null, null, null, null, false, "0", false, null);
        Hashtable patientContactPhoneNbrHash = GetPatientPhoneNbrCache(bookings);
        Hashtable patientContactEmailHash    = GetPatientEmailCache(bookings);
        Hashtable orgContactHash             = GetOrgPhoneNbrCache(bookings);
        Hashtable orgAddrContactHash         = GetOrgAddrCache(bookings);



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


        string    callerId                 = System.Configuration.ConfigurationManager.AppSettings["SMSTech_callerId"];  // not used here as the callerId will be the org name
        string    countryCode              = System.Configuration.ConfigurationManager.AppSettings["SMSTech_CountryCode"];
        ArrayList messagesToSMS            = new ArrayList();
        ArrayList messagesToEmail          = new ArrayList();
        ArrayList bookingIDsConfirmedSMS   = new ArrayList();
        ArrayList bookingIDsConfirmedEmail = new ArrayList();


        string output           = "<table class=\"table table-bordered table-striped table-grid table-grid-top-bottum-padding-thick auto_width block_center\" border=\"1\" style=\"border-collapse:collapse;\">";
        int    countWithPatient = 0;

        foreach (Booking booking in bookings)
        {
            if (booking.BookingTypeID != 34)  // only bookings, not days marked off
            {
                continue;
            }

            if (booking.Patient == null || booking.Offering == null)      // prob aged care booking
            {
                continue;
            }

            // Marcus: send sms even if booking is confirmed
            //if (booking.ConfirmedBy != null)  // don't send reminders to those already confirmed
            //    continue;

            // get all info to send via sms or email

            string phoneNumPatient = GetPhoneNbr(patientContactPhoneNbrHash, booking.Patient.Person.EntityID, true);
            if (phoneNumPatient != null)
            {
                phoneNumPatient = phoneNumPatient.StartsWith("0") ? countryCode + phoneNumPatient.Substring(1) : phoneNumPatient;
            }

            string emailPatient = GetEmail(patientContactEmailHash, booking.Patient.Person.EntityID);
            string phoneNumOrg  = GetPhoneNbrs(orgContactHash, booking.Organisation.EntityID);
            string addrOrg      = GetAddr(orgAddrContactHash, booking.Organisation.EntityID);

            string smsText          = GetSMSText(booking, phoneNumOrg, addrOrg, SendDailyBookingReminderText_SMS);
            string emailText        = GetEmailText(booking, phoneNumOrg, addrOrg, SendDailyBookingReminderText_Email);
            string emailSubjectText = GetEmailSubjectText(booking, phoneNumOrg, addrOrg, SendDailyBookingReminderText_EmailSubject);


            // kept just to show their email/phone number exists even though we may not be sending to there due to settings or low balance.
            string phoneNumPatient_Original = phoneNumPatient;
            string emailPatient_Original    = emailPatient;


            // ignore if setting is to not sending sms's or emails
            if (phoneNumPatient != null && !EnableDailyBookingReminderSMS)
            {
                phoneNumPatient = null;
            }
            if (emailPatient != null && !EnableDailyBookingReminderEmails)
            {
                emailPatient = null;
            }

            // if balance too low, can not send by SMS
            if (phoneNumPatient != null && balance < cost)
            {
                phoneNumPatient = null;
            }

            // if has both, then send based on setting
            if (phoneNumPatient != null && emailPatient != null)
            {
                if (PT_Reminders_HasBothSMSandEmail == "Email") // setting is - when both, send only via email
                {
                    phoneNumPatient = null;
                }
                if (PT_Reminders_HasBothSMSandEmail == "SMS")   // setting is - when both, send only via sms
                {
                    emailPatient = null;
                }
            }


            string textToDisplay = string.Empty;
            if (phoneNumPatient != null)
            {
                textToDisplay += "<b>" + smsText.Replace(Environment.NewLine, "<br />") + "</b>";
            }
            if (emailPatient != null)
            {
                textToDisplay += (textToDisplay.Length == 0 ? "" : "<br><hr>") + "<u>" + emailSubjectText + "</u><br /><br />" + emailText;
            }



            // display the info

            string tdTagStart          = phoneNumPatient == null && emailPatient == null ? "<td class=\"nowrap\" style=\"color:grey;\">" : (phoneNumPatient == null ? "<td>"  : "<td>");
            string tdTagStartLeftAlign = phoneNumPatient == null && emailPatient == null ? "<td class=\"nowrap text_left\" style=\"color:grey;\">" : (phoneNumPatient == null ? "<td class=\"text_left\">" : "<td class=\"text_left\">");
            string tdTagEnd            = phoneNumPatient == null && emailPatient == null ? "</td>" : (phoneNumPatient == null ? "</td>" : "</td>");

            output += "<tr>";
            output += tdTagStart + booking.BookingID + tdTagEnd;
            output += tdTagStart + booking.DateStart.ToString("dd-MM-yy") + "<br />" + booking.DateStart.ToString("HH:mm") + " - " + booking.DateEnd.ToString("HH:mm") + tdTagEnd;
            output += tdTagStart + booking.Organisation.Name + "<br />" + (phoneNumOrg == null ? "-- No Phone --" : phoneNumOrg.Replace(",", "<br />").Replace("or", "<br />")) + tdTagEnd;
            output += tdTagStart + booking.Patient.Person.FullnameWithoutMiddlename + "<br />" +
                      (phoneNumPatient_Original == null ? "-- No Mobile --" : "<u>" + phoneNumPatient_Original + "</u>") + "<br />" +
                      (emailPatient_Original == null ? "-- No Email --"  : "<u>" + emailPatient_Original + "</u>") + tdTagEnd;
            output += tdTagStartLeftAlign + textToDisplay + tdTagEnd;
            output += "</tr>";

            countWithPatient++;



            /*
             *  add to lists to sms or email (or both)
             */

            if (phoneNumPatient != null)
            {
                messagesToSMS.Add(new Tuple <int, decimal, string, string, string>(booking.BookingID, cost, phoneNumPatient, smsText, booking.Organisation.Name));
                bookingIDsConfirmedSMS.Add(booking.BookingID);
                if (incSending)
                {
                    balance -= cost;
                }
            }
            if (emailPatient != null)
            {
                messagesToEmail.Add(new Tuple <int, string, string, string, string>(booking.BookingID, booking.Organisation.Name, emailPatient, emailText, emailSubjectText));
                bookingIDsConfirmedEmail.Add(booking.BookingID);
            }


            /*
             * bool sendingAlready = false;
             * if (EnableDailyBookingReminderSMS && phoneNumPatient != null && balance >= cost)
             * {
             *  messagesToSMS.Add(new Tuple<int, decimal, string, string, string>(booking.BookingID, cost, phoneNumPatient, smsText, booking.Organisation.Name));
             *  bookingIDsConfirmedSMS.Add(booking.BookingID);
             *  sendingAlready = true;
             *  if (incSending)
             *      balance -= cost;
             * }
             * if (EnableDailyBookingReminderEmails && emailPatient != null)
             * {
             *  messagesToEmail.Add(new Tuple<int, string, string, string, string>(booking.BookingID, booking.Organisation.Name, emailPatient, emailText, emailSubjectText));
             *  if (!sendingAlready)  // if not already added for sms sending
             *      bookingIDsConfirmedEmail.Add(booking.BookingID);
             * }
             */
        }
        output += "</table>";


        // run the sending and send off reminders -- but only if there was any bookings

        if (incSending && bookings.Length > 0)
        {
            /*
             * run the sendings
             */

            SendSMSes((Tuple <int, decimal, string, string, string>[])messagesToSMS.ToArray(typeof(Tuple <int, decimal, string, string, string>)));
            SendEmails((Tuple <int, string, string, string, string>[])messagesToEmail.ToArray(typeof(Tuple <int, string, string, string, string>)));

            /*
             * if sms or email sent, set booking as confirmed
             */
            BookingDB.UpdateSetConfirmed((int[])bookingIDsConfirmedSMS.ToArray(typeof(int)), 2, -1);
            BookingDB.UpdateSetConfirmed((int[])bookingIDsConfirmedEmail.ToArray(typeof(int)), 3, -1);

            /*
             * send balance warning
             */

            SystemVariables systemVariables            = SystemVariableDB.GetAll();
            string          warningEmail               = systemVariables["SMSCreditNotificationEmailAddress"].Value;
            decimal         warningThreshold           = Convert.ToDecimal(systemVariables["SMSCreditLowBalance_Threshold"].Value);
            bool            checkSMSCreditOutOfBalance = Convert.ToInt32(systemVariables["SMSCreditOutOfBalance_SendEmail"].Value) == 1;
            bool            checkMSCreditLowBalance    = Convert.ToInt32(systemVariables["SMSCreditLowBalance_SendEmail"].Value) == 1;


            if (warningEmail.Length > 0 && checkSMSCreditOutOfBalance && balance < cost)
            {
                SendEmail(
                    warningEmail,
                    "SMS Credit Used Up",
                    "Please note that your SMS credit at mediclinic has been used up. To continue sending, please top up.<br /><br />Best regards,<br />Mediclinic");
            }
            else if (warningEmail.Length > 0 && checkMSCreditLowBalance && balance <= warningThreshold)  // dont send warning low balance if already sending out of credit email
            {
                SendEmail(
                    warningEmail,
                    "SMS Credit Warning - Don't Forget To Top-Up Before It Runs Out",
                    "Hi! Just a friendly reminder that the SMS reminder threshold you set has been reached.<br /> To avoid missing SMS'es being sent, don't forget to top-up before the remainder runs out!<br /><br />Best regards,<br />Mediclinic");
            }
        }

        if (incDisplay)
        {
            return("Count: <b>" + countWithPatient + "</b> &nbsp;&nbsp; [Sending Via SMS: <b>" + messagesToSMS.Count + "</b>] &nbsp;&nbsp; [Sending Via Email: <b>" + messagesToEmail.Count + "</b>] " + "<br /><br />" + output);
        }
        else
        {
            return(string.Empty);
        }
    }
    protected void btnPrint_Click(object sender, EventArgs e)
    {
        try
        {
            decimal smsBalance = SMSCreditDataDB.GetTotal() - SMSHistoryDataDB.GetTotal();
            decimal smsCost    = Convert.ToDecimal(SystemVariableDB.GetByDescr("SMSPrice").Value);

            int maxSMSCountCanAfford = smsCost == 0 ? 1000000 : (int)(smsBalance / smsCost);
            int smsCountSending      = 0;


            //
            // Start Validation
            //

            txtEmailSubject.Text     = txtEmailSubject.Text.Trim();
            txtEmailForPrinting.Text = txtEmailForPrinting.Text.Trim();
            txtSMSText.Text          = txtSMSText.Text.Trim();


            bool printSelected = (ddlBothMobileAndEmail.SelectedValue == "1" || ddlEmailNoMobile.SelectedValue == "1" ||
                                  ddlMobileNoEmail.SelectedValue == "1" || ddlNeitherMobileOrEmail.SelectedValue == "1");
            bool emailSelected = (ddlBothMobileAndEmail.SelectedValue == "2" || ddlEmailNoMobile.SelectedValue == "2" ||
                                  ddlMobileNoEmail.SelectedValue == "2" || ddlNeitherMobileOrEmail.SelectedValue == "2");
            bool smsSelected = (ddlBothMobileAndEmail.SelectedValue == "3" || ddlEmailNoMobile.SelectedValue == "3" ||
                                ddlMobileNoEmail.SelectedValue == "3" || ddlNeitherMobileOrEmail.SelectedValue == "3");


            string validationErrors = string.Empty;

            if (printSelected)
            {
                if (txtEmailForPrinting.Text.Length == 0)
                {
                    validationErrors += "<li>Printed Batch Letters Email Address To Send To can not be empty.</li>";
                }
                else if (!Utilities.IsValidEmailAddress(txtEmailForPrinting.Text))
                {
                    validationErrors += "<li>Printed Batch Letters Email Address To Send To must look like a valid email address.</li>";
                }
            }
            if (emailSelected)
            {
                if (txtEmailSubject.Text.Length == 0)
                {
                    validationErrors += "<li>Email Subject can not be empty.</li>";
                }
                if (FreeTextBox1.Text.Length == 0)
                {
                    validationErrors += "<li>Email Text can not be empty.</li>";
                }
            }
            if (smsSelected)
            {
                if (smsCost > 0 && smsBalance == 0)
                {
                    validationErrors += "<li>Can not send SMS's - your SMS balance is empty. Please topup or unselect sending by SMS.</li>";
                }
                else if (txtSMSText.Text.Length == 0)
                {
                    validationErrors += "<li>SMS Text can not be empty.</li>";
                }
            }

            if (validationErrors.Length > 0)
            {
                throw new CustomMessageException("<ul>" + validationErrors + "</ul>");
            }

            //
            // End Validation
            //



            //
            // get hashtables of those with mobiles and emails
            //

            ArrayList regRefIDsArr = new ArrayList();


            foreach (ListItem referrerItem in lstReferrers.Items)  // regrefid
            {
                if (referrerItem.Selected)
                {
                    regRefIDsArr.Add(Convert.ToInt32(referrerItem.Value));
                }
            }


            int[]     regRefIDs    = (int[])regRefIDsArr.ToArray(typeof(int));
            int[]     entityIDs    = RegisterReferrerDB.GetOrgEntityIDs(regRefIDs);
            Hashtable entityIDHash = RegisterReferrerDB.GetOrgEntityIDsHash(regRefIDs);
            Hashtable regRefIDHash = RegisterReferrerDB.GetByIDsInHashtable(regRefIDs);

            Hashtable emailHash  = PatientsContactCacheDB.GetBullkEmail(entityIDs, -1);
            Hashtable mobileHash = PatientsContactCacheDB.GetBullkPhoneNumbers(entityIDs, -1, "30");

            string email_from_address = ((SystemVariables)System.Web.HttpContext.Current.Session["SystemVariables"])["Email_FromEmail"].Value;
            string email_from_name    = ((SystemVariables)System.Web.HttpContext.Current.Session["SystemVariables"])["Email_FromName"].Value;

            //bool StoreLettersHistoryInDB       = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["StoreLettersHistoryInDB"]);
            //bool StoreLettersHistoryInFlatFile = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["StoreLettersHistoryInFlatFile"]);
            bool StoreLettersHistoryInDB       = false; // don't store bulk marketing letters
            bool StoreLettersHistoryInFlatFile = false; // don't store bulk marketing letters



            //
            // ok start the sending process
            //


            int bulkLetterSendingQueueBatchID = UseBulkLetterSender ? BulkLetterSendingQueueBatchDB.Insert(txtEmailForPrinting.Text, false) : -1;


            // TODO: Send Letter By Email
            int letterPrintHistorySendMethodID = 1; // send by mail


            // make sure at least one referrer selected
            if (lstReferrers.GetSelectedIndices().Length == 0)
            {
                throw new CustomMessageException("Please select at least one referrer.");
            }

            // make sure at least one letter selected
            if (lstLetters.GetSelectedIndices().Length == 0)
            {
                throw new CustomMessageException("Please select a letter.");
            }


            // get letter and make sure it exists
            Letter letter             = LetterDB.GetByID(Convert.ToInt32(lstLetters.SelectedValue));
            string sourchTemplatePath = letter.GetFullPath(Convert.ToInt32(Session["SiteID"]));
            if (!File.Exists(sourchTemplatePath))
            {
                throw new CustomMessageException("File doesn't exist.");
            }

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

            // delete old tmp files
            FileHelper.DeleteOldFiles(tmpLettersDirectory, new TimeSpan(1, 0, 0));



            // create individual merged docs and put into list of docsToMerge - only if there is an org-patient relationship
            ArrayList docsToMerge = new ArrayList();

            Site site    = SiteDB.GetByID(Convert.ToInt32(Session["SiteID"]));
            int  StaffID = Convert.ToInt32(Session["StaffID"]);
            foreach (ListItem referrerItem in lstReferrers.Items)
            {
                if (!referrerItem.Selected)
                {
                    continue;
                }

                if (UseBulkLetterSender)
                {
                    int        refEntityID    = (int)entityIDHash[Convert.ToInt32(referrerItem.Value)];
                    string     refPhoneNumber = GetPhoneNbr(mobileHash, refEntityID, true);
                    string     refEmail       = GetEmail(emailHash, refEntityID);
                    SendMethod sendMethod     = GetSendMethod(refEmail != null, refPhoneNumber != null);

                    RegisterReferrer regRef = RegisterReferrerDB.GetByID(Convert.ToInt32(referrerItem.Value));

                    if (sendMethod != SendMethod.None)
                    {
                        string text = string.Empty;
                        if (sendMethod == SendMethod.SMS)
                        {
                            text = txtSMSText.Text;
                        }
                        if (sendMethod == SendMethod.Email)
                        {
                            text = FreeTextBox1.Text;
                        }

                        text = ReplaceMergeFields(text, regRefIDHash, Convert.ToInt32(referrerItem.Value));

                        bool generateLetter = false;
                        if (sendMethod == SendMethod.SMS)
                        {
                            generateLetter = false;
                        }
                        if (sendMethod == SendMethod.Email)
                        {
                            generateLetter = lstLetters.GetSelectedIndices().Length != 0;
                        }
                        if (sendMethod == SendMethod.Print)
                        {
                            generateLetter = true;
                        }


                        if (sendMethod == SendMethod.SMS)  // copy to other methods!!
                        {
                            smsCountSending++;
                        }


                        BulkLetterSendingQueueDB.Insert
                        (
                            bulkLetterSendingQueueBatchID,
                            (int)sendMethod,                                              // bulk_letter_sending_queue_method_id
                            StaffID,                                                      // added_by
                            -1,                                                           // patient_id
                            regRef.Referrer.ReferrerID,                                   // referrer_id
                            -1,                                                           // booking_id
                            (sendMethod == SendMethod.SMS)   ? refPhoneNumber       : "", // phone_number
                            (sendMethod == SendMethod.Email) ? refEmail             : "", // email_to_address
                            "",                                                           // email_to_name
                            (sendMethod == SendMethod.Email) ? email_from_address   : "", // email_from_address
                            (sendMethod == SendMethod.Email) ? email_from_name      : "", // email_from_name
                            text,                                                         // text
                            (sendMethod == SendMethod.Email) ? txtEmailSubject.Text : "", // email_subject
                            "",                                                           // email_attachment_location
                            false,                                                        // email_attachment_delete_after_sending
                            false,                                                        // email_attachment_folder_delete_after_sending

                            !generateLetter ? -1    : letter.LetterID,
                            !generateLetter ? false : chkKeepInHistory.Checked && StoreLettersHistoryInDB,
                            !generateLetter ? false : chkKeepInHistory.Checked && StoreLettersHistoryInFlatFile,
                            !generateLetter ? -1    : letterPrintHistorySendMethodID,
                            !generateLetter ? ""    : Letter.GetLettersHistoryDirectory(0),
                            !generateLetter ? ""    : letter.Docname.Replace(".dot", ".doc"),
                            !generateLetter ? -1    : site.SiteID,
                            0,                                                             // organisation_id
                            -1,                                                            // booking id
                            -1,                                                            // patient_id

                            !generateLetter ? -1    : Convert.ToInt32(referrerItem.Value), // register_referrer_id_to_use_instead_of_patients_reg_ref
                            !generateLetter ? -1    : StaffID,
                            -1,                                                            //healthcardactionid
                            !generateLetter ? ""    : sourchTemplatePath,
                            !generateLetter ? ""    : tmpLettersDirectory + letter.Docname.Replace(".dot", ".doc"),
                            !generateLetter ? false : true,

                            "",    // email_letter_extra_pages
                            "",    // email_letter_item_seperator
                            "",    // sql_to_run_on_completion
                            ""     // sql_to_run_on_failure
                        );
                    }
                }
                else
                {
                    // create doc
                    string tmpSingleFileName = Letter.CreateMergedDocument(
                        letter.LetterID,
                        chkKeepInHistory.Checked && StoreLettersHistoryInDB,
                        chkKeepInHistory.Checked && StoreLettersHistoryInFlatFile,
                        letterPrintHistorySendMethodID,
                        Letter.GetLettersHistoryDirectory(0),
                        letter.Docname.Replace(".dot", ".doc"),
                        site,
                        0,  // org id
                        -1, // booking id
                        -1, // patient id
                        Convert.ToInt32(referrerItem.Value),
                        StaffID,
                        -1, //healthcardactionid
                        sourchTemplatePath,
                        tmpLettersDirectory + letter.Docname.Replace(".dot", ".doc"),
                        true);

                    // record name of merged doc
                    docsToMerge.Add(tmpSingleFileName);
                }
            }


            if (UseBulkLetterSender)
            {
                if ((smsCountSending * smsCost) > smsBalance)
                {
                    BulkLetterSendingQueueDB.DeleteByBatchID(bulkLetterSendingQueueBatchID);
                    BulkLetterSendingQueueBatchDB.Delete(bulkLetterSendingQueueBatchID);

                    SetErrorMessage("Not Enough Credit To Send SMS's. Please Top Up You SMS Credit or Choose Methods Other Than SMS.");
                    return;
                }

                BulkLetterSendingQueueBatchDB.UpdateReadyToProcess(bulkLetterSendingQueueBatchID, true);
                SetErrorMessage("Items Added To Sending Queue. View Details <a href='/Letters_PrintBatch_StatusV2.aspx?batch_id=" + bulkLetterSendingQueueBatchID + "'>Here</a>");
            }
            else
            {
                // merge all tmp files
                string tmpFinalFileName = Letter.MergeMultipleDocuments(
                    ((string[])docsToMerge.ToArray(typeof(string))),
                    tmpLettersDirectory + letter.Docname.Replace(".dot", ".doc"));

                // delete all single tmp files
                foreach (string file in docsToMerge)
                {
                    File.Delete(file);
                }

                // download the document
                byte[] fileContents = File.ReadAllBytes(tmpFinalFileName);
                System.IO.File.Delete(tmpFinalFileName);

                // 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, letter.Docname.Replace(".dot", ".doc"));
            }
        }
        catch (CustomMessageException cmEx)
        {
            SetErrorMessage(cmEx.Message);
            return;
        }
    }
    public static string Run(bool incDisplay, bool incSending, DateTime date)
    {
        if (incSending)
        {
            RunBirthdaysWithoutSMSorEmail();
        }

        date = date.Date;


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


        Site[] sites = SiteDB.GetAll();

        Patient[] patients = PatientDB.GetBirthdays(date);
        Hashtable patientContactPhoneNbrHash = GetPatientPhoneNbrCache(patients);
        Hashtable patientContactEmailHash    = GetPatientEmailCache(patients);
        Hashtable patientRegOrgHash          = GetPatientRegOrgCache(patients);   // get a hash of patient reg to org


        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
        string    countryCode     = System.Configuration.ConfigurationManager.AppSettings["SMSTech_CountryCode"];
        ArrayList messagesToSMS   = new ArrayList();
        ArrayList messagesToEmail = new ArrayList();


        string output           = "<table class=\"table table-bordered table-striped table-grid table-grid-top-bottum-padding-thick auto_width block_center\" border=\"1\" style=\"border-collapse:collapse;\">";
        int    countWithPatient = 0;

        foreach (Patient patient in patients)
        {
            // get all info to send via sms or email

            Site site = null;
            foreach (Site curSite in sites)
            {
                if ((patient.IsClinicPatient && curSite.SiteType.ID == 1) || (!patient.IsClinicPatient && curSite.SiteType.ID == 2))
                {
                    site = curSite;
                }
            }

            ArrayList orgs    = patientRegOrgHash[patient.PatientID] as ArrayList;
            string    orgText = (orgs == null || orgs.Count == 0 || orgs.Count > 1) ? site.Name : ((Organisation)orgs[0]).Name;


            string phoneNumPatient = GetPhoneNbr(patientContactPhoneNbrHash, patient.Person.EntityID, true);
            if (phoneNumPatient != null)
            {
                phoneNumPatient = phoneNumPatient.StartsWith("0") ? countryCode + phoneNumPatient.Substring(1) : phoneNumPatient;
            }

            string emailPatient = GetEmail(patientContactEmailHash, patient.Person.EntityID);

            string smsText          = GetSMSText(patient, site, patientRegOrgHash[patient.PatientID] as ArrayList);
            string emailText        = GetEmailText(patient, site, patientRegOrgHash[patient.PatientID] as ArrayList);
            string emailSubjectText = GetEmailSubjectText(patient, site, patientRegOrgHash[patient.PatientID] as ArrayList);



            // display the info

            string tdTagStart          = phoneNumPatient == null && emailPatient == null ? "<td class=\"nowrap\" style=\"color:grey;\">" : (phoneNumPatient == null ? "<td>"  : "<td><b>");
            string tdTagStartLeftAlign = phoneNumPatient == null && emailPatient == null ? "<td class=\"nowrap text_left\" style=\"color:grey;\">" : (phoneNumPatient == null ? "<td class=\"text_left\">" : "<td class=\"text_left\"><b>");
            string tdTagEnd            = phoneNumPatient == null && emailPatient == null ? "</td>" : (phoneNumPatient == null ? "</td>" : "</b></td>");

            output += "<tr>";
            output += tdTagStart + patient.PatientID + tdTagEnd;
            output += tdTagStart + patient.Person.Dob.ToString("dd-MM-yyyy") + tdTagEnd;
            output += tdTagStart + patient.Person.FullnameWithoutMiddlename + "<br />" +
                      (phoneNumPatient == null ? "-- No Mobile --" : "<u>" + phoneNumPatient + "</u>") + "<br />" +
                      (emailPatient == null ? "-- No Email --" : "<u>" + emailPatient + "</u>") + tdTagEnd;
            output += tdTagStartLeftAlign + (phoneNumPatient == null && emailPatient == null ? "" : "<u>" + emailSubjectText + "</u><br /><br />" + emailText) + tdTagEnd;
            output += "</tr>";

            countWithPatient++;



            // add to lists to sms or email (or both)

            if (EnableBirthdaySMS && phoneNumPatient != null && balance >= cost)
            {
                messagesToSMS.Add(new Tuple <int, decimal, string, string, string>(patient.PatientID, cost, phoneNumPatient, smsText, orgText));
                if (incSending)
                {
                    balance -= cost;
                }
            }
            if (EnableBirthdayEmails && emailPatient != null)
            {
                messagesToEmail.Add(new Tuple <int, string, string, string, string>(patient.PatientID, orgText, emailPatient, emailText, emailSubjectText));
            }
        }
        output += "</table>";


        // run the sending and send off reminders -- but only if there was any bookings

        if (incSending && patients.Length > 0)
        {
            /*
             * run the sendings
             */

            SendSMSes((Tuple <int, decimal, string, string, string>[])messagesToSMS.ToArray(typeof(Tuple <int, decimal, string, string, string>)));
            SendEmails((Tuple <int, string, string, string, string>[])messagesToEmail.ToArray(typeof(Tuple <int, string, string, string, string>)));


            /*
             * send balance warning
             */

            SystemVariables systemVariables            = SystemVariableDB.GetAll();
            string          warningEmail               = systemVariables["SMSCreditNotificationEmailAddress"].Value;
            decimal         warningThreshold           = Convert.ToDecimal(systemVariables["SMSCreditLowBalance_Threshold"].Value);
            bool            checkSMSCreditOutOfBalance = Convert.ToInt32(systemVariables["SMSCreditOutOfBalance_SendEmail"].Value) == 1;
            bool            checkMSCreditLowBalance    = Convert.ToInt32(systemVariables["SMSCreditLowBalance_SendEmail"].Value) == 1;


            if (warningEmail.Length > 0 && checkSMSCreditOutOfBalance && balance < cost)
            {
                SendEmail(
                    warningEmail,
                    "SMS Credit Used Up",
                    "Please note that your SMS credit at mediclinic has been used up. To continue sending, please top up.<br /><br />Best regards,<br />Mediclinic");
            }
            else if (warningEmail.Length > 0 && checkMSCreditLowBalance && balance <= warningThreshold)  // dont send warning low balance if already sending out of credit email
            {
                SendEmail(
                    warningEmail,
                    "SMS Credit Warning - Don't Forget To Top-Up Before It Runs Out",
                    "Hi! Just a friendly reminder that the SMS reminder threshold you set has been reached.<br /> To avoid missing SMS'es being sent, don't forget to top-up before the remainder runs out!<br /><br />Best regards,<br />Mediclinic");
            }
        }

        if (incDisplay)
        {
            return("Count: <b>" + countWithPatient + "</b> &nbsp;&nbsp; [with mobile: <b>" + messagesToSMS.Count + "</b>] &nbsp;&nbsp; [with email: <b>" + messagesToEmail.Count + "</b>] " + "<br /><br />" + output);
        }
        else
        {
            return(string.Empty);
        }
    }
예제 #4
0
    protected void FillGrid()
    {
        DataTable dt = SMSCreditDataDB.GetDataTable();

        Session["data_sms_credit"] = dt;

        if (dt.Rows.Count > 0)
        {
            if (IsPostBack && Session["sortExpression_sms_credit"] != null && Session["sortExpression_sms_credit"].ToString().Length > 0)
            {
                DataView dataView = new DataView(dt);
                dataView.Sort           = Session["sortExpression_sms_credit"].ToString();
                GrdSMSCredit.DataSource = dataView;
            }
            else
            {
                GrdSMSCredit.DataSource = dt;
            }


            try
            {
                GrdSMSCredit.DataBind();
                GrdSMSCredit.PagerSettings.FirstPageText = "1";
                GrdSMSCredit.PagerSettings.LastPageText  = GrdSMSCredit.PageCount.ToString();
                GrdSMSCredit.DataBind();
            }
            catch (Exception ex)
            {
                SetErrorMessage(ex.ToString());
            }
        }
        else
        {
            dt.Rows.Add(dt.NewRow());
            GrdSMSCredit.DataSource = dt;
            GrdSMSCredit.DataBind();

            int TotalColumns = GrdSMSCredit.Rows[0].Cells.Count;
            GrdSMSCredit.Rows[0].Cells.Clear();
            GrdSMSCredit.Rows[0].Cells.Add(new TableCell());
            GrdSMSCredit.Rows[0].Cells[0].ColumnSpan = TotalColumns;
            GrdSMSCredit.Rows[0].Cells[0].Text       = "No Record Found";
        }

        if (hideFotter)
        {
            GrdSMSCredit.FooterRow.Visible = false;
        }


        decimal credit = SMSCreditDataDB.GetTotal();
        decimal used   = SMSHistoryDataDB.GetTotal();

        lblTotalCredit.Text    = credit.ToString("0.00");
        lblTotalUsed.Text      = used.ToString("0.00");
        lblTotalRemaining.Text = (credit - used).ToString("0.00");



        DateTime fromDate = IsValidDate(txtStartDate.Text) ? GetDate(txtStartDate.Text) : DateTime.MinValue;
        DateTime toDate   = IsValidDate(txtEndDate.Text)   ? GetDate(txtEndDate.Text).Add(new TimeSpan(23, 59, 59)) : DateTime.MinValue;

        decimal ptRemidners    = SMSHistoryDataDB.GetPTReminders(fromDate, toDate);
        decimal ptBirthdays    = SMSHistoryDataDB.GetPTBirthdays(fromDate, toDate);
        decimal staffRemidners = SMSHistoryDataDB.GetStaffReminders(fromDate, toDate);

        lblPTReminders.Text    = ptRemidners.ToString("0.00");
        lblPTBirthdays.Text    = ptBirthdays.ToString("0.00");
        lblStaffReminders.Text = staffRemidners.ToString("0.00");
    }
예제 #5
0
    public static string Run(bool incDisplay, bool incSending, DateTime date)
    {
        date = date.Date;

        bool   EnableDailyStaffBookingsReminderSMS    = Convert.ToInt32(SystemVariableDB.GetByDescr("EnableDailyStaffBookingsReminderSMS").Value) == 1;
        bool   EnableDailyStaffBookingsReminderEmails = Convert.ToInt32(SystemVariableDB.GetByDescr("EnableDailyStaffBookingsReminderEmails").Value) == 1;
        string Staff_Reminders_HasBothSMSandEmail     = SystemVariableDB.GetByDescr("Staff_Reminders_HasBothSMSandEmail").Value;

        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
        string callerId    = ((SystemVariables)System.Web.HttpContext.Current.Session["SystemVariables"])["Email_FromName"].Value;
        string countryCode = System.Configuration.ConfigurationManager.AppSettings["SMSTech_CountryCode"];


        // get bookings and organise the data to send/display
        Booking[] bookings = GetBookingsSortedByProviderTimeOrganisation(date);
        ArrayList list     = OrganiseData(bookings);

        // get phone nbr and email hash in one db call
        int[] entityIDs = new int[list.Count];
        for (int i = 0; i < list.Count; i++)
        {
            entityIDs[i] = ((Tuple <Staff, ArrayList>)list[i]).Item1.Person.EntityID;
        }
        Hashtable staffContactPhoneNbrHash = PatientsContactCacheDB.GetBullkPhoneNumbers(entityIDs, -1);
        Hashtable staffContactEmailHash    = PatientsContactCacheDB.GetBullkEmail(entityIDs, -1);;



        // lists to send
        ArrayList messagesToSMS   = new ArrayList();
        ArrayList messagesToEmail = new ArrayList();


        // display all bookings for debugging
        string bkOutput = "<a href=\"#\" onclick=\"   var e = document.getElementById('div_bk'); e.style.display = (e.style.display == '') ? 'none' : ''; return false; \">Show/Hide Bookings</a><br /><br />";

        bkOutput += "<div id=\"div_bk\" style=\"display:none;\" ><table border=\"1\" cellpadding=\"4\" style=\"border-collapse:collapse;\">";
        for (int i = 0; i < bookings.Length; i++)
        {
            bkOutput += "<tr><td>" + bookings[i].BookingID + "</td><td>" + bookings[i].Provider.Person.FullnameWithoutMiddlename + " [" + bookings[i].Provider.StaffID + "]</td><td>" + bookings[i].Organisation.OrganisationID + "</td><td>" + bookings[i].DateStart.ToString("HH:mm") + " - " + bookings[i].DateEnd.ToString("HH:mm") + "</td></tr>";
        }
        bkOutput += "</table></div>";


        // go through all items to add to send lists and to display for debugging
        string output = "<table border=\"1\" cellpadding=\"4\" style=\"border-collapse:collapse;\">";

        for (int i = 0; i < list.Count; i++)
        {
            Tuple <Staff, ArrayList> t = (Tuple <Staff, ArrayList>)list[i];

            string phoneNum = GetPhoneNbr(staffContactPhoneNbrHash, t.Item1.Person.EntityID, true);
            if (phoneNum != null)
            {
                phoneNum = phoneNum.StartsWith("0") ? countryCode + phoneNum.Substring(1) : phoneNum;
            }

            string email = GetEmail(staffContactEmailHash, t.Item1.Person.EntityID);


            // ignore if setting is to not sending sms's or emails
            if (phoneNum != null && (!EnableDailyStaffBookingsReminderSMS || !t.Item1.EnableDailyReminderSMS))
            {
                phoneNum = null;
            }
            if (email != null && (!EnableDailyStaffBookingsReminderEmails || !t.Item1.EnableDailyReminderEmail))
            {
                email = null;
            }

            // if balance too low, can not send by SMS
            if (phoneNum != null && balance < cost)
            {
                phoneNum = null;
            }

            // if has both, then send based on setting
            if (phoneNum != null && email != null)
            {
                if (Staff_Reminders_HasBothSMSandEmail == "Email") // setting is - when both, send only via email
                {
                    phoneNum = null;
                }
                if (Staff_Reminders_HasBothSMSandEmail == "SMS")   // setting is - when both, send only via sms
                {
                    email = null;
                }
            }


            output += "<tr>";
            output += "<td>" + "<b><u>" + t.Item1.Person.FullnameWithoutMiddlename + " [ID:" + t.Item1.StaffID + "]</u></b>";
            output += "    <table cellpadding=\"0\" cellspacing=\"0\">";
            output += "        <tr><td>" + "Mobile:</td><td>" + (phoneNum == null ? "NONE" : "<b>" + phoneNum + "</b>") + "</td></tr>";
            output += "        <tr><td>" + "Email:</td><td>" + (email == null ? "NONE" : "<b>" + email + "</b>") + "</td></tr>";
            output += "    </table>";
            output += "</td>";

            string smsText   = "Hi " + t.Item1.Person.Firstname + Environment.NewLine + "Tomorrow (" + date.ToString("dddd") + " " + Utilities.GetDateOrdinal(date.Day) + ") you have appointments at:" + Environment.NewLine;
            string emailText = "Hi " + t.Item1.Person.Firstname + "," + "<br />" + "Tomorrow (" + date.ToString("dddd") + " " + Utilities.GetDateOrdinal(date.Day) + ") you have appointments at:" + "<br /><br />";

            emailText += "<table>";
            string times = string.Empty;
            for (int j = 0; j < t.Item2.Count; j++)
            {
                Tuple <Organisation, DateTime, DateTime> t2 = (Tuple <Organisation, DateTime, DateTime>)t.Item2[j];

                smsText   += Environment.NewLine + "[" + ConvertTime(t2.Item2) + " - " + ConvertTime(t2.Item3) + "] " + t2.Item1.Name;
                emailText += "<tr><td>" + "[" + ConvertTime(t2.Item2) + " - " + ConvertTime(t2.Item3) + "]" + "</td><td><b>" + t2.Item1.Name + "</b></td></tr>";

                times += (times.Length == 0 ? "" : "<br />") + t2.Item1.Name + " [ID:" + t2.Item1.OrganisationID + "] " + ConvertTime(t2.Item2) + " - " + ConvertTime(t2.Item3);
            }
            emailText += "</table><br />Regards,<br />" + callerId;

            output += "<td>" + times + "</td>";
            output += "<td>" + "<b><font color=\"blue\">" + smsText.Replace(Environment.NewLine, "<br />") + "</font></b>" + "</td>";



            // add to lists to sms or email (or both)
            if (phoneNum != null)
            {
                messagesToSMS.Add(new Tuple <Staff, decimal, string, string, string>(t.Item1, cost, phoneNum, smsText, callerId));
                if (incSending)
                {
                    balance -= cost;
                }
            }
            if (email != null)
            {
                messagesToEmail.Add(new Tuple <Staff, string, string, string, string>(t.Item1, callerId, email, emailText, "Work locations for " + date.ToString("d MMM, yyyy")));
            }
        }

        output += "</table>";


        // run the sending and send off reminders

        if (incSending)
        {
            /*
             * run the sendings
             */

            SendSMSes((Tuple <Staff, decimal, string, string, string>[])messagesToSMS.ToArray(typeof(Tuple <Staff, decimal, string, string, string>)));
            SendEmails((Tuple <Staff, string, string, string, string>[])messagesToEmail.ToArray(typeof(Tuple <Staff, string, string, string, string>)));


            /*
             * send balance warning
             */

            SystemVariables systemVariables            = SystemVariableDB.GetAll();
            string          warningEmail               = systemVariables["SMSCreditNotificationEmailAddress"].Value;
            decimal         warningThreshold           = Convert.ToDecimal(systemVariables["SMSCreditLowBalance_Threshold"].Value);
            bool            checkSMSCreditOutOfBalance = Convert.ToInt32(systemVariables["SMSCreditOutOfBalance_SendEmail"].Value) == 1;
            bool            checkMSCreditLowBalance    = Convert.ToInt32(systemVariables["SMSCreditLowBalance_SendEmail"].Value) == 1;


            if (warningEmail.Length > 0 && checkSMSCreditOutOfBalance && balance < cost)
            {
                SendEmail(
                    warningEmail,
                    "SMS Credit Used Up",
                    "Please note that your SMS credit at mediclinic has been used up. To continue sending, please top up.<br /><br />Best regards,<br />Mediclinic");
            }
            else if (warningEmail.Length > 0 && checkMSCreditLowBalance && balance <= warningThreshold)  // dont send warning low balance if already sending out of credit email
            {
                SendEmail(
                    warningEmail,
                    "SMS Credit Warning - Don't Forget To Top-Up Before It Runs Out",
                    "Hi! Just a friendly reminder that the SMS reminder threshold you set has been reached.<br /> To avoid missing SMS'es being sent, don't forget to top-up before the remainder runs out!<br /><br />Best regards,<br />Mediclinic");
            }
        }

        if (incDisplay)
        {
            return(output + "<br />" + bkOutput);
        }
        else
        {
            return(string.Empty);
        }
    }