Example #1
0
        ///<summary>Generates all the xml up to the point where the first statement would go.</summary>
        public static void GeneratePracticeInfo(XmlWriter writer, long clinicNum)
        {
            Clinic clinic      = Clinics.GetClinic(clinicNum);
            Ebill  eBillClinic = Ebills.GetForClinic(clinicNum);

            if (eBillClinic == null)           //Clinic specific Ebill doesn't exist, use the defaults.
            {
                eBillClinic = Ebills.GetForClinic(0);
            }
            writer.WriteProcessingInstruction("xml", "version = \"1.0\" standalone=\"yes\"");
            writer.WriteStartElement("StatementFile");
            //sender address----------------------------------------------------------
            writer.WriteStartElement("SenderAddress");
            if (clinic == null)
            {
                writer.WriteElementString("Name", PrefC.GetString(PrefName.PracticeTitle));
            }
            else
            {
                writer.WriteElementString("Name", clinic.Description);
            }
            WriteAddress(writer, eBillClinic.PracticeAddress, clinic);
            writer.WriteEndElement();            //SenderAddress
            writer.WriteStartElement("Statements");
        }
Example #2
0
        //these are temporary:
        //private static string vendorID="68";
        //private static string vendorPMScode="144";
        //private static string clientAccountNumber="8011";//the dental office number set by EHG
        //private static string creditCardChoices="MC,D,V,A";//MasterCard,Discover,Visa,AmericanExpress
        //private static string userName="";
        //private static string password="";

        ///<summary>Returns empty list if no errors.  Otherwise returns a list with error messages.</summary>
        public static List <string> Validate(long clinicNum)
        {
            List <string> listErrors   = new List <string>();
            Clinic        clinic       = Clinics.GetClinic(clinicNum);
            Ebill         eBillClinic  = Ebills.GetForClinic(clinicNum);
            Ebill         eBillDefault = Ebills.GetForClinic(0);
            EHG_Address   addressRemit = null;

            if (eBillClinic == null)
            {
                addressRemit = GetAddress(eBillDefault.RemitAddress, clinic);
            }
            else
            {
                addressRemit = GetAddress(eBillClinic.RemitAddress, clinic);
            }
            if (addressRemit.Address1.Trim().Length == 0 || addressRemit.City.Trim().Length == 0 ||
                addressRemit.State.Trim().Length == 0 || addressRemit.Zip.Trim().Length == 0)
            {
                listErrors.Add(Lan.g("EHG_Statements", "invalid") + " " + Lan.g("EHG_Statements", addressRemit.Source));
            }
            return(listErrors);
        }
Example #3
0
        ///<summary>Generates all the xml up to the point where the first statement would go.</summary>
        public static void GeneratePracticeInfo(XmlWriter writer, long clinicNum)
        {
            Clinic clinic       = Clinics.GetClinic(clinicNum);
            Ebill  eBillClinic  = Ebills.GetForClinic(clinicNum);
            Ebill  eBillDefault = Ebills.GetForClinic(0);

            writer.WriteProcessingInstruction("xml", "version = \"1.0\" standalone=\"yes\"");
            writer.WriteStartElement("EISStatementFile");
            writer.WriteAttributeString("VendorID", PrefC.GetString(PrefName.BillingElectVendorId));
            writer.WriteAttributeString("OutputFormat", "StmOut_Blue6Col");
            writer.WriteAttributeString("Version", "2");
            writer.WriteElementString("SubmitDate", DateTime.Today.ToString("yyyy-MM-dd"));
            writer.WriteElementString("PrimarySubmitter", PrefC.GetString(PrefName.BillingElectVendorPMSCode));
            writer.WriteElementString("Transmitter", "EHG");
            writer.WriteStartElement("Practice");
            string billingClientAccountNumber = eBillDefault.ClientAcctNumber;

            if (eBillClinic != null && eBillClinic.ClientAcctNumber != "")         //clinic eBill entry exists, check the fields for overrides
            {
                billingClientAccountNumber = eBillClinic.ClientAcctNumber;
            }
            writer.WriteAttributeString("AccountNumber", billingClientAccountNumber);
            //sender address----------------------------------------------------------
            writer.WriteStartElement("SenderAddress");
            if (clinic == null)
            {
                writer.WriteElementString("Name", PrefC.GetString(PrefName.PracticeTitle));
            }
            else
            {
                writer.WriteElementString("Name", clinic.Description);
            }
            if (eBillClinic == null)
            {
                WriteAddress(writer, eBillDefault.PracticeAddress, clinic);
            }
            else
            {
                WriteAddress(writer, eBillClinic.PracticeAddress, clinic);
            }
            writer.WriteEndElement();            //senderAddress
            //remit address----------------------------------------------------------
            writer.WriteStartElement("RemitAddress");
            if (clinic == null)
            {
                writer.WriteElementString("Name", PrefC.GetString(PrefName.PracticeTitle));
            }
            else
            {
                writer.WriteElementString("Name", clinic.Description);
            }
            if (eBillClinic == null)
            {
                WriteAddress(writer, eBillDefault.RemitAddress, clinic);
            }
            else
            {
                WriteAddress(writer, eBillClinic.RemitAddress, clinic);
            }
            writer.WriteEndElement();            //remitAddress
            //Rendering provider------------------------------------------------------
            Provider prov = Providers.GetProv(PrefC.GetLong(PrefName.PracticeDefaultProv));

            writer.WriteStartElement("RenderingProvider");
            writer.WriteElementString("Name", prov.GetFormalName());
            writer.WriteElementString("LicenseNumber", prov.StateLicense);
            writer.WriteElementString("State", PrefC.GetString(PrefName.PracticeST));
            writer.WriteEndElement();            //Rendering provider
        }
Example #4
0
        ///<summary>Surround with try catch.  The "data" is the previously constructed xml.  If the internet connection is lost or unavailable, then the exception thrown will be a 404 error similar to the following: "The remote server returned an error: (404) Not Found"</summary>
        public static void Send(string data, long clinicNum)
        {
            //Validate the structure of the XML before sending.
            StringReader sr = new StringReader(data);

            try {
                XmlReader xmlr = XmlReader.Create(sr);
                while (xmlr.Read())                  //Read every node an ensure that there are no exceptions thrown.
                {
                }
            }
            catch (Exception ex) {
                throw new ApplicationException("Invalid XML in statement batch: " + ex.Message);
            }
            finally {
                sr.Dispose();
            }
            string strHistoryFile = "";

            if (PrefC.GetBool(PrefName.BillingElectSaveHistory))
            {
                string strHistoryDir = CodeBase.ODFileUtils.CombinePaths(ImageStore.GetPreferredAtoZpath(), "EHG_History");
                if (!Directory.Exists(strHistoryDir))
                {
                    Directory.CreateDirectory(strHistoryDir);
                }
                strHistoryFile = CodeBase.ODFileUtils.CreateRandomFile(strHistoryDir, ".txt");
                File.WriteAllText(strHistoryFile, data);
            }
            //Step 1: Post authentication request:
            Version        myVersion = new Version(Application.ProductVersion);
            HttpWebRequest webReq;
            WebResponse    response;
            StreamReader   readStream;
            string         str;

            string[] responseParams;
            string   status             = "";
            string   group              = "";
            string   userid             = "";
            string   authid             = "";
            string   errormsg           = "";
            string   alertmsg           = "";
            string   curParam           = "";
            string   serverName         = "https://claimconnect.dentalxchange.com/dci/upload.svl";//live URL for claims (According to phone call with Dentalxchange)
            string   serverNameOverride = PrefC.GetString(PrefName.BillingElectStmtUploadURL);

            if (!string.IsNullOrEmpty(serverNameOverride))
            {
                serverName = serverNameOverride;
            }
#if DEBUG
            //serverName="https://prelive.dentalxchange.com/dci/upload.svl";      //test URL for claims
            //serverName="https://claimconnect.dentalxchange.com/dci/upload.svl"; //live URL for claims
            //serverName="https://prelive.dentalxchange.com/dci/upload.svl";      //test URL for Stmts
            //serverName="https://billconnect.dentalxchange.com/dci/upload.svl";  //live URL for Stmts; probably the correct one to use.
#endif
            webReq = (HttpWebRequest)WebRequest.Create(serverName);
            Ebill  ebillDefault    = Ebills.GetForClinic(0);
            string billingUserName = ebillDefault.ElectUserName;
            string billingPassword = ebillDefault.ElectPassword;
            if (PrefC.HasClinicsEnabled && clinicNum != 0)
            {
                Ebill eBill = Ebills.GetForClinic(clinicNum);
                if (eBill != null)               //eBill entry exists, check the fields for overrides.
                {
                    if (eBill.ElectUserName != "")
                    {
                        billingUserName = eBill.ElectUserName;
                    }
                    if (eBill.ElectPassword != "")
                    {
                        billingPassword = eBill.ElectPassword;
                    }
                }
            }
            string postData =
                "Function=Auth"                                                                                                          //CONSTANT; signifies that this is an authentication request
                + "&Source=STM"                                                                                                          //CONSTANT; file format
                + "&UploaderName=OpenDental"                                                                                             //CONSTANT
                + "&UploaderVersion=" + myVersion.Major.ToString() + "." + myVersion.Minor.ToString() + "." + myVersion.Build.ToString() //eg 12.3.24
                + "&Username="******"&Password="******"POST";
            webReq.ContentType   = "application/x-www-form-urlencoded";
            webReq.ContentLength = postData.Length;
            ASCIIEncoding encoding  = new ASCIIEncoding();
            byte[]        bytes     = encoding.GetBytes(postData);
            Stream        streamOut = webReq.GetRequestStream();
            streamOut.Write(bytes, 0, bytes.Length);
            streamOut.Close();
            response = webReq.GetResponse();
            //Process the authentication response:
            readStream = new StreamReader(response.GetResponseStream(), Encoding.ASCII);
            str        = readStream.ReadToEnd();
            readStream.Close();
            if (strHistoryFile != "")           //Tack the response onto the end of the saved history file if one was created above.
            {
                File.AppendAllText(strHistoryFile, "\r\n\r\nCONNECTION REQUEST: postData.Length=" + postData.Length + " bytes.Length=" + bytes.Length + "==============\r\n"
                                   + " RESPONSE TO CONNECTION REQUEST================================================================\r\n" + str);
            }
            //Debug.WriteLine(str);
            //MessageBox.Show(str);
            responseParams = str.Split('&');
            for (int i = 0; i < responseParams.Length; i++)
            {
                curParam = GetParam(responseParams[i]);
                switch (curParam)
                {
                case "Status":
                    status = GetParamValue(responseParams[i]);
                    break;

                case "GROUP":
                    group = GetParamValue(responseParams[i]);
                    break;

                case "UserID":
                    userid = GetParamValue(responseParams[i]);
                    break;

                case "AuthenticationID":
                    authid = GetParamValue(responseParams[i]);
                    break;

                case "ErrorMessage":
                    errormsg = GetParamValue(responseParams[i]);
                    break;

                case "AlertMessage":
                    alertmsg = GetParamValue(responseParams[i]);
                    break;

                default:
                    throw new Exception("Unexpected parameter: " + curParam);
                }
            }
            //Process response for errors:
            if (alertmsg != "")
            {
                MessageBox.Show(alertmsg);
            }
            switch (status)
            {
            case "0":
                //MessageBox.Show("Authentication successful.");
                break;

            case "1":
                throw new Exception("Authentication failed. " + errormsg);

            case "2":
                throw new Exception("Cannot authenticate at this time. " + errormsg);

            case "3":
                throw new Exception("Invalid authentication request. " + errormsg);

            case "4":
                throw new Exception("Invalid program version. " + errormsg);

            case "5":
                throw new Exception("No customer contract. " + errormsg);

            default:                    //some as-yet-undefined error
                throw new Exception("Error " + status + ". " + errormsg);
            }
            //Step 2: Post upload request:
            //string fileName=Directory.GetFiles(clearhouse.ExportPath)[0];
            string boundary = "------------7d13e425b00d0";
            postData =
                "--" + boundary + "\r\n"
                + "Content-Disposition: form-data; name=\"Function\"\r\n"
                + "\r\n"
                + "Upload\r\n"
                + "--" + boundary + "\r\n"
                + "Content-Disposition: form-data; name=\"Source\"\r\n"
                + "\r\n"
                + "STM\r\n"
                + "--" + boundary + "\r\n"
                + "Content-Disposition: form-data; name=\"AuthenticationID\"\r\n"
                + "\r\n"
                + authid + "\r\n"
                + "--" + boundary + "\r\n"
                + "Content-Disposition: form-data; name=\"File\"; filename=\"" + "stmt.xml" + "\"\r\n"
                + "Content-Type: text/plain\r\n"
                + "\r\n"
                //using(StreamReader sr=new StreamReader(fileName)) {
                //	postData+=sr.ReadToEnd()+"\r\n"
                + data + "\r\n"
                + "--" + boundary + "--";
            //}
            //Debug.WriteLine(postData);
            //MessageBox.Show(postData);
            webReq = (HttpWebRequest)WebRequest.Create(serverName);
            //Timeout documentation: https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.timeout(v=vs.110).aspx.
            //Timeout: "Gets or sets the time-out value in milliseconds for the GetResponse and GetRequestStream methods."
            //Timeout default is 100 seconds, which should be sufficient in waiting for a reply from dentalxchange, since the reply is small.
            //ReadWriteTimeout documentation: https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.readwritetimeout%28v=vs.110%29.aspx
            //ReadWriteTimeout: "Gets or sets a time-out in milliseconds when writing to or reading from a stream."
            //ReadWriteTimeout default is 300 seconds (5 minutes).
            //Our message box that tells the user to wait up to 10 minutes for bills to send, therefore we need at least a 10 minute ReadWriteTimeout.
            //The user sees progress in the UI when sending.  We can increase timeouts as much as we want without making the program look like it crashed.
            webReq.ReadWriteTimeout = 600000;          //10 minutes = 10*60 seconds = 600 seconds = 600*1000 milliseconds = 600,000 milliseconds.
            webReq.KeepAlive        = false;
            webReq.Method           = "POST";
            webReq.ContentType      = "multipart/form-data; boundary=" + boundary;
            webReq.ContentLength    = postData.Length;
            bytes     = encoding.GetBytes(postData);
            streamOut = webReq.GetRequestStream();
            streamOut.Write(bytes, 0, bytes.Length);
            streamOut.Close();
            response = webReq.GetResponse();
            //Process the response
            readStream = new StreamReader(response.GetResponseStream(), Encoding.ASCII);
            str        = readStream.ReadToEnd();
            readStream.Close();
            if (strHistoryFile != "")           //Tack the response onto the end of the saved history file if one was created above.
            {
                File.AppendAllText(strHistoryFile, "\r\n\r\nUPLOAD REQUEST: postData.Length=" + postData.Length + " bytes.Length=" + bytes.Length + "==============\r\n"
                                   + " RESPONSE TO DATA UPLOAD================================================================\r\n" + str);
            }
            errormsg = "";
            status   = "";
            str      = str.Replace("\r\n", "");
            //Debug.Write(str);
            if (str.Length > 300)
            {
                throw new Exception("Unknown lengthy error message received.");
            }
            responseParams = str.Split('&');
            for (int i = 0; i < responseParams.Length; i++)
            {
                curParam = GetParam(responseParams[i]);
                switch (curParam)
                {
                case "Status":
                    status = GetParamValue(responseParams[i]);
                    break;

                case "Error Message":
                case "ErrorMessage":
                    errormsg = GetParamValue(responseParams[i]);
                    break;

                case "Filename":
                case "Timestamp":
                    break;

                case "":                        //errorMessage blank
                    break;

                default:
                    throw new Exception(str);                            //"Unexpected parameter: "+str);//curParam+"*");
                }
            }
            switch (status)
            {
            case "0":
                //MessageBox.Show("Upload successful.");
                break;

            case "1":
                throw new Exception("Authentication failed. " + errormsg);

            case "2":
                throw new Exception("Cannot upload at this time. " + errormsg);
            }
        }
Example #5
0
        private void butOK_Click(object sender, EventArgs e)
        {
            if (textDays.errorProvider1.GetError(textDays) != "")
            {
                MsgBox.Show(this, "Please fix data entry errors first.");
                return;
            }
            if (listElectBilling.SelectedIndex.In(2, 3, 4) && !Directory.Exists(textStatementURL.Text))
            {
                MsgBox.Show(this, "Please choose a valid Output Path.");
                return;
            }
            if (checkSinglePatient.Checked && checkIntermingled.Checked)
            {
                MsgBox.Show(this, "Cannot select both 'Intermingle family members' and 'Single patient only' as defaults.");
                return;
            }
            string cc = "";

            if (checkMC.Checked)
            {
                cc = "MC";
            }
            if (checkV.Checked)
            {
                if (cc != "")
                {
                    cc += ",";
                }
                cc += "V";
            }
            if (checkD.Checked)
            {
                if (cc != "")
                {
                    cc += ",";
                }
                cc += "D";
            }
            if (checkAmEx.Checked)
            {
                if (cc != "")
                {
                    cc += ",";
                }
                cc += "A";
            }
            string billingUseElectronic = listElectBilling.SelectedIndex.ToString();

            SaveEbill(_eBillCur);
            if (listElectBilling.SelectedIndex == 1 && string.IsNullOrEmpty(textStatementURL.Text))
            {
                textStatementURL.Text = @"https://claimconnect.dentalxchange.com/dci/upload.svl";              //default value from before 16.2.19
            }
            string modesToText = string.Join(",", listModesToText.SelectedTags <StatementMode>().Select(x => POut.Int((int)x)));

            if (Prefs.UpdateLong(PrefName.BillingDefaultsLastDays, PIn.Long(textDays.Text))
                | Prefs.UpdateBool(PrefName.BillingDefaultsIntermingle, checkIntermingled.Checked)
                | Prefs.UpdateString(PrefName.BillingDefaultsNote, textNote.Text)
                | Prefs.UpdateString(PrefName.BillingUseElectronic, billingUseElectronic)
                | Prefs.UpdateString(PrefName.BillingEmailSubject, textBillingEmailSubject.Text)
                | Prefs.UpdateString(PrefName.BillingEmailBodyText, textBillingEmailBody.Text)
                | Prefs.UpdateString(PrefName.BillingElectVendorId, textVendorId.Text)
                | Prefs.UpdateString(PrefName.BillingElectVendorPMSCode, textVendorPMScode.Text)
                | Prefs.UpdateString(PrefName.BillingElectCreditCardChoices, cc)
                | Prefs.UpdateString(PrefName.BillingDefaultsInvoiceNote, textInvoiceNote.Text)
                | Prefs.UpdateBool(PrefName.BillingElectCreatePDF, checkCreatePDF.Checked)
                | (listElectBilling.SelectedIndex == 1 && Prefs.UpdateString(PrefName.BillingElectStmtUploadURL, textStatementURL.Text))
                | (listElectBilling.SelectedIndex == 2 && Prefs.UpdateString(PrefName.BillingElectStmtOutputPathPos, textStatementURL.Text))
                | (listElectBilling.SelectedIndex == 3 && Prefs.UpdateString(PrefName.BillingElectStmtOutputPathClaimX, textStatementURL.Text))
                | (listElectBilling.SelectedIndex == 4 && Prefs.UpdateString(PrefName.BillingElectStmtOutputPathEds, textStatementURL.Text))
                | Prefs.UpdateBool(PrefName.BillingDefaultsSinglePatient, checkSinglePatient.Checked)
                | Prefs.UpdateString(PrefName.BillingDefaultsModesToText, modesToText)
                | Prefs.UpdateString(PrefName.BillingDefaultsSmsTemplate, textSmsTemplate.Text)
                | Prefs.UpdateBool(PrefName.BillingShowTransSinceBalZero, checkBoxBillShowTransSinceZero.Checked))
            {
                DataValid.SetInvalid(InvalidType.Prefs);
            }
            if (Ebills.Sync(_listEbills, _listEbillsOld))            //Includes the default Ebill
            {
                DataValid.SetInvalid(InvalidType.Ebills);            //Also updates cache.
            }
            DialogResult = DialogResult.OK;
        }
Example #6
0
        private void FormBillingDefaults_Load(object sender, EventArgs e)
        {
            textDays.Text                          = PrefC.GetLong(PrefName.BillingDefaultsLastDays).ToString();
            checkIntermingled.Checked              = PrefC.GetBool(PrefName.BillingDefaultsIntermingle);
            checkSinglePatient.Checked             = PrefC.GetBool(PrefName.BillingDefaultsSinglePatient);
            textNote.Text                          = PrefC.GetString(PrefName.BillingDefaultsNote);
            checkCreatePDF.Checked                 = PrefC.GetBool(PrefName.BillingElectCreatePDF);
            checkBoxBillShowTransSinceZero.Checked = PrefC.GetBool(PrefName.BillingShowTransSinceBalZero);
            listElectBilling.SelectedIndex         = 0;
            int billingUseElectronicIdx = PrefC.GetInt(PrefName.BillingUseElectronic);

            if (billingUseElectronicIdx == 1)
            {
                listElectBilling.SelectedIndex = 1;
                checkCreatePDF.Enabled         = true;
                labelBlankForDefault.Visible   = true;
            }
            if (billingUseElectronicIdx == 2)
            {
                listElectBilling.SelectedIndex = 2;
            }
            if (billingUseElectronicIdx == 3)
            {
                checkCreatePDF.Enabled         = true;
                listElectBilling.SelectedIndex = 3;
            }
            if (billingUseElectronicIdx == 4)
            {
                listElectBilling.SelectedIndex = 4;
            }
            arrayOutputPaths[0]    = "";       //Will never be used, but is helpful to keep the indexes of arrayOutputPaths aligned with the options listed in listElectBilling.
            arrayOutputPaths[1]    = PrefC.GetString(PrefName.BillingElectStmtUploadURL);
            arrayOutputPaths[2]    = PrefC.GetString(PrefName.BillingElectStmtOutputPathPos);
            arrayOutputPaths[3]    = PrefC.GetString(PrefName.BillingElectStmtOutputPathClaimX);
            arrayOutputPaths[4]    = PrefC.GetString(PrefName.BillingElectStmtOutputPathEds);
            textStatementURL.Text  = arrayOutputPaths[billingUseElectronicIdx];
            textVendorId.Text      = PrefC.GetString(PrefName.BillingElectVendorId);
            textVendorPMScode.Text = PrefC.GetString(PrefName.BillingElectVendorPMSCode);
            string cc = PrefC.GetString(PrefName.BillingElectCreditCardChoices);

            if (cc.Contains("MC"))
            {
                checkMC.Checked = true;
            }
            if (cc.Contains("V"))
            {
                checkV.Checked = true;
            }
            if (cc.Contains("D"))
            {
                checkD.Checked = true;
            }
            if (cc.Contains("A"))
            {
                checkAmEx.Checked = true;
            }
            textBillingEmailSubject.Text = PrefC.GetString(PrefName.BillingEmailSubject);
            textBillingEmailBody.Text    = PrefC.GetString(PrefName.BillingEmailBodyText);
            textInvoiceNote.Text         = PrefC.GetString(PrefName.BillingDefaultsInvoiceNote);
            _listEbills    = Ebills.GetDeepCopy();
            _listEbillsOld = _listEbills.Select(x => x.Copy()).ToList();
            //Find the default Ebill
            for (int i = 0; i < _listEbills.Count; i++)
            {
                if (_listEbills[i].ClinicNum == 0)
                {
                    _eBillDefault = _listEbills[i];
                }
            }
            if (_eBillDefault == null)
            {
                MsgBox.Show(this, "The default ebill entry is missing. Run " + nameof(DatabaseMaintenances.EbillMissingDefaultEntry)
                            + " in the Database Maintenance Tool before continuing.");
                DialogResult = DialogResult.Cancel;
                return;
            }
            _eBillCur = _eBillDefault;
            //Set the textboxes to default values.
            textClientAcctNumber.Text = _eBillDefault.ClientAcctNumber;
            textUserName.Text         = _eBillDefault.ElectUserName;
            textPassword.Text         = _eBillDefault.ElectPassword;
            string[] arrayEbillAddressEnums = Enum.GetNames(typeof(EbillAddress));
            for (int i = 0; i < arrayEbillAddressEnums.Length; i++)
            {
                comboPracticeAddr.Items.Add(arrayEbillAddressEnums[i]);
                comboRemitAddr.Items.Add(arrayEbillAddressEnums[i]);
                //If clinics are off don't add the Clinic specific EbillAddress enums
                if (!PrefC.HasClinicsEnabled && i == 2)
                {
                    break;
                }
            }
            if (PrefC.HasClinicsEnabled)
            {
                comboClinic.Visible = true;
                labelClinic.Visible = true;
                //Bold clinic specific fields.
                groupBoxBilling.Text   = Lan.g(this, "Electronic Billing - Bolded fields are clinic specific");
                labelAcctNum.Font      = new Font(labelAcctNum.Font, FontStyle.Bold);
                labelUserName.Font     = new Font(labelUserName.Font, FontStyle.Bold);
                labelPassword.Font     = new Font(labelPassword.Font, FontStyle.Bold);
                labelClinic.Font       = new Font(labelClinic.Font, FontStyle.Bold);
                labelPracticeAddr.Font = new Font(labelPracticeAddr.Font, FontStyle.Bold);
                labelRemitAddr.Font    = new Font(labelRemitAddr.Font, FontStyle.Bold);
                comboClinic.Items.Clear();
                _listClinics = new List <Clinic>();
                //Add "Unassigned/Default" option if the user isn't restricted or the selected clinic is 0.
                if (!Security.CurUser.ClinicIsRestricted || Clinics.ClinicNum == 0)
                {
                    Clinic clinicUnassigned = new Clinic();
                    clinicUnassigned.ClinicNum = 0;
                    clinicUnassigned.Abbr      = Lan.g(this, "Unassigned/Default");
                    _listClinics.Add(clinicUnassigned);
                }
                _listClinics.AddRange(Clinics.GetForUserod(Security.CurUser));
                for (int i = 0; i < _listClinics.Count; i++)
                {
                    comboClinic.Items.Add(_listClinics[i].Abbr);
                    //If the clinic we're adding is the one currently selected in OD, attempt to find its Ebill entry.
                    if (_listClinics[i].ClinicNum == Clinics.ClinicNum)
                    {
                        comboClinic.SelectedIndex = i;
                        Ebill eBill = null;
                        if (Clinics.ClinicNum == 0)                       //Use the default Ebill if OD has Headquarters selected or if clinics are disabled.
                        {
                            eBill = _eBillDefault;
                        }
                        else
                        {
                            eBill = _listEbills.FirstOrDefault(x => x.ClinicNum == _listClinics[i].ClinicNum);                        //Can be null.
                        }
                        //_eBillCur will be the default Ebill, the clinic's Ebill, or null if there are no existing ebills for OD's selected clinic.
                        _eBillCur = eBill;
                    }
                }
            }
            listModesToText.Items.Clear();
            foreach (StatementMode stateMode in Enum.GetValues(typeof(StatementMode)))
            {
                listModesToText.Items.Add(new ODBoxItem <StatementMode>(Lan.g("enumStatementMode", stateMode.GetDescription()), stateMode));
            }
            foreach (string modeIdx in PrefC.GetString(PrefName.BillingDefaultsModesToText)
                     .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries))
            {
                listModesToText.SetSelected(PIn.Int(modeIdx), true);
            }
            textSmsTemplate.Text = PrefC.GetString(PrefName.BillingDefaultsSmsTemplate);
            //Load _eBillCur's fields into the UI.
            LoadEbill(_eBillCur);
        }