예제 #1
0
        ///<summary>Will throw an error if not authorized and message not suppressed.</summary>
        public static bool IsAuthorized(Permissions perm, DateTime date, bool suppressMessage, long userGroupNum)
        {
            //No need to check RemotingRole; no call to db.
            if (!GroupPermissions.HasPermission(userGroupNum, perm))
            {
                if (!suppressMessage)
                {
                    throw new Exception(Lans.g("Security", "Not authorized for") + "\r\n" + GroupPermissions.GetDesc(perm));
                }
                return(false);
            }
            if (perm == Permissions.AccountingCreate || perm == Permissions.AccountingEdit)
            {
                if (date <= PrefC.GetDate(PrefName.AccountingLockDate))
                {
                    if (!suppressMessage)
                    {
                        throw new Exception(Lans.g("Security", "Locked by Administrator."));
                    }
                    return(false);
                }
            }
            //Check the global security lock------------------------------------------------------------------------------------
            //the list below is NOT the list of permissions that take dates. See GroupPermissions.PermTakesDates().
            if (perm == Permissions.AdjustmentCreate ||
                perm == Permissions.AdjustmentEdit ||
                perm == Permissions.PaymentCreate ||
                perm == Permissions.PaymentEdit ||
                perm == Permissions.ProcComplCreate ||
                perm == Permissions.ProcComplEdit
                //|| perm==Permissions.ImageDelete
                || perm == Permissions.InsPayCreate ||
                perm == Permissions.InsPayEdit ||
                perm == Permissions.SheetEdit ||
                perm == Permissions.CommlogEdit
                )
            {
                //If the global lock is date-based:
                if (date.Year > 1 &&          //if a valid date was passed in
                    date <= PrefC.GetDate(PrefName.SecurityLockDate))                       //and that date is earlier than the lock
                {
                    if (PrefC.GetBool(PrefName.SecurityLockIncludesAdmin) ||                //if admins are locked out too
                        !GroupPermissions.HasPermission(userGroupNum, Permissions.SecurityAdmin))                          //or is not an admin
                    {
                        if (!suppressMessage)
                        {
                            throw new Exception(Lans.g("Security", "Locked by Administrator before ") + PrefC.GetDate(PrefName.SecurityLockDate).ToShortDateString());
                        }
                        return(false);
                    }
                }
                //If the global lock is days-based:
                if (date.Year > 1 &&          //if a valid date was passed in
                    PrefC.GetInt(PrefName.SecurityLockDays) > 0 &&
                    date <= DateTime.Today.AddDays(-PrefC.GetInt(PrefName.SecurityLockDays)))                       //and that date is earlier than the lock
                {
                    if (PrefC.GetBool(PrefName.SecurityLockIncludesAdmin) ||                //if admins are locked out too
                        !GroupPermissions.HasPermission(userGroupNum, Permissions.SecurityAdmin))                          //or is not an admin
                    {
                        if (!suppressMessage)
                        {
                            throw new Exception(Lans.g("Security", "Locked by Administrator before ") + PrefC.GetInt(PrefName.SecurityLockDays).ToString() + " days.");
                        }
                        return(false);
                    }
                }
            }
            //Check date/days limits on individual permission----------------------------------------------------------------
            if (!GroupPermissions.PermTakesDates(perm))
            {
                return(true);
            }
            DateTime dateLimit = GetDateLimit(perm, userGroupNum);

            if (date > dateLimit)          //authorized
            {
                return(true);
            }
            //Prevents certain bugs when 1/1/1 dates are passed in and compared----------------------------------------------
            //Handling of min dates.  There might be others, but we have to handle them individually to avoid introduction of bugs.
            if (perm == Permissions.ClaimSentEdit ||      //no date sent was entered before setting claim received
                perm == Permissions.ProcComplEdit ||              //a completed procedure with a min date.
                perm == Permissions.InsPayEdit ||              //a claim payment with no date.
                perm == Permissions.TreatPlanEdit ||
                perm == Permissions.AdjustmentEdit ||
                perm == Permissions.CommlogEdit ||              //usually from a conversion
                perm == Permissions.ProcDelete)                 //because older versions did not set the DateEntryC.
            {
                if (date.Year < 1880 && dateLimit.Year < 1880)
                {
                    return(true);
                }
            }
            if (!suppressMessage)
            {
                throw new Exception(Lans.g("Security", "Not authorized for") + "\r\n"
                                    + GroupPermissions.GetDesc(perm) + "\r\n" + Lans.g("Security", "Date limitation"));
            }
            return(false);
        }
예제 #2
0
        public static DataTable GetProvList(DateTime dt)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetTable(MethodBase.GetCurrentMethod(), dt));
            }
#if DEBUG
            _elapsedTimeProvList = "";
            System.Diagnostics.Stopwatch stopWatch      = new System.Diagnostics.Stopwatch();
            System.Diagnostics.Stopwatch stopWatchTotal = new System.Diagnostics.Stopwatch();
            _elapsedTimeProvList = "Elapsed time for GetProvList:\r\n";
            stopWatch.Restart();
            stopWatchTotal.Restart();
#endif
            Random rnd    = new Random();
            string rndStr = rnd.Next(1000000).ToString();
            string command;
            command = "DROP TABLE IF EXISTS tempdash" + rndStr + @";";
            Db.NonQ(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProvList += "DROP TABLE: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            command = @"CREATE TABLE tempdash" + rndStr + @" (
				ProvNum bigint NOT NULL PRIMARY KEY,
				production decimal NOT NULL,
				income decimal NOT NULL
				) DEFAULT CHARSET=utf8"                ;
            Db.NonQ(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProvList += "CREATE TABLE: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            //providers
            command = @"INSERT INTO tempdash" + rndStr + @" (ProvNum)
				SELECT ProvNum
				FROM provider WHERE IsHidden=0
				ORDER BY ItemOrder"                ;
            Db.NonQ(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProvList += "providers: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            //production--------------------------------------------------------------------
            //procs
            command = @"UPDATE tempdash" + rndStr + @" 
				SET production=(SELECT SUM(ProcFee*(UnitQty+BaseUnits)) FROM procedurelog 
				WHERE procedurelog.ProvNum=tempdash"                 + rndStr + @".ProvNum
				AND procedurelog.ProcStatus="                 + POut.Int((int)ProcStat.C) + @"
				AND ProcDate="                 + POut.Date(dt) + ")";
            Db.NonQ(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProvList += "production - procs: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            //capcomplete writeoffs were skipped
            //adjustments
            command = @"UPDATE tempdash" + rndStr + @" 
				SET production=production+(SELECT IFNULL(SUM(AdjAmt),0) FROM adjustment 
				WHERE adjustment.ProvNum=tempdash"                 + rndStr + @".ProvNum
				AND AdjDate="                 + POut.Date(dt) + ")";
            Db.NonQ(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProvList += "production - adjustments: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            //insurance writeoffs
            if (PrefC.GetBool(PrefName.ReportsPPOwriteoffDefaultToProcDate))                                     //use procdate
            {
                command = @"UPDATE tempdash" + rndStr + @" 
					SET production=production-(SELECT IFNULL(SUM(WriteOff),0) FROM claimproc 
					WHERE claimproc.ProvNum=tempdash"                     + rndStr + @".ProvNum
					AND ProcDate="                     + POut.Date(dt) + @" 
					AND (claimproc.Status=1 OR claimproc.Status=4 OR claimproc.Status=0) )"                    ; //received or supplemental or notreceived
            }
            else
            {
                command = @"UPDATE tempdash" + rndStr + @" 
					SET production=production-(SELECT IFNULL(SUM(WriteOff),0) FROM claimproc 
					WHERE claimproc.ProvNum=tempdash"                     + rndStr + @".ProvNum
					AND DateCP="                     + POut.Date(dt) + @" 
					AND (claimproc.Status=1 OR claimproc.Status=4) )"                    ;//received or supplemental
            }
            Db.NonQ(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProvList += "production - writeoffs: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            //income------------------------------------------------------------------------
            //patient income
            command = @"UPDATE tempdash" + rndStr + @" 
				SET income=(SELECT SUM(SplitAmt) FROM paysplit 
				WHERE paysplit.ProvNum=tempdash"                 + rndStr + @".ProvNum
				AND DatePay="                 + POut.Date(dt) + ")";
            Db.NonQ(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProvList += "income - patient: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            //ins income
            command = @"UPDATE tempdash" + rndStr + @" 
				SET income=income+(SELECT IFNULL(SUM(InsPayAmt),0) FROM claimproc 
				WHERE claimproc.ProvNum=tempdash"                 + rndStr + @".ProvNum
				AND DateCP="                 + POut.Date(dt) + ")";
            Db.NonQ(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProvList += "income - insurance: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            //final queries
            command = "SELECT * FROM tempdash" + rndStr + @"";
            DataTable table = Db.GetTable(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProvList += "SELECT * : " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            command = "DROP TABLE IF EXISTS tempdash" + rndStr + @";";
            Db.NonQ(command);
#if DEBUG
            stopWatch.Stop();
            stopWatchTotal.Stop();
            _elapsedTimeProvList += "DROP TABLE: " + stopWatch.Elapsed.ToString() + "\r\n";
            _elapsedTimeProvList += "Total: " + stopWatchTotal.Elapsed.ToString();
            if (_showElapsedTimesForDebug)
            {
                System.Windows.Forms.MessageBox.Show(_elapsedTimeProvList);
            }
#endif
            return(table);
        }
예제 #3
0
        ///<summary>Returns the status code of the web call made to Podium.
        ///200-299 indicates a successful response, >=300 indicates a Podium error response, negative status codes indicate an Open Dental error.</summary>
        private static int MakeWebCall(string apiToken, string apiUrl, string locationId, string phoneNumber, Patient pat)
        {
            int retVal = -100;

            if (pat.TxtMsgOk == YN.No || (pat.TxtMsgOk == YN.Unknown && PrefC.GetBool(PrefName.TextMsgOkStatusTreatAsNo))) //Use email.
            {
                retVal      = -200;                                                                                        //Our code for 'no email address'
                phoneNumber = "";                                                                                          //Ensure that there is no way we send a phone number to Podium if the patient doesn't approve text messages.
                if (string.IsNullOrEmpty(pat.Email))
                {
                    return(retVal);                   //Will be -200, meaning no email and can't text.
                }
            }
            if (string.IsNullOrWhiteSpace(phoneNumber) && string.IsNullOrWhiteSpace(pat.Email))
            {
                return(retVal);
            }
            //We either have a phoneNumber or email (or both), so send it to Podium.
            string isTestString = "false";

#if DEBUG
            isTestString = "true";
#endif
            try {
                using (WebClientEx client = new WebClientEx()) {
                    client.Headers[HttpRequestHeader.Accept]        = "application/json";
                    client.Headers[HttpRequestHeader.ContentType]   = "application/json";
                    client.Headers[HttpRequestHeader.Authorization] = "Token token=\"" + apiToken + "\"";
                    client.Encoding = UnicodeEncoding.UTF8;
                    string bodyJson = string.Format(@"
							{{
								""locationId"": ""{0}"",
								""lastName"": ""{3}"",
								""firstName"": ""{2}"",
								""email"": ""{4}"",
								""phoneNumber"": ""{1}"",
								""integrationName"": ""opendental"",
								""test"": {5}
							}}"                            , locationId, phoneNumber, pat.FName, pat.LName, pat.Email, isTestString);
                    //Post with Authorization headers and a body comprised of a JSON serialized anonymous type.
                    client.UploadString(apiUrl, "POST", bodyJson);
                    retVal = (int)(client.StatusCode);
                }
            }
            catch (WebException we) {
                if (we.Response.GetType() == typeof(HttpWebResponse))
                {
                    retVal = (int)((HttpWebResponse)we.Response).StatusCode;
                }
            }
            catch (Exception) {
                //Do nothing because a verbose commlog will be made below if all phone numbers fail.
            }
            return(retVal);
            //Sample Request:

            //Accept: 'application/json's
            //Content-Type: 'application/json'
            //Authorization: 'Token token="my_dummy_token"'
            //Body:
            //{
            //	"location_id": "54321",
            //	"phone_number": "1234567890",
            //	"customer": {
            //		"first_name": "Johnny",
            //		"last_name": "Appleseed",
            //		"email": "*****@*****.**"
            //	},
            //	"test": true
            //}
            //NOTE:  There will never be a value after "customer": although it was initially interpreted that there would be a "new" flag there.
        }
예제 #4
0
        ///<summary>Surrond with Try/Catch. Error messages will be thrown to caller.</summary>
        public static bool IsGlobalDateLock(Permissions perm, DateTime date, bool isSilent = false, long codeNum = 0, double procFee = -1, long sheetDefNum = 0)
        {
            if (!(new[] {
                Permissions.AdjustmentCreate
                , Permissions.AdjustmentEdit
                , Permissions.PaymentCreate
                , Permissions.PaymentEdit
                , Permissions.ProcComplCreate
                , Permissions.ProcComplEdit
                , Permissions.ProcExistingEdit
                //,Permissions.ProcComplEditLimited
                //,Permissions.ImageDelete
                , Permissions.InsPayCreate
                , Permissions.InsPayEdit
                //,Permissions.InsWriteOffEdit//per Nathan 7/5/2016 this should not be affected by the global date lock
                , Permissions.SheetEdit
                , Permissions.SheetDelete
                , Permissions.CommlogEdit
                //,Permissions.ClaimDelete //per Nathan 01/18/2018 this should not be affected by the global date lock
                , Permissions.PayPlanEdit
                //,Permissions.ClaimHistoryEdit //per Nathan & Mark 03/01/2018 this should not be affected by the global lock date, not financial data.
            }).Contains(perm))
            {
                return(false);               //permission being checked is not affected by global lock date.
            }
            if (date.Year == 1)
            {
                return(false);               //Invalid or MinDate passed in.
            }
            if (!PrefC.GetBool(PrefName.SecurityLockIncludesAdmin) && GroupPermissions.HasPermission(Security.CurUser, Permissions.SecurityAdmin, 0))
            {
                return(false);               //admins are never affected by global date limitation when preference is false.
            }
            if (perm.In(Permissions.ProcComplCreate, Permissions.ProcComplEdit, Permissions.ProcExistingEdit) &&
                ProcedureCodes.CanBypassLockDate(codeNum, procFee))
            {
                return(false);
            }
            if (perm.In(Permissions.SheetEdit, Permissions.SheetDelete) && sheetDefNum > 0 && SheetDefs.CanBypassLockDate(sheetDefNum))
            {
                return(false);
            }
            //If global lock is Date based.
            if (date <= PrefC.GetDate(PrefName.SecurityLockDate))
            {
                if (!isSilent)
                {
                    MessageBox.Show(Lans.g("Security", "Locked by Administrator before ") + PrefC.GetDate(PrefName.SecurityLockDate).ToShortDateString());
                }
                return(true);
            }
            //If global lock is days based.
            int lockDays = PrefC.GetInt(PrefName.SecurityLockDays);

            if (lockDays > 0 && date <= DateTime.Today.AddDays(-lockDays))
            {
                if (!isSilent)
                {
                    MessageBox.Show(Lans.g("Security", "Locked by Administrator before ") + lockDays.ToString() + " days.");
                }
                return(true);
            }
            return(false);
        }
예제 #5
0
        public static DataTable GetProvList(DateTime dt)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetTable(MethodBase.GetCurrentMethod(), dt));
            }
            string command;

            command = "DROP TABLE IF EXISTS tempdash;";
            Db.NonQ(command);
            command = @"CREATE TABLE tempdash (
				ProvNum bigint NOT NULL PRIMARY KEY,
				production decimal NOT NULL,
				income decimal NOT NULL
				) DEFAULT CHARSET=utf8"                ;
            Db.NonQ(command);
            //providers
            command = @"INSERT INTO tempdash (ProvNum)
				SELECT ProvNum
				FROM provider WHERE IsHidden=0
				ORDER BY ItemOrder"                ;
            Db.NonQ(command);
            //production--------------------------------------------------------------------
            //procs
            command = @"UPDATE tempdash 
				SET production=(SELECT SUM(ProcFee*(UnitQty+BaseUnits)) FROM procedurelog 
				WHERE procedurelog.ProvNum=tempdash.ProvNum
				AND procedurelog.ProcStatus="                 + POut.Int((int)ProcStat.C) + @"
				AND ProcDate="                 + POut.Date(dt) + ")";
            Db.NonQ(command);
            //capcomplete writeoffs were skipped
            //adjustments
            command = @"UPDATE tempdash 
				SET production=production+(SELECT IFNULL(SUM(AdjAmt),0) FROM adjustment 
				WHERE adjustment.ProvNum=tempdash.ProvNum
				AND AdjDate="                 + POut.Date(dt) + ")";
            Db.NonQ(command);
            //insurance writeoffs
            if (PrefC.GetBool(PrefName.ReportsPPOwriteoffDefaultToProcDate))                                     //use procdate
            {
                command = @"UPDATE tempdash 
					SET production=production-(SELECT IFNULL(SUM(WriteOff),0) FROM claimproc 
					WHERE claimproc.ProvNum=tempdash.ProvNum
					AND ProcDate="                     + POut.Date(dt) + @" 
					AND (claimproc.Status=1 OR claimproc.Status=4 OR claimproc.Status=0) )"                    ; //received or supplemental or notreceived
            }
            else
            {
                command = @"UPDATE tempdash 
					SET production=production-(SELECT IFNULL(SUM(WriteOff),0) FROM claimproc 
					WHERE claimproc.ProvNum=tempdash.ProvNum
					AND DateCP="                     + POut.Date(dt) + @" 
					AND (claimproc.Status=1 OR claimproc.Status=4) )"                    ;//received or supplemental
            }
            Db.NonQ(command);
            //income------------------------------------------------------------------------
            //patient income
            command = @"UPDATE tempdash 
				SET income=(SELECT SUM(SplitAmt) FROM paysplit 
				WHERE paysplit.ProvNum=tempdash.ProvNum
				AND DatePay="                 + POut.Date(dt) + ")";
            Db.NonQ(command);
            //ins income
            command = @"UPDATE tempdash 
				SET income=income+(SELECT IFNULL(SUM(InsPayAmt),0) FROM claimproc 
				WHERE claimproc.ProvNum=tempdash.ProvNum
				AND DateCP="                 + POut.Date(dt) + ")";
            Db.NonQ(command);
            //final queries
            command = "SELECT * FROM tempdash";
            DataTable table = Db.GetTable(command);

            command = "DROP TABLE IF EXISTS tempdash;";
            Db.NonQ(command);
            return(table);
        }
예제 #6
0
        ///<summary>Should only be called if ODHQ.</summary>
        private static List <Procedure> AddSmsRepeatingChargesHelper(DateTime dateRun)
        {
            //No remoting role check; no call to db
            DateTime          dateStart       = new DateTime(dateRun.AddMonths(-1).AddDays(-20).Year, dateRun.AddMonths(-1).AddDays(-20).Month, 1);
            DateTime          dateStop        = dateRun.AddDays(1);
            List <SmsBilling> listSmsBilling  = SmsBillings.GetByDateRange(dateStart, dateStop);
            List <Patient>    listPatients    = Patients.GetMultPats(listSmsBilling.Select(x => x.CustPatNum).Distinct().ToList()).ToList();    //local cache
            ProcedureCode     procCodeAccess  = ProcedureCodes.GetProcCode("038");
            ProcedureCode     procCodeUsage   = ProcedureCodes.GetProcCode("039");
            ProcedureCode     procCodeConfirm = ProcedureCodes.GetProcCode("040");
            List <Procedure>  listProcsAccess = Procedures.GetCompletedForDateRange(dateStart, dateStop, new List <long> {
                procCodeAccess.CodeNum
            });
            List <Procedure> listProcsUsage = Procedures.GetCompletedForDateRange(dateStart, dateStop, new List <long> {
                procCodeUsage.CodeNum
            });
            List <Procedure> listProcsConfirm = Procedures.GetCompletedForDateRange(dateStart, dateStop, new List <long> {
                procCodeConfirm.CodeNum
            });
            List <Procedure> retVal = new List <Procedure>();

            foreach (SmsBilling smsBilling in listSmsBilling)
            {
                Patient pat = listPatients.FirstOrDefault(x => x.PatNum == smsBilling.CustPatNum);
                if (pat == null)
                {
                    EServiceSignal eSignal = new EServiceSignal {
                        ServiceCode = (int)eServiceCode.IntegratedTexting,
                        SigDateTime = MiscData.GetNowDateTime(),
                        Severity    = eServiceSignalSeverity.Error,
                        Description = "Sms billing row found for non existent patient PatNum:" + smsBilling.CustPatNum
                    };
                    EServiceSignals.Insert(eSignal);
                    continue;
                }
                //Find the billing date based on the date usage.
                DateTime billingDate = smsBilling.DateUsage.AddMonths(1);              //we always bill the month after usage posts. Example: all January usage = 01/01/2015
                billingDate = new DateTime(
                    billingDate.Year,
                    billingDate.Month,
                    Math.Min(pat.BillingCycleDay, DateTime.DaysInMonth(billingDate.Year, billingDate.Month)));
                //example: dateUsage=08/01/2015, billing cycle date=8/14/2012, billing date should be 9/14/2015.
                if (billingDate > dateRun || billingDate < dateRun.AddMonths(-1).AddDays(-20))
                {
                    //One month and 20 day window. Bill regardless of presence of "038" repeat charge.
                    continue;
                }
                if (smsBilling.AccessChargeTotalUSD == 0 && smsBilling.MsgChargeTotalUSD == 0 && smsBilling.ConfirmationChargeTotalUSD == 0)
                {
                    //No charges so skip this customer.
                    continue;
                }
                //Only post confirmation charge if valid.
                if (smsBilling.ConfirmationChargeTotalUSD > 0 &&
                    (billingDate <= DateTime.Today || PrefC.GetBool(PrefName.FutureTransDatesAllowed) &&
                     !listProcsConfirm.Exists(x => x.PatNum == pat.PatNum && x.ProcDate.Year == billingDate.Year && x.ProcDate.Month == billingDate.Month)))
                {
                    //The calculated access charge was greater than 0 and there is not an existing "038" procedure on the account for that month.
                    Procedure procConfirm = new Procedure();
                    procConfirm.CodeNum        = procCodeConfirm.CodeNum;
                    procConfirm.DateEntryC     = DateTime.Today;
                    procConfirm.PatNum         = pat.PatNum;
                    procConfirm.ProcDate       = billingDate;
                    procConfirm.DateTP         = billingDate;
                    procConfirm.ProcFee        = smsBilling.ConfirmationChargeTotalUSD;
                    procConfirm.ProcStatus     = ProcStat.C;
                    procConfirm.ProvNum        = PrefC.GetLong(PrefName.PracticeDefaultProv);
                    procConfirm.MedicalCode    = procCodeConfirm.MedicalCode;
                    procConfirm.BaseUnits      = procCodeConfirm.BaseUnits;
                    procConfirm.DiagnosticCode = PrefC.GetString(PrefName.ICD9DefaultForNewProcs);
                    procConfirm.BillingNote    = smsBilling.BillingDescConfirmation;
                    procConfirm.PlaceService   = (PlaceOfService)PrefC.GetInt(PrefName.DefaultProcedurePlaceService);                //Default Proc Place of Service for the Practice is used.
                    Procedures.Insert(procConfirm);
                    listProcsConfirm.Add(procConfirm);
                    retVal.Add(procConfirm);
                }
                //Confirmation charges may wipe out access charges. We still want to see the $0 charge in this case so post this charge if either of the 2 are valid.
                if ((smsBilling.AccessChargeTotalUSD > 0 || smsBilling.ConfirmationChargeTotalUSD > 0) &&
                    (billingDate <= DateTime.Today || PrefC.GetBool(PrefName.FutureTransDatesAllowed)) &&
                    !listProcsAccess.Exists(x => x.PatNum == pat.PatNum && x.ProcDate.Year == billingDate.Year && x.ProcDate.Month == billingDate.Month))
                {
                    //The calculated access charge was greater than 0 and there is not an existing "038" procedure on the account for that month.
                    Procedure procAccess = new Procedure();
                    procAccess.CodeNum        = procCodeAccess.CodeNum;
                    procAccess.DateEntryC     = DateTime.Today;
                    procAccess.PatNum         = pat.PatNum;
                    procAccess.ProcDate       = billingDate;
                    procAccess.DateTP         = billingDate;
                    procAccess.ProcFee        = smsBilling.AccessChargeTotalUSD;
                    procAccess.ProcStatus     = ProcStat.C;
                    procAccess.ProvNum        = PrefC.GetLong(PrefName.PracticeDefaultProv);
                    procAccess.MedicalCode    = procCodeAccess.MedicalCode;
                    procAccess.BaseUnits      = procCodeAccess.BaseUnits;
                    procAccess.DiagnosticCode = PrefC.GetString(PrefName.ICD9DefaultForNewProcs);
                    procAccess.BillingNote    = smsBilling.BillingDescSms;
                    procAccess.PlaceService   = (PlaceOfService)PrefC.GetInt(PrefName.DefaultProcedurePlaceService);                //Default Proc Place of Service for the Practice is used.
                    Procedures.Insert(procAccess);
                    listProcsAccess.Add(procAccess);
                    retVal.Add(procAccess);
                }
                //Only post usage charge if valid.
                if (smsBilling.MsgChargeTotalUSD > 0 &&
                    (billingDate <= DateTime.Today || PrefC.GetBool(PrefName.FutureTransDatesAllowed)) &&
                    !listProcsUsage.Exists(x => x.PatNum == pat.PatNum && x.ProcDate.Year == billingDate.Year && x.ProcDate.Month == billingDate.Month))
                {
                    //Calculated Usage charge > 0 and not already billed, may exist without access charge
                    Procedure procUsage = new Procedure();
                    procUsage.CodeNum        = procCodeUsage.CodeNum;
                    procUsage.DateEntryC     = DateTime.Today;
                    procUsage.PatNum         = pat.PatNum;
                    procUsage.ProcDate       = billingDate;
                    procUsage.DateTP         = billingDate;
                    procUsage.ProcFee        = smsBilling.MsgChargeTotalUSD;
                    procUsage.ProcStatus     = ProcStat.C;
                    procUsage.ProvNum        = PrefC.GetLong(PrefName.PracticeDefaultProv);
                    procUsage.MedicalCode    = procCodeUsage.MedicalCode;
                    procUsage.BaseUnits      = procCodeUsage.BaseUnits;
                    procUsage.DiagnosticCode = PrefC.GetString(PrefName.ICD9DefaultForNewProcs);
                    procUsage.PlaceService   = (PlaceOfService)PrefC.GetInt(PrefName.DefaultProcedurePlaceService);                //Default Proc Place of Service for the Practice is used.
                    procUsage.BillingNote    = "Texting Usage charge for " + smsBilling.DateUsage.ToString("MMMM yyyy") + ".";
                    Procedures.Insert(procUsage);
                    listProcsUsage.Add(procUsage);
                    retVal.Add(procUsage);
                }
            }
            return(retVal);
        }
예제 #7
0
        ///<summary>Gets the DataTable to display for treatment finder report</summary>
        ///<param name="listProviders">Include '0' in the list to get for all providers.</param>
        ///<param name="listBilling">Include '0' in the list to get for all billing types.</param>
        ///<param name="listClinicNums">Pass in an empty list to get for all clinics.</param>
        public static DataTable GetTreatmentFinderList(bool noIns, bool patsWithAppts, int monthStart, DateTime dateSince, double aboveAmount,
                                                       List <long> listProviders, List <long> listBilling, string code1, string code2, List <long> listClinicNums, bool isProcsGeneral)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetTable(MethodBase.GetCurrentMethod(), noIns, patsWithAppts, monthStart, dateSince, aboveAmount, listProviders, listBilling, code1, code2,
                                     listClinicNums, isProcsGeneral));
            }
#if DEBUG
            Stopwatch sw = Stopwatch.StartNew();
#endif
            DataTable table = new DataTable();
            DataRow   row;
            //columns that start with lowercase are altered for display rather than being raw data.
            table.Columns.Add("PatNum");
            table.Columns.Add("LName");
            table.Columns.Add("FName");
            table.Columns.Add("contactMethod");
            table.Columns.Add("address");
            table.Columns.Add("City");
            table.Columns.Add("State");
            table.Columns.Add("Zip");
            table.Columns.Add("annualMaxInd");
            table.Columns.Add("annualMaxFam");
            table.Columns.Add("amountUsedInd");
            table.Columns.Add("amountUsedFam");
            table.Columns.Add("amountPendingInd");
            table.Columns.Add("amountPendingFam");
            table.Columns.Add("amountRemainingInd");
            table.Columns.Add("amountRemainingFam");
            table.Columns.Add("treatmentPlan");
            table.Columns.Add("carrierName");
            table.Columns.Add("clinicAbbr");
            List <DataRow> rows             = new List <DataRow>();
            string         command          = "";
            string         joinAnnualMax    = "";
            string         joinCoverageInfo = "";
            string         joinIndInfo      = "";
            string         joinFamInfo      = "";
            string         subSelectPlanned = "";
            string         cmdFutureApt     = @" AND patient.PatNum NOT IN (
					SELECT PatNum FROM appointment WHERE AptStatus="                     + POut.Int((int)ApptStatus.Scheduled) + @"
					AND AptDateTime>="                     + DbHelper.Curdate() + ")";
            DateTime       renewDate        = BenefitLogic.ComputeRenewDate(DateTime.Now, monthStart);
            List <long>    listPatNums      = new List <long>();
            if ((!listProviders.Contains(0) || !listBilling.Contains(0) || listClinicNums.Count > 0))
            {
                string cmdPatients = "SELECT PatNum from patient ";
                string patWhere    = "";
                if (!listProviders.Contains(0))
                {
                    patWhere = " AND patient.PriProv IN (" + string.Join(",", listProviders) + ") ";
                }
                if (!listBilling.Contains(0))
                {
                    patWhere = " AND patient.BillingType IN (" + string.Join(",", listBilling) + ") ";
                }
                if (listClinicNums.Count > 0)
                {
                    patWhere += " AND patient.ClinicNum IN (" + string.Join(",", listClinicNums) + ") ";
                }
                if (!patsWithAppts)
                {
                    patWhere += cmdFutureApt;
                }
                cmdPatients += "WHERE TRUE " + patWhere;
                listPatNums  = Db.GetListLong(cmdPatients);
                if (listPatNums.Count == 0)
                {
                    return(table);
                }
            }
            joinCoverageInfo = @"
				SELECT patplan.PatPlanNum,claimproc.InsSubNum,
				SUM(CASE WHEN claimproc.Status="                 + POut.Int((int)ClaimProcStatus.NotReceived) + @" AND claimproc.InsPayAmt=0 
				THEN claimproc.InsPayEst ELSE 0 END) AmtPending,
				SUM(CASE WHEN claimproc.Status IN ("                 + POut.Int((int)ClaimProcStatus.Received) + ","
                               + POut.Int((int)ClaimProcStatus.Adjustment) + ","
                               + POut.Int((int)ClaimProcStatus.Supplemental) + @"
				) THEN claimproc.InsPayAmt ELSE 0 END) AmtUsed
				FROM claimproc
				INNER JOIN patient ON patient.PatNum=claimproc.PatNum
				LEFT JOIN patplan ON patplan.PatNum=claimproc.PatNum
					AND patplan.InsSubNum=claimproc.InsSubNum
				LEFT JOIN procedurelog pl ON pl.ProcNum=claimproc.ProcNum
				LEFT JOIN procedurecode pc ON pc.CodeNum=pl.CodeNum "                ;
            if (!isProcsGeneral)
            {
                joinCoverageInfo += @"
					LEFT JOIN (
							SELECT isub.InsSubNum,
							COALESCE(cp.FromCode,pc.ProcCode) AS FromCode,
							COALESCE(cp.ToCode,pc.ProcCode) AS ToCode
							FROM inssub isub
							INNER JOIN benefit b ON b.PlanNum=isub.PlanNum
								AND b.BenefitType="                                 + (int)InsBenefitType.Limitations + @"
								AND b.QuantityQualifier="                                 + (int)BenefitQuantity.None + @" 
								AND b.TimePeriod IN ("                                 + (int)BenefitTimePeriod.ServiceYear + "," + (int)BenefitTimePeriod.CalendarYear + @")
							LEFT JOIN covcat cc ON cc.CovCatNum=b.CovCatNum 
							LEFT JOIN covspan cp ON cp.CovCatNum=cc.CovCatNum
							LEFT JOIN procedurecode pc ON pc.CodeNum=b.CodeNum
							WHERE (cc.CovCatNum IS NOT NULL OR b.CodeNum!=0) 
							)ProcCheck ON ProcCheck.InsSubNum=claimproc.InsSubNum
							 AND pc.ProcCode BETWEEN ProcCheck.FromCode AND ProcCheck.ToCode "                            ;
            }
            joinCoverageInfo += "WHERE claimproc.Status IN (" + (int)ClaimProcStatus.NotReceived + ", " + (int)ClaimProcStatus.Received
                                + ", " + (int)ClaimProcStatus.Adjustment + ", " + (int)ClaimProcStatus.Supplemental + ") ";
            if (!isProcsGeneral)
            {
                joinCoverageInfo += "AND ProcCheck.InsSubNum IS NULL ";
            }
            joinCoverageInfo += "AND claimproc.ProcDate BETWEEN  " + POut.Date(renewDate) + @" AND " + POut.Date(renewDate.AddYears(1)) + @" ";
            if (listPatNums.Count > 0)
            {
                joinCoverageInfo += @"AND patient.PatNum IN (" + string.Join(",", listPatNums) + ") ";
            }
            else if (!patsWithAppts)
            {
                joinCoverageInfo += cmdFutureApt;
            }
            joinIndInfo      = joinCoverageInfo + " GROUP BY patplan.PatPlanNum ";
            joinFamInfo      = joinCoverageInfo + " GROUP BY claimproc.InsSubNum ";
            subSelectPlanned = @"
				(SELECT COALESCE(SUM(ProcFee),0) AmtPlanned
				FROM procedurelog "                ;
            if (code1 != "")
            {
                subSelectPlanned += "INNER JOIN procedurecode ON procedurecode.CodeNum=procedurelog.CodeNum ";
            }
            subSelectPlanned += "WHERE ProcStatus=" + (int)ProcStat.TP + " ";
            if (code1 != "")
            {
                subSelectPlanned += "AND procedurecode.ProcCode>='" + POut.String(code1) + "' "
                                    + " AND procedurecode.ProcCode<='" + POut.String(code2) + "' ";
            }
            if (dateSince.Year > 1880)
            {
                subSelectPlanned += "AND procedurelog.DateTP>=" + POut.DateT(dateSince) + " ";
            }
            subSelectPlanned += "AND PatNum=patient.PatNum ";
            subSelectPlanned += "GROUP BY PatNum) ";
            joinAnnualMax     = @"
				SELECT insplan.PlanNum, MAX(CASE WHEN CoverageLevel!="                 + POut.Int((int)BenefitCoverageLevel.Family) + @"
				THEN MonetaryAmt ELSE -1 END) AnnualMaxInd/*for oracle in case there's more than one*/, 
				MAX(CASE WHEN CoverageLevel="                 + POut.Int((int)BenefitCoverageLevel.Family) + @"
				THEN MonetaryAmt ELSE -1 END) AnnualMaxFam/*for oracle in case there's more than one*/
				FROM benefit
				INNER JOIN insplan ON insplan.PlanNum=benefit.PlanNum 
				INNER JOIN inssub ON inssub.PlanNum=benefit.PlanNum
				INNER JOIN patplan ON patplan.InsSubNum=inssub.InsSubNum
				INNER JOIN patient ON patient.PatNum=patplan.PatNum
				LEFT JOIN covcat ON benefit.CovCatNum=covcat.CovCatNum
				WHERE (covcat.EbenefitCat="                 + (int)EbenefitCategory.General + @" OR ISNULL(covcat.EbenefitCat))
				AND benefit.BenefitType="                 + (int)InsBenefitType.Limitations + @" 
				AND benefit.MonetaryAmt > 0
				AND benefit.QuantityQualifier="                 + (int)BenefitQuantity.None + " ";
            if (listPatNums.Count > 0)
            {
                joinAnnualMax += @"AND patient.PatNum IN (" + string.Join(",", listPatNums) + ") ";
            }
            else if (!patsWithAppts)
            {
                joinAnnualMax += cmdFutureApt;
            }
            joinAnnualMax += @"GROUP BY insplan.PlanNum";
            command        = @"SELECT patient.PatNum, patient.LName, patient.FName,
				patient.Email, patient.HmPhone, patient.PreferRecallMethod,
				patient.WirelessPhone, patient.WkPhone, patient.Address,
				patient.Address2, patient.City, patient.State, patient.Zip,
				patient.PriProv, patient.BillingType,
				COALESCE(annualMax.AnnualMaxInd,0) ""AnnualMaxInd"",
				COALESCE(annualMax.AnnualMaxFam,0) ""AnnualMaxFam"",
				IndividualInfo.AmtUsed ""AmountUsedInd"",
				FamilyInfo.AmtUsed ""AmountUsedFam"",
				IndividualInfo.AmtPending ""AmountPendingInd"",
				FamilyInfo.AmtPending ""AmountPendingFam"",
				COALESCE(annualMax.AnnualMaxInd,0)-COALESCE(IndividualInfo.AmtUsed,0)-COALESCE(IndividualInfo.AmtPending,0) AS ""$AmtRemainingInd"",
				COALESCE(annualMax.AnnualMaxFam,0)-COALESCE(FamilyInfo.AmtUsed,0)-COALESCE(FamilyInfo.AmtPending,0) AS ""$AmtRemainingFam"","                 +
                             subSelectPlanned + @"""$TreatmentPlan"", carrier.CarrierName,COALESCE(clinic.Abbr,'Unassigned') clinicAbbr
				FROM patient
				LEFT JOIN patplan ON patient.PatNum=patplan.PatNum
				LEFT JOIN inssub ON patplan.InsSubNum=inssub.InsSubNum
				LEFT JOIN insplan ON insplan.PlanNum=inssub.PlanNum
				LEFT JOIN carrier ON insplan.CarrierNum=carrier.CarrierNum
				LEFT JOIN ("
                             + joinIndInfo
                             + @")IndividualInfo ON IndividualInfo.PatPlanNum=patplan.PatPlanNum
				LEFT JOIN ("
                             + joinFamInfo
                             + @")FamilyInfo ON FamilyInfo.InsSubNum=inssub.InsSubNum
				LEFT JOIN ("
                             + joinAnnualMax
                             + @") annualMax ON annualMax.PlanNum=inssub.PlanNum
				AND (annualMax.AnnualMaxInd>0 OR annualMax.AnnualMaxFam>0)/*may not be necessary*/
				LEFT JOIN clinic ON clinic.ClinicNum=patient.ClinicNum
				WHERE TRUE 
				AND patient.PatStatus="                 + POut.Int((int)PatientStatus.Patient) + " ";
            if (!noIns)             //if we don't want patients without insurance
            {
                command += " AND patplan.Ordinal=1 AND insplan.MonthRenew=" + POut.Int(monthStart) + " ";
            }
            if (aboveAmount > 0)
            {
                command += " AND (annualMax.PlanNum IS NULL OR ((annualMax.AnnualMaxInd=-1 OR annualMax.AnnualMaxInd-COALESCE(IndividualInfo.AmtUsed,0) > "
                           + POut.Double(aboveAmount) + @")
					AND (annualMax.AnnualMaxFam=-1 OR annualMax.AnnualMaxFam-COALESCE(FamilyInfo.AmtUsed,0) > "                     + POut.Double(aboveAmount) + "))) ";
            }
            if (listPatNums.Count > 0)
            {
                command += " AND patient.PatNum IN (" + string.Join(",", listPatNums) + ") ";
            }
            else if (!patsWithAppts)
            {
                command += cmdFutureApt;
            }
            command += @"HAVING $TreatmentPlan > 0 ";
            command += @"ORDER BY $TreatmentPlan DESC";
            DataTable rawtable = Db.GetTable(command);
#if DEBUG
            sw.Stop();
            Console.WriteLine("Finishing retreiving query: {0}", sw.ElapsedMilliseconds);
            sw = Stopwatch.StartNew();
#endif
            ContactMethod contmeth;
            for (int i = 0; i < rawtable.Rows.Count; i++)
            {
                row           = table.NewRow();
                row["PatNum"] = PIn.Long(rawtable.Rows[i]["PatNum"].ToString());
                row["LName"]  = rawtable.Rows[i]["LName"].ToString();
                row["FName"]  = rawtable.Rows[i]["FName"].ToString();
                contmeth      = (ContactMethod)PIn.Long(rawtable.Rows[i]["PreferRecallMethod"].ToString());
                if (contmeth == ContactMethod.None)
                {
                    if (PrefC.GetBool(PrefName.RecallUseEmailIfHasEmailAddress))                     //if user only wants to use email if contact method is email
                    {
                        if (rawtable.Rows[i]["Email"].ToString() != "")
                        {
                            row["contactMethod"] = rawtable.Rows[i]["Email"].ToString();
                        }
                        else
                        {
                            row["contactMethod"] = Lans.g("FormRecallList", "Hm:") + rawtable.Rows[i]["HmPhone"].ToString();
                        }
                    }
                    else
                    {
                        row["contactMethod"] = Lans.g("FormRecallList", "Hm:") + rawtable.Rows[i]["HmPhone"].ToString();
                    }
                }
                else if (contmeth == ContactMethod.HmPhone)
                {
                    row["contactMethod"] = Lans.g("FormRecallList", "Hm:") + rawtable.Rows[i]["HmPhone"].ToString();
                }
                else if (contmeth == ContactMethod.WkPhone)
                {
                    row["contactMethod"] = Lans.g("FormRecallList", "Wk:") + rawtable.Rows[i]["WkPhone"].ToString();
                }
                else if (contmeth == ContactMethod.WirelessPh)
                {
                    row["contactMethod"] = Lans.g("FormRecallList", "Cell:") + rawtable.Rows[i]["WirelessPhone"].ToString();
                }
                else if (contmeth == ContactMethod.Email)
                {
                    row["contactMethod"] = rawtable.Rows[i]["Email"].ToString();
                }
                else if (contmeth == ContactMethod.Mail)
                {
                    row["contactMethod"] = Lans.g("FormRecallList", "Mail");
                }
                else if (contmeth == ContactMethod.DoNotCall || contmeth == ContactMethod.SeeNotes)
                {
                    row["contactMethod"] = Lans.g("enumContactMethod", contmeth.ToString());
                }
                row["address"] = rawtable.Rows[i]["Address"].ToString();
                if (rawtable.Rows[i]["Address2"].ToString() != "")
                {
                    row["address"] += "\r\n" + rawtable.Rows[i]["Address2"].ToString();
                }
                row["City"]               = rawtable.Rows[i]["City"].ToString();
                row["State"]              = rawtable.Rows[i]["State"].ToString();
                row["Zip"]                = rawtable.Rows[i]["Zip"].ToString();
                row["annualMaxInd"]       = (PIn.Double(rawtable.Rows[i]["AnnualMaxInd"].ToString())).ToString("N");
                row["annualMaxFam"]       = (PIn.Double(rawtable.Rows[i]["AnnualMaxFam"].ToString())).ToString("N");
                row["amountUsedInd"]      = (PIn.Double(rawtable.Rows[i]["AmountUsedInd"].ToString())).ToString("N");
                row["amountUsedFam"]      = (PIn.Double(rawtable.Rows[i]["AmountUsedFam"].ToString())).ToString("N");
                row["amountPendingInd"]   = (PIn.Double(rawtable.Rows[i]["AmountPendingInd"].ToString())).ToString("N");
                row["amountPendingFam"]   = (PIn.Double(rawtable.Rows[i]["AmountPendingFam"].ToString())).ToString("N");
                row["amountRemainingInd"] = (PIn.Double(rawtable.Rows[i]["$AmtRemainingInd"].ToString())).ToString("N");
                row["amountRemainingFam"] = (PIn.Double(rawtable.Rows[i]["$AmtRemainingFam"].ToString())).ToString("N");
                row["treatmentPlan"]      = (PIn.Double(rawtable.Rows[i]["$TreatmentPlan"].ToString())).ToString("N");
                row["carrierName"]        = rawtable.Rows[i]["CarrierName"].ToString();
                row["clinicAbbr"]         = rawtable.Rows[i]["clinicAbbr"].ToString();
                rows.Add(row);
            }
            for (int i = 0; i < rows.Count; i++)
            {
                table.Rows.Add(rows[i]);
            }
#if DEBUG
            sw.Stop();
            Console.WriteLine("Finished Filling query result: {0}", sw.ElapsedMilliseconds);
#endif
            return(table);
        }
예제 #8
0
 /// <summary>Runs repeating charges for the date passed in, usually today. Can't use 'out' variables because this runs over Middle Tier.</summary>
 public static RepeatChargeResult RunRepeatingCharges(DateTime dateRun)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         return(Meth.GetObject <RepeatChargeResult>(MethodBase.GetCurrentMethod(), dateRun));
     }
     Prefs.UpdateDateT(PrefName.RepeatingChargesBeginDateTime, dateRun);
     try {
         RepeatChargeResult  result = new RepeatChargeResult();
         List <RepeatCharge> listRepeatingCharges = RepeatCharges.Refresh(0).ToList();
         if (PrefC.IsODHQ)
         {
             //Remove all eService repeating charges.
             //EService charges have already been calculated and stored in EServiceBilling table. Add those here.
             List <string> listEServiceCodes = EServiceCodeLink.GetProcCodesForAll();
             listRepeatingCharges.RemoveAll(x => listEServiceCodes.Contains(x.ProcCode));
             result.ProceduresAddedCount += EServiceBillings.AddEServiceRepeatingChargesHelper(dateRun).Count;
         }
         //Must contain all procedures that affect the date range, safe to contain too many, bad to contain too few.
         List <Procedure> listExistingProcs = Procedures.GetCompletedForDateRange(dateRun.AddMonths(-3), dateRun.AddDays(1),
                                                                                  listRepeatingCharges.Select(x => x.ProcCode).Distinct().Select(x => ProcedureCodes.GetProcCode(x).CodeNum).ToList());
         DateTime startedUsingFKs = UpdateHistories.GetDateForVersion(new Version("16.1.0.0"));              //We started using FKs from procs to repeat charges in 16.1.
         foreach (RepeatCharge repeatCharge in listRepeatingCharges)
         {
             if (!repeatCharge.IsEnabled || (repeatCharge.DateStop.Year > 1880 && repeatCharge.DateStop.AddMonths(3) < dateRun))
             {
                 continue;                        //This repeating charge is too old to possibly create a new charge. Not precise but greatly reduces calls to DB.
                 //We will filter by more stringently on the DateStop later on.
             }
             Patient         pat = null;
             List <DateTime> listBillingDates;                   //This list will have 1 or 2 dates where a repeating charge might be added
             if (PrefC.GetBool(PrefName.BillingUseBillingCycleDay))
             {
                 pat = Patients.GetPat(repeatCharge.PatNum);
                 listBillingDates = GetBillingDatesHelper(repeatCharge.DateStart, repeatCharge.DateStop, dateRun, pat.BillingCycleDay);
             }
             else
             {
                 listBillingDates = GetBillingDatesHelper(repeatCharge.DateStart, repeatCharge.DateStop, dateRun);
             }
             long codeNum = ProcedureCodes.GetCodeNum(repeatCharge.ProcCode);
             //Remove billing dates if there is a procedure from this repeat charge in that month and year
             for (int i = listBillingDates.Count - 1; i >= 0; i--)             //iterate backwards to remove elements
             {
                 DateTime billingDate = listBillingDates[i];
                 for (int j = listExistingProcs.Count - 1; j >= 0; j--)                 //iterate backwards to remove elements
                 {
                     Procedure proc = listExistingProcs[j];
                     if ((proc.RepeatChargeNum == repeatCharge.RepeatChargeNum &&                       //Check the procedure's FK first
                          IsRepeatDateHelper(repeatCharge, billingDate, proc.ProcDate, pat))
                         //Use the old logic without matching FKs only if the procedure was added before updating to 16.1
                         //Match patnum, codenum, fee, year, and month (IsRepeatDateHelper uses special logic to determine correct month)
                         || ((proc.ProcDate < startedUsingFKs || startedUsingFKs.Year < 1880) &&
                             proc.PatNum == repeatCharge.PatNum &&
                             proc.CodeNum == codeNum &&
                             IsRepeatDateHelper(repeatCharge, billingDate, proc.ProcDate, pat) &&
                             proc.ProcFee.IsEqual(repeatCharge.ChargeAmt)))
                     {
                         //This is a match to an existing procedure.
                         listBillingDates.RemoveAt(i);         //Removing so that a procedure will not get added on this date.
                         listExistingProcs.RemoveAt(j);        //Removing so that another repeat charge of the same code, date, and amount will be added.
                         break;                                //Go to the next billing date
                     }
                 }
             }
             //If any billing dates have not been filtered out, add a repeating charge on those dates
             foreach (DateTime billingDate in listBillingDates)
             {
                 Procedure    procAdded       = AddRepeatingChargeHelper(repeatCharge, billingDate, dateRun);
                 List <Claim> listClaimsAdded = new List <Claim>();
                 if (repeatCharge.CreatesClaim && !ProcedureCodes.GetProcCode(repeatCharge.ProcCode).NoBillIns)
                 {
                     listClaimsAdded = AddClaimsHelper(repeatCharge, procAdded);
                 }
                 result.ProceduresAddedCount++;
                 result.ClaimsAddedCount += listClaimsAdded.Count;
             }
         }
         return(result);
     }
     finally {
         Prefs.UpdateString(PrefName.RepeatingChargesBeginDateTime, "");
     }
 }
예제 #9
0
        ///<summary>Returns 1 or 2 dates to be billed given the date range. Only filtering based on date range has been performed.</summary>
        private static List <DateTime> GetBillingDatesHelper(DateTime dateStart, DateTime dateStop, DateTime dateRun, int billingCycleDay = 0)
        {
            //No remoting role check; no call to db
            List <DateTime> retVal = new List <DateTime>();

            if (!PrefC.GetBool(PrefName.BillingUseBillingCycleDay))
            {
                billingCycleDay = dateStart.Day;
            }
            //Add dates on the first of each of the last three months
            retVal.Add(new DateTime(dateRun.AddMonths(-0).Year, dateRun.AddMonths(-0).Month, 1));          //current month -0
            retVal.Add(new DateTime(dateRun.AddMonths(-1).Year, dateRun.AddMonths(-1).Month, 1));          //current month -1
            retVal.Add(new DateTime(dateRun.AddMonths(-2).Year, dateRun.AddMonths(-2).Month, 1));          //current month -2
            //This loop fixes day of month, taking into account billing day past the end of the month.
            for (int i = 0; i < retVal.Count; i++)
            {
                int billingDay = Math.Min(retVal[i].AddMonths(1).AddDays(-1).Day, billingCycleDay);
                retVal[i] = new DateTime(retVal[i].Year, retVal[i].Month, billingDay);            //This re-adds the billing date with the proper day of month.
            }
            //Remove billing dates that are calulated before repeat charge started.
            retVal.RemoveAll(x => x < dateStart);
            //Remove billing dates older than one month and 20 days ago.
            retVal.RemoveAll(x => x < dateRun.AddMonths(-1).AddDays(-20));
            //Remove any dates after today
            retVal.RemoveAll(x => x > dateRun);
            //Remove billing dates past the end of the dateStop
            int monthAdd = 0;

            //To account for a partial month, add a charge after the repeat charge stop date in certain circumstances (for each of these scenarios, the
            //billingCycleDay will be 11):
            //--Scenario #1: The start day is before the stop day which is before the billing day. Ex: Start: 12/08, Stop 12/09
            //--Scenario #2: The start day is after the billing day which is after the stop day. Ex: Start: 11/25 Stop 12/01
            //--Scenario #3: The start day is before the stop day but before the billing day. Ex: Start: 11/25, Stop 11/27
            //--Scenario #4: The start day is the same as the stop day but after the billing day. Ex: Start: 10/13, Stop 11/13
            //--Scenario #5: The start day is the same as the stop day but before the billing day. Ex: Start: 11/10, Stop 12/10
            //Each of these repeat charges will post a charge on 12/11 even though it is after the stop date.
            if (PrefC.GetBool(PrefName.BillingUseBillingCycleDay))
            {
                if (dateStart.Day < billingCycleDay)
                {
                    if ((dateStop.Day < billingCycleDay && dateStart.Day < dateStop.Day) ||                //Scenario #1
                        dateStart.Day == dateStop.Day)                         //Scenario #5
                    {
                        monthAdd = 1;
                    }
                }
                else if (dateStart.Day > billingCycleDay)
                {
                    if (dateStart.Day <= dateStop.Day ||                //Scenario #3 and #4
                        dateStop.Day < billingCycleDay)                           //Scenario #2
                    {
                        monthAdd = 1;
                    }
                }
            }
            if (dateStop.Year > 1880)
            {
                retVal.RemoveAll(x => x > dateStop.AddMonths(monthAdd));
            }
            retVal.Sort();            //Order by oldest first
            return(retVal);
        }
예제 #10
0
파일: X270.cs 프로젝트: steev90/opendental
        public static string Validate(Clearinghouse clearhouse, Carrier carrier, Provider billProv, Clinic clinic, InsPlan insPlan, Patient subscriber, InsSub insSub)
        {
            StringBuilder strb = new StringBuilder();

            X12Validate.ISA(clearhouse, strb);
            X12Validate.Carrier(carrier, strb);
            if (carrier.ElectID.Length < 2)
            {
                if (strb.Length != 0)
                {
                    strb.Append(",");
                }
                strb.Append("Electronic ID");
            }
            if (billProv.SSN.Length != 9)
            {
                if (strb.Length != 0)
                {
                    strb.Append(",");
                }
                strb.Append("Prov TIN 9 digits");
            }
            X12Validate.BillProv(billProv, strb);
            if (PrefC.GetBool(PrefName.UseBillingAddressOnClaims))
            {
                X12Validate.BillingAddress(strb);
            }
            else if (clinic == null)
            {
                X12Validate.PracticeAddress(strb);
            }
            else
            {
                X12Validate.Clinic(clinic, strb);
            }
            if (insSub.SubscriberID.Length < 2)
            {
                if (strb.Length != 0)
                {
                    strb.Append(",");
                }
                strb.Append("SubscriberID");
            }
            if (subscriber.Birthdate.Year < 1880)
            {
                if (strb.Length != 0)
                {
                    strb.Append(",");
                }
                strb.Append("Subscriber Birthdate");
            }
            if (insPlan.GroupNum == "")
            {
                if (strb.Length != 0)
                {
                    strb.Append(",");
                }
                strb.Append("Group Number");
            }
            return(strb.ToString());
        }
예제 #11
0
        ///<summary>this code is similar to code in the phone tracking server.  But here, we frequently only change clockStatus and ColorBar by setting employeeNum=-1.  If employeeNum is not -1, then EmployeeName also gets set.  If employeeNum==0, then clears employee from that row.</summary>
        public static void SetPhoneStatus(ClockStatusEnum clockStatus, int extens, long employeeNum)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                Meth.GetVoid(MethodBase.GetCurrentMethod(), clockStatus, extens, employeeNum);
                return;
            }
            string command = @"SELECT phoneempdefault.EmployeeNum,phoneempdefault.IsTriageOperator,Description,phoneempdefault.EmpName,HasColor,phone.ClockStatus "
                             + "FROM phone "
                             + "LEFT JOIN phoneempdefault ON phone.Extension=phoneempdefault.PhoneExt "
                             + "WHERE phone.Extension=" + POut.Long(extens);
            DataTable tablePhone = Db.GetTable(command);

            if (tablePhone.Rows.Count == 0)
            {
                //It would be nice if we could create a phone row for this extension.
                return;
            }
            long     empNum           = PIn.Long(tablePhone.Rows[0]["EmployeeNum"].ToString());
            bool     isTriageOperator = PIn.Bool(tablePhone.Rows[0]["IsTriageOperator"].ToString());
            string   empName          = PIn.String(tablePhone.Rows[0]["EmpName"].ToString());
            string   clockStatusDb    = PIn.String(tablePhone.Rows[0]["ClockStatus"].ToString());
            Employee emp = Employees.GetEmp(employeeNum);

            if (emp != null)           //A new employee is going to take over this extension.
            {
                empName = emp.FName;
                empNum  = emp.EmployeeNum;
            }
            else if (employeeNum == 0)           //Clear the employee from that row.
            {
                empName = "";
                empNum  = 0;
            }
            //if these values are null because of missing phoneempdefault row, they will default to false
            //PhoneEmpStatusOverride statusOverride=(PhoneEmpStatusOverride)PIn.Int(tablePhone.Rows[0]["StatusOverride"].ToString());
            bool hasColor = PIn.Bool(tablePhone.Rows[0]["HasColor"].ToString());

            #region DateTimeStart
            //When a user shows up as a color on the phone panel, we want a timer to be constantly going to show how long they've been off the phone.
            string dateTimeStart = "";
            //It's possible that a new user has never clocked in before, therefore their clockStatus will be empty.  Simply set it to the status that they are trying to go to.
            if (clockStatusDb == "")
            {
                clockStatusDb = clockStatus.ToString();
            }
            if (clockStatus == ClockStatusEnum.Break ||
                clockStatus == ClockStatusEnum.Lunch)
            {
                //The user is going on Lunch or Break.  Start the DateTimeStart counter so we know how long they have been gone.
                dateTimeStart = "DateTimeStart=NOW(), ";
            }
            else if (clockStatus == ClockStatusEnum.Home)
            {
                //User is going Home.  Always clear the DateTimeStart column no matter what.
                dateTimeStart = "DateTimeStart='0001-01-01', ";
            }
            else              //User shows as a color on big phones and is not going to a status of Home, Lunch, or Break.  Example: Available, Training etc.
                              //Get the current clock status from the database.
            {
                ClockStatusEnum clockStatusCur = (ClockStatusEnum)Enum.Parse(typeof(ClockStatusEnum), clockStatusDb);
                //Start the clock if the user is going from a break status to any other non-break status.
                if (clockStatusCur == ClockStatusEnum.Home ||
                    clockStatusCur == ClockStatusEnum.Lunch ||
                    clockStatusCur == ClockStatusEnum.Break)
                {
                    //The user is clocking in from home, lunch, or break.  Start the timer up.
                    if (hasColor)                     //Only start up the timer when someone with color clocks in.
                    {
                        dateTimeStart = "DateTimeStart=NOW(), ";
                    }
                    else                       //Someone with no color then reset the timer. They are back from break, that's all we need to know.
                    {
                        dateTimeStart = "DateTimeStart='0001-01-01', ";
                    }
                }
            }
            #endregion
            //Update the phone row to reflect the new clock status of the user.
            string clockStatusNew = clockStatus.ToString();
            if (clockStatus == ClockStatusEnum.None)
            {
                clockStatusNew = "";
            }
            command = "UPDATE phone SET ClockStatus='" + POut.String(clockStatusNew) + "', "
                      + dateTimeStart
                      //+"ColorBar=-1, " //ColorBar is now determined at runtime by OD using Phones.GetPhoneColor.
                      + "EmployeeNum=" + POut.Long(empNum) + ", "
                      + "EmployeeName='" + POut.String(empName) + "' "
                      + "WHERE Extension=" + extens;
            Db.NonQ(command);

            if (PrefC.GetBool(PrefName.DockPhonePanelShow))             //hq only
            //Zero out any duplicate phone table rows for this employee.
            //This is possible if a user logged off and another employee logs into their computer. This would cause duplicate entries in the big phones window.
            {
                UpdatePhoneToEmpty(employeeNum, extens);
            }
        }
예제 #12
0
        ///<summary>If not using clinics then supply an empty list of clinicNums.  listClinicNums must have at least one item if using clinics.
        ///The table returned has the following columns in this order:
        ///PatientName, ProcDate, Descript, ProcFee, ProcNum, ClinicNum, PatNum, IsInProcess</summary>
        public static DataTable GetProcsNotBilled(List <long> listClinicNums, bool includeMedProcs, DateTime dateStart, DateTime dateEnd,
                                                  bool showProcsBeforeIns, bool hasMultiVisitProcs)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetTable(MethodBase.GetCurrentMethod(), listClinicNums, includeMedProcs, dateStart, dateEnd, showProcsBeforeIns, hasMultiVisitProcs));
            }
            string query = "SELECT ";

            if (PrefC.GetBool(PrefName.ReportsShowPatNum))
            {
                query += DbHelper.Concat("CAST(PatNum AS CHAR)", "'-'", "LName", "', '", "FName", "' '", "MiddleI");
            }
            else
            {
                query += DbHelper.Concat("LName", "', '", "FName", "' '", "MiddleI");
            }
            query += " AS 'PatientName',Stat,ProcDate,Descript,procFee,ProcNum,ClinicNum,PatNum "
                     + "FROM (SELECT patient.LName,patient.FName,patient.MiddleI,"
                     + "CASE WHEN procmultivisit.ProcMultiVisitNum IS NULL "
                     + "THEN '" + Lans.g("enumProcStat", ProcStat.C.ToString()) + "' ELSE '" + Lans.g("enumProcStat", ProcStatExt.InProcess) + "' END Stat,"
                     + "procedurelog.ProcDate,procedurecode.Descript,procedurelog.ProcFee*(procedurelog.UnitQty+procedurelog.BaseUnits) procFee,"
                     + "procedurelog.ProcNum,procedurelog.ClinicNum,patient.PatNum,insplan.PlanNum,MAX(insplan.IsMedical) isMedical,"
                     + "CASE WHEN MIN(insplan.IsMedical)=0 THEN 1 ELSE 0 END hasDental "
                     + "FROM patient "
                     + "INNER JOIN procedurelog ON procedurelog.PatNum = patient.PatNum "
                     + "AND procedurelog.ProcFee>0 "
                     + "AND procedurelog.procstatus=" + (int)ProcStat.C + " "
                     + "AND procedurelog.ProcDate	BETWEEN "+ POut.Date(dateStart) + " AND " + POut.Date(dateEnd) + " "
                     + "INNER JOIN procedurecode ON procedurecode.CodeNum = procedurelog.CodeNum ";
            if (CultureInfo.CurrentCulture.Name.EndsWith("CA"))
            {
                query += "AND procedurecode.IsCanadianLab=0 ";              //ignore Canadian labs
            }
            query += "LEFT JOIN claimproc ON claimproc.ProcNum = procedurelog.ProcNum "
                     + "LEFT JOIN insplan ON insplan.PlanNum = claimproc.PlanNum "
                     + "LEFT JOIN procmultivisit ON procmultivisit.ProcNum=procedurelog.ProcNum AND procmultivisit.IsInProcess=1 "
                     + "WHERE EXISTS(SELECT 1 FROM patplan WHERE patplan.PatNum=patient.PatNum) "
                     + "AND ((claimproc.NoBillIns=0 AND claimproc.Status=" + (int)ClaimProcStatus.Estimate + ") ";
            if (showProcsBeforeIns)
            {
                query += "OR claimproc.ClaimProcNum IS NULL ";
            }
            query += ") ";
            if (!hasMultiVisitProcs)
            {
                query += "AND (procmultivisit.ProcMultiVisitNum IS NULL) ";
            }
            if (listClinicNums.Count > 0)
            {
                query += "AND procedurelog.ClinicNum IN (" + String.Join(",", listClinicNums) + ") ";
            }
            query += "GROUP BY procedurelog.ProcNum "
                     + ") procnotbilled ";          //End of the main query which is treated like a sub query in order to process includeMedProcs and showProcsBeforeIns.
            //Having the "AND insplan.IsMedical=0" check within the WHERE clause of the main query causes slowness for large databases.
            //MySQL will freak out when looking for what index to use which causes full row scans to take place instead of simply filtering the results.
            //This problem can be resolved by putting the insplan.IsMedical=0 check into the LEFT JOIN clause and performing a corresponding NULL check.
            //However, the "OR insplan.PlanNum IS NULL" complicates the query enough to where it is easier to just put the old WHERE clause outside.
            //This sub query trick improved the following report for a large office from ~55 seconds to ~5 seconds.
            query += "WHERE (procnotbilled.hasDental=1 ";          //Always include procedures when the patient has dental insurance.
            if (includeMedProcs)
            {
                query += "OR procnotbilled.isMedical=1 ";
            }
            if (showProcsBeforeIns)
            {
                query += "OR procnotbilled.PlanNum IS NULL ";
            }
            query += ") ORDER BY LName,FName,PatNum,ProcDate";
            return(Db.GetTable(query));
        }
예제 #13
0
        public static ApptReminderRule CreateDefaultReminderRule(ApptReminderType ruleType, long clinicNum = 0, bool isBeforeAppointment = true)
        {
            ApptReminderRule rule = null;

            switch (ruleType)
            {
            case ApptReminderType.Reminder:
                rule = new ApptReminderRule()
                {
                    ClinicNum                  = clinicNum,         //works with practice too because _listClinics[0] is a spoofed "Practice/Defaults" clinic with ClinicNum=0
                    TypeCur                    = ApptReminderType.Reminder,
                    TSPrior                    = TimeSpan.FromHours(3),
                    TemplateSMS                = "Appointment Reminder: [NameF] is scheduled for [ApptTime] on [ApptDate] at [ClinicName]. If you have questions call [ClinicPhone].", //default message
                    TemplateEmail              = @"[NameF],

Your appointment is scheduled for [ApptTime] on [ApptDate] at [OfficeName]. If you have questions, call <a href=""tel:[OfficePhone]"">[OfficePhone]</a>.",
                    TemplateEmailSubject       = "Appointment Reminder",                                                                                                               //default subject
                    TemplateSMSAggShared       = "Appointment Reminder:\n[Appts]\nIf you have questions call [ClinicPhone].",
                    TemplateSMSAggPerAppt      = "[NameF] is scheduled for [ApptTime] on [ApptDate] at [ClinicName].",
                    TemplateEmailSubjAggShared = "Appointment Reminder",
                    TemplateEmailAggShared     = @"[Appts]
If you have questions, call <a href=""tel:[OfficePhone]"">[OfficePhone]</a>.",
                    TemplateEmailAggPerAppt    = "[NameF] is scheduled for [ApptTime] on [ApptDate] at [ClinicName].",
                    //SendOrder="0,1,2" //part of ctor
                };
                break;

            case ApptReminderType.ConfirmationFutureDay:
                rule = new ApptReminderRule()
                {
                    ClinicNum     = clinicNum,                      //works with practice too because _listClinics[0] is a spoofed "Practice/Defaults" clinic with ClinicNum=0
                    TypeCur       = ApptReminderType.ConfirmationFutureDay,
                    TSPrior       = TimeSpan.FromDays(7),
                    TemplateSMS   = "[NameF] is scheduled for [ApptTime] on [ApptDate] at [OfficeName]. Reply [ConfirmCode] to confirm or call [OfficePhone].",                        //default message
                    TemplateEmail = @"[NameF], 

Your appointment is scheduled for [ApptTime] on [ApptDate] at [OfficeName]. Click <a href=""[ConfirmURL]"">[ConfirmURL]</a> to confirm " +
                                    @"or call <a href=""tel:[OfficePhone]"">[OfficePhone]</a>.",
                    TemplateEmailSubject       = "Appointment Confirmation",                    //default subject
                    TemplateSMSAggShared       = "[Appts]\nReply [ConfirmCode] to confirm or call [OfficePhone].",
                    TemplateSMSAggPerAppt      = "[NameF] is scheduled for [ApptTime] on [ApptDate] at [ClinicName].",
                    TemplateEmailSubjAggShared = "Appointment Confirmation",
                    TemplateEmailAggShared     = @"[Appts]
Click <a href=""[ConfirmURL]"">[ConfirmURL]</a> to confirm or call <a href=""tel:[OfficePhone]"">[OfficePhone]</a>.",
                    TemplateEmailAggPerAppt    = "[NameF] is scheduled for [ApptTime] on [ApptDate] at [ClinicName].",
                    //SendOrder="0,1,2" //part of ctor
                    DoNotSendWithin      = TimeSpan.FromDays(1).Add(TimeSpan.FromHours(10)),
                    TemplateAutoReply    = "Thank you for confirming your appointment with [OfficeName].  We look forward to seeing you.",
                    TemplateAutoReplyAgg = "Thank you for confirming your appointments with [OfficeName].  We look forward to seeing you",
                    IsAutoReplyEnabled   = true,
                };
                break;

            case ApptReminderType.PatientPortalInvite:
                if (isBeforeAppointment)
                {
                    rule = new ApptReminderRule()
                    {
                        ClinicNum                  = clinicNum,
                        TypeCur                    = ApptReminderType.PatientPortalInvite,
                        TSPrior                    = TimeSpan.FromDays(7),
                        TemplateEmail              = @"[NameF],
			
In preparation for your upcoming dental appointment at [OfficeName], we invite you to log in to our Patient Portal. " + @"
There you can view your scheduled appointments, view your treatment plan, send a message to your provider, and view your account balance. " + @"
Visit our <a href=""[PatientPortalURL]"">Patient Portal</a> and use this temporary user name and password to log in:

User name: [UserName]
Password: [Password]

If you have any questions, please give us a call at <a href=""tel:[OfficePhone]"">[OfficePhone]</a>, and we would be happy to answer any of your questions.",
                        TemplateEmailSubject       = "Patient Portal Invitation",
                        TemplateEmailSubjAggShared = "Patient Portal Invitation",
                        TemplateEmailAggShared     = @"[NameF],
			
In preparation for your upcoming dental appointments at [OfficeName], we invite you to log in to our Patient Portal. " + @"
There you can view your scheduled appointments, view your treatment plan, send a message to your provider, and view your account balance. " + @"
Visit our <a href=""[PatientPortalURL]"">Patient Portal</a> and use these temporary user names and passwords to log in:

[Credentials]
If you have any questions, please give us a call at <a href=""tel:[OfficePhone]"">[OfficePhone]</a>, and we would be happy to answer any of your questions.",
                        TemplateEmailAggPerAppt    = @"[NameF]
User name: [UserName]
Password: [Password]
",
                        SendOrder                  = "2"              //Email only
                    };
                    break;
                }
                else                          //Same day
                {
                    rule = new ApptReminderRule()
                    {
                        ClinicNum                  = clinicNum,
                        TypeCur                    = ApptReminderType.PatientPortalInvite,
                        TSPrior                    = new TimeSpan(-1, 0, 0),         //Send 1 hour after the appointment
                        TemplateEmail              = @"[NameF],
			
Thank you for coming in to visit [OfficeName] today. As a follow up to your appointment, we invite you to log in to our Patient Portal. " + @"
There you can view your scheduled appointments, view your treatment plan, send a message to your provider, and view your account balance. " + @"
Visit <a href=""[PatientPortalURL]"">Patient Portal</a> and use this temporary user name and password to log in:

User name: [UserName]
Password: [Password]

If you have any questions, please give us a call at <a href=""tel:[OfficePhone]"">[OfficePhone]</a>, and we would be happy to answer any of your questions.",
                        TemplateEmailSubject       = "Patient Portal Invitation",
                        TemplateEmailSubjAggShared = "Patient Portal Invitation",
                        TemplateEmailAggShared     = @"[NameF],
			
Thank you for coming in to visit [OfficeName] today. As a follow up to your appointment, we invite you to log in to our Patient Portal. " + @"
There you can view your scheduled appointments, view your treatment plan, send a message to your provider, and view your account balance. " + @"
Visit <a href=""[PatientPortalURL]"">Patient Portal</a> and use these temporary user names and passwords to log in:

[Credentials]
If you have any questions, please give us a call at <a href=""tel:[OfficePhone]"">[OfficePhone]</a>, and we would be happy to answer any of your questions.",
                        TemplateEmailAggPerAppt    = @"[NameF]
User name: [UserName]
Password: [Password]
",
                        SendOrder                  = "2"              //Email only
                    };
                    break;
                }

            case ApptReminderType.ScheduleThankYou:
                rule = new ApptReminderRule()
                {
                    ClinicNum                  = clinicNum,                                                                          //works with practice too because _listClinics[0] is a spoofed "Practice/Defaults" clinic with ClinicNum=0
                    TypeCur                    = ApptReminderType.ScheduleThankYou,
                    TSPrior                    = new TimeSpan(-1, 0, 0),                                                             //default to send thank you 1 hour after creating appointment.
                    TemplateSMS                = "[NameF], thank you for scheduling with [OfficeName] on [ApptDate] at [ApptTime].", //default message
                    TemplateEmail              = @"[NameF],

Thank you for scheduling your appointment with [OfficeName] on [ApptDate] at [ApptTime]. If you have questions, call <a href=""tel:[OfficePhone]"">[OfficePhone]</a>.",
                    TemplateEmailSubject       = "Appointment Thank You",                                                            //default subject
                    TemplateSMSAggShared       = "Thank you for scheduling these appointments: [Appts]",
                    TemplateSMSAggPerAppt      = "[NameF] for [ApptTime] on [ApptDate] at [ClinicName]",
                    TemplateEmailSubjAggShared = "Appointment Thank You",
                    TemplateEmailAggShared     = @"Thank you for scheduling these appointments: [Appts]
If you have questions, call <a href=""tel:[OfficePhone]"">[OfficePhone]</a>.",
                    TemplateEmailAggPerAppt    = "[NameF] is scheduled for [ApptTime] on [ApptDate] at [ClinicName].",
                    //SendOrder="0,1,2" //part of ctor
                    DoNotSendWithin = new TimeSpan(2, 0, 0),                        //Do not send within 2 hours of appointment.AptDateTime.
                };
                break;
            }
            if (PrefC.GetBool(PrefName.EmailDisclaimerIsOn))
            {
                rule.TemplateEmail          += "\r\n\r\n\r\n[EmailDisclaimer]";
                rule.TemplateEmailAggShared += "\r\n\r\n\r\n[EmailDisclaimer]";
            }
            return(rule);
        }
예제 #14
0
        ///<summary>If not using clinics then supply an empty list of clinicNums.  listClinicNums must have at least one item if using clinics.</summary>
        public static DataTable GetProcsNotBilled(List <long> listClinicNums, bool includeMedProcs, DateTime dateStart, DateTime dateEnd, bool showProcsBeforeIns)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetTable(MethodBase.GetCurrentMethod(), listClinicNums, includeMedProcs, dateStart, dateEnd, showProcsBeforeIns));
            }
            string query = "SELECT ";

            if (PrefC.GetBool(PrefName.ReportsShowPatNum))
            {
                query += DbHelper.Concat("CAST(patient.PatNum AS CHAR)", "'-'", "patient.LName", "', '", "patient.FName", "' '", "patient.MiddleI");
            }
            else
            {
                query += DbHelper.Concat("patient.LName", "', '", "patient.FName", "' '", "patient.MiddleI");
            }
            query += " AS 'PatientName',procedurelog.ProcDate,procedurecode.Descript,procedurelog.ProcFee*(procedurelog.UnitQty+procedurelog.BaseUnits),"
                     + "procedurelog.ProcNum,procedurelog.ClinicNum "
                     + "FROM patient "
                     + "INNER JOIN procedurelog ON procedurelog.PatNum = patient.PatNum "
                     + "AND procedurelog.ProcFee>0 "
                     + "AND procedurelog.procstatus=" + (int)ProcStat.C + " "
                     + "AND procedurelog.ProcDate	BETWEEN "+ POut.Date(dateStart) + " AND " + POut.Date(dateEnd) + " "
                     + "INNER JOIN ( "
                     + "SELECT PatNum FROM patplan GROUP BY PatNum "
                     + " )HasIns ON HasIns.PatNum = patient.PatNum ";
            if (listClinicNums.Count > 0)
            {
                query += "AND procedurelog.ClinicNum IN (" + String.Join(",", listClinicNums) + ") ";
            }
            query += "INNER JOIN procedurecode ON procedurecode.CodeNum = procedurelog.CodeNum ";
            if (CultureInfo.CurrentCulture.Name.EndsWith("CA"))
            {
                query += "AND procedurecode.IsCanadianLab=0 ";              //ignore Canadian labs
            }
            query += "LEFT JOIN claimproc ON claimproc.ProcNum = procedurelog.ProcNum "
                     + "LEFT JOIN insplan ON insplan.PlanNum = claimproc.PlanNum ";
            if (showProcsBeforeIns)
            {
                query += "WHERE ((claimproc.NoBillIns=0 "
                         + "AND claimproc.Status=" + (int)ClaimProcStatus.Estimate + ") "
                         + "OR claimproc.ClaimProcNum IS NULL) ";
            }
            else
            {
                query += "WHERE claimproc.NoBillIns=0 "
                         + "AND claimproc.Status=" + (int)ClaimProcStatus.Estimate + " ";
            }
            if (!includeMedProcs)
            {
                query += "AND (insplan.IsMedical=0 ";
                if (showProcsBeforeIns)
                {
                    query += "OR insplan.PlanNum IS NULL ";
                }
                query += ") ";
            }
            query += "GROUP BY procedurelog.ProcNum "
                     + "ORDER BY patient.LName,patient.FName,patient.PatNum,procedurelog.ProcDate";
            return(Db.GetTable(query));
        }
예제 #15
0
 /// <summary>Runs repeating charges for the date passed in, usually today. Can't use 'out' variables because this runs over Middle Tier.</summary>
 public static RepeatChargeResult RunRepeatingCharges(DateTime dateRun)
 {
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         return(Meth.GetObject <RepeatChargeResult>(MethodBase.GetCurrentMethod(), dateRun));
     }
     Prefs.UpdateDateT(PrefName.RepeatingChargesBeginDateTime, dateRun);
     try {
         RepeatChargeResult  result = new RepeatChargeResult();
         List <RepeatCharge> listRepeatingCharges = RepeatCharges.Refresh(0).ToList();
         if (PrefC.IsODHQ)
         {
             //Remove all eService repeating charges.
             //EService charges have already been calculated and stored in EServiceBilling table. Add those here.
             List <string> listEServiceCodes = EServiceCodeLink.GetProcCodesForAll();
             listRepeatingCharges.RemoveAll(x => listEServiceCodes.Contains(x.ProcCode));
             result.ProceduresAddedCount += EServiceBillings.AddEServiceRepeatingChargesHelper(dateRun).Count;
         }
         DateTime startedUsingFKs = UpdateHistories.GetDateForVersion(new Version("16.1.0.0"));              //We started using FKs from procs to repeat charges in 16.1.
         foreach (RepeatCharge repeatCharge in listRepeatingCharges)
         {
             if (!repeatCharge.IsEnabled || (repeatCharge.DateStop.Year > 1880 && repeatCharge.DateStop.AddMonths(3) < dateRun))
             {
                 continue;                        //This repeating charge is too old to possibly create a new charge. Not precise but greatly reduces calls to DB.
                 //We will filter by more stringently on the DateStop later on.
             }
             long codeNum = ProcedureCodes.GetCodeNum(repeatCharge.ProcCode);
             //Must contain all procedures that affect the date range.
             DateTime         procRangeStart    = repeatCharge.DateStart.AddMonths(-1);       //Minus 1 month to catch accounts that have changed their billing date
             List <Procedure> listExistingProcs = Procedures.GetCompletedForDateRange(procRangeStart, dateRun,
                                                                                      new List <long> {
                 codeNum
             },
                                                                                      new List <long> {
                 repeatCharge.PatNum
             });
             for (int j = listExistingProcs.Count - 1; j >= 0; j--)               //iterate backwards to remove elements
             {
                 Procedure proc = listExistingProcs[j];
                 if (((proc.RepeatChargeNum == repeatCharge.RepeatChargeNum)                      //Check the procedure's FK first
                      //Use the old logic without matching FKs only if the procedure was added before updating to 16.1
                      //Match patnum, codenum, fee, year, and month (IsRepeatDateHelper uses special logic to determine correct month)
                      //Procedures with the ProcDate prior to the RepeatCharge.StartDate should not be considered as valid procedures
                      //associated to the current repeat charge.
                      || ((proc.ProcDate < startedUsingFKs || startedUsingFKs.Year < 1880) &&
                          proc.PatNum == repeatCharge.PatNum &&
                          proc.CodeNum == codeNum &&
                          proc.ProcFee.IsEqual(repeatCharge.ChargeAmt))) &&
                     (proc.ProcDate >= repeatCharge.DateStart ||                           //Consider procedures that fall on or after the repeat charge start date.
                      proc.ProcDate.Day != repeatCharge.DateStart.Day)) //Consider procs only when days are not the same. Catches procs that have changed their billing date
                 {
                     continue;                                          //This existing procedure needs to be counted for this repeat charge.
                 }
                 listExistingProcs.RemoveAt(j);                         //Removing so that another repeat charge of the same code, date, and amount will be added.
             }
             List <DateTime> listBillingDates;                          //This list will have 1 or 2 dates where a repeating charge might be added
             if (PrefC.GetBool(PrefName.BillingUseBillingCycleDay))
             {
                 listBillingDates = GetBillingDatesHelper(repeatCharge.DateStart, repeatCharge.DateStop, dateRun, listExistingProcs, repeatCharge,
                                                          Patients.GetPat(repeatCharge.PatNum).BillingCycleDay);
             }
             else
             {
                 listBillingDates = GetBillingDatesHelper(repeatCharge.DateStart, repeatCharge.DateStop, dateRun, listExistingProcs, repeatCharge);
             }
             listBillingDates.RemoveAll(x => x.Date > DateTime.Today.Date && !PrefC.GetBool(PrefName.FutureTransDatesAllowed));
             //If any billing dates have not been filtered out, add a repeating charge on those dates
             foreach (DateTime billingDate in listBillingDates)
             {
                 Procedure    procAdded       = AddRepeatingChargeHelper(repeatCharge, billingDate, dateRun);
                 List <Claim> listClaimsAdded = new List <Claim>();
                 if (repeatCharge.CreatesClaim && !ProcedureCodes.GetProcCode(repeatCharge.ProcCode).NoBillIns)
                 {
                     listClaimsAdded = AddClaimsHelper(repeatCharge, procAdded);
                 }
                 result.ProceduresAddedCount++;
                 result.ClaimsAddedCount += listClaimsAdded.Count;
             }
         }
         return(result);
     }
     finally {
         Prefs.UpdateString(PrefName.RepeatingChargesBeginDateTime, "");
     }
 }
예제 #16
0
        ///<summary>Called by local practice db to query HQ for EService setup info. Must remain very lite and versionless. Will be used by signup portal.
        ///If HasClinics==true then any SignupOut.EServices entries where ClinicNum==0 are invalid and should be ignored.
        ///If HasClinics==false then SignupOut.EServices should only pay attention items where ClinicNum==0.
        ///This list is kept completely unfiltered by ClinicNum for forward compatibility reasons.
        ///The ClinicNum 0 items are always used by the Signup portal to determine default signup preferences.
        ///However, these items are only used for validation and billing in the case where HasClinics==true.</summary>
        public static EServiceSetup.SignupOut GetEServiceSetupFull(SignupPortalPermission permission, bool isSwitchClinicPref = false)
        {
            //Clinics will be stored in this order at HQ to allow signup portal to display them in proper order.
            List <Clinic> clinics = Clinics.GetDeepCopy().OrderBy(x => x.ItemOrder).ToList();

            if (PrefC.GetBool(PrefName.ClinicListIsAlphabetical))
            {
                clinics = clinics.OrderBy(x => x.Abbr).ToList();
            }
#if DEBUG
            bool isMockChanged = false;
            if (WebServiceMainHQProxy.MockWebServiceMainHQ == null)
            {
                WebServiceMainHQProxy.MockWebServiceMainHQ = new WebServiceMainHQMockDemo();
                isMockChanged = true;
            }
#endif
            EServiceSetup.SignupOut signupOut = ReadXml <EServiceSetup.SignupOut>
                                                (
                WebSerializer.DeserializePrimitiveOrThrow <string>
                (
                    GetWebServiceMainHQInstance().EServiceSetup
                    (
                        CreateWebServiceHQPayload
                        (
                            WriteXml(new EServiceSetup.SignupIn()
            {
                MethodNameInt = (int)EServiceSetup.SetupMethod.GetSignupOutFull,
                HasClinics    = PrefC.HasClinicsEnabled,
                //ClinicNum is not currently used as input.
                ClinicNum                 = 0,
                ProgramVersionStr         = PrefC.GetString(PrefName.ProgramVersion),
                SignupPortalPermissionInt = (int)permission,
                Clinics = clinics
                          .Select(x => new EServiceSetup.SignupIn.ClinicLiteIn()
                {
                    ClinicNum   = x.ClinicNum,
                    ClinicTitle = x.Abbr,
                    IsHidden    = x.IsHidden,
                }).ToList(),
                IsSwitchClinicPref = isSwitchClinicPref,
            }), eServiceCode.Undefined
                        )
                    )
                )
                                                );
#if DEBUG
            if (isMockChanged)
            {
                WebServiceMainHQProxy.MockWebServiceMainHQ = null;
            }
#endif
            //We just got the latest sync info from HQ so update the local db to reflect what HQ says is true.
            #region Reconcile Phones
            List <SmsPhone> listPhonesHQ = signupOut.Phones.Select(x => new SmsPhone()
            {
                ClinicNum        = x.ClinicNum,
                CountryCode      = x.CountryCode,
                DateTimeActive   = x.DateTimeActive,
                DateTimeInactive = x.DateTimeInactive,
                InactiveCode     = x.InactiveCode,
                PhoneNumber      = x.PhoneNumber,
            }).ToList();
            SmsPhones.UpdateOrInsertFromList(listPhonesHQ);
            #endregion
            #region Reconcile practice and clinics
            List <EServiceSetup.SignupOut.SignupOutSms> smsSignups = GetSignups <EServiceSetup.SignupOut.SignupOutSms>(signupOut, eServiceCode.IntegratedTexting);
            bool isCacheInvalid = false;
            bool isSmsEnabled   = false;
            if (PrefC.HasClinicsEnabled)              //Clinics are ON so loop through all clinics and reconcile with HQ.
            {
                List <Clinic> listClinicsAll = Clinics.GetDeepCopy();
                foreach (Clinic clinicDb in listClinicsAll)
                {
                    WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms clinicSignup =
                        smsSignups.FirstOrDefault(x => x.ClinicNum == clinicDb.ClinicNum) ?? new WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms()
                    {
                        //Not found so turn it off.
                        SmsContractDate = DateTime.MinValue,
                        MonthlySmsLimit = 0,
                        IsEnabled       = false,
                    };
                    Clinic clinicNew = clinicDb.Copy();
                    clinicNew.SmsContractDate = clinicSignup.SmsContractDate;
                    clinicNew.SmsMonthlyLimit = clinicSignup.MonthlySmsLimit;
                    isCacheInvalid           |= Clinics.Update(clinicNew, clinicDb);
                    isSmsEnabled |= clinicSignup.IsEnabled;
                }
            }
            else               //Clinics are off so ClinicNum 0 is the practice clinic.
            {
                WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms practiceSignup =
                    smsSignups.FirstOrDefault(x => x.ClinicNum == 0) ?? new WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutSms()
                {
                    //Not found so turn it off.
                    SmsContractDate = DateTime.MinValue,
                    MonthlySmsLimit = 0,
                    IsEnabled       = false,
                };
                isCacheInvalid
                    |= Prefs.UpdateDateT(PrefName.SmsContractDate, practiceSignup.SmsContractDate)
                       | Prefs.UpdateLong(PrefName.TextingDefaultClinicNum, 0)
                       | Prefs.UpdateDouble(PrefName.SmsMonthlyLimit, practiceSignup.MonthlySmsLimit);
                isSmsEnabled |= practiceSignup.IsEnabled;
            }
            #endregion
            #region Reconcile CallFire
            //Turn off CallFire if SMS has been activated.
            //This only happens the first time SMS is turned on and CallFire is still activated.
            if (isSmsEnabled && Programs.IsEnabled(ProgramName.CallFire))
            {
                Program callfire = Programs.GetCur(ProgramName.CallFire);
                if (callfire != null)
                {
                    callfire.Enabled = false;
                    Programs.Update(callfire);
                    Signalods.Insert(new Signalod()
                    {
                        IType = InvalidType.Providers
                    });
                    signupOut.Prompts.Add("Call Fire has been disabled. Cancel Integrated Texting and access program properties to retain Call Fire.");
                }
            }
            #endregion
            #region eConfirmations
            if (Prefs.UpdateBool(PrefName.ApptConfirmAutoSignedUp, IsEServiceActive(signupOut, eServiceCode.ConfirmationRequest)))
            {
                //HQ does not match the local pref. Make it match with HQ.
                isCacheInvalid = true;
                SecurityLogs.MakeLogEntry(Permissions.Setup, 0, "Automated appointment eConfirmations automatically changed by HQ.  Local pref set to "
                                          + IsEServiceActive(signupOut, eServiceCode.ConfirmationRequest).ToString() + ".");
            }
            #endregion
            if (isCacheInvalid)              //Something changed in the db. Alert other workstations and change this workstation immediately.
            {
                Signalods.Insert(new Signalod()
                {
                    IType = InvalidType.Prefs
                });
                Prefs.RefreshCache();
                Signalods.Insert(new Signalod()
                {
                    IType = InvalidType.Providers
                });
                Providers.RefreshCache();
                Clinics.RefreshCache();
            }
            return(signupOut);
        }
예제 #17
0
        private static Procedure AddRepeatingChargeHelper(RepeatCharge repeatCharge, DateTime billingDate, DateTime dateNow)
        {
            //No remoting role check; no call to db
            Procedure     procedure = new Procedure();
            ProcedureCode procCode  = ProcedureCodes.GetProcCode(repeatCharge.ProcCode);
            Patient       pat       = Patients.GetPat(repeatCharge.PatNum);

            procedure.CodeNum    = procCode.CodeNum;
            procedure.ClinicNum  = pat.ClinicNum;
            procedure.DateEntryC = dateNow;
            procedure.PatNum     = repeatCharge.PatNum;
            procedure.ProcDate   = billingDate;
            procedure.DateTP     = billingDate;
            procedure.ProcFee    = repeatCharge.ChargeAmt;
            procedure.ProcStatus = ProcStat.C;
            if (procCode.ProvNumDefault == 0)
            {
                procedure.ProvNum = pat.PriProv;
            }
            else
            {
                procedure.ProvNum = procCode.ProvNumDefault;
            }
            procedure.MedicalCode     = ProcedureCodes.GetProcCode(procedure.CodeNum).MedicalCode;
            procedure.BaseUnits       = ProcedureCodes.GetProcCode(procedure.CodeNum).BaseUnits;
            procedure.DiagnosticCode  = PrefC.GetString(PrefName.ICD9DefaultForNewProcs);
            procedure.RepeatChargeNum = repeatCharge.RepeatChargeNum;
            procedure.PlaceService    = (PlaceOfService)PrefC.GetInt(PrefName.DefaultProcedurePlaceService);       //Default Proc Place of Service for the Practice is used.
            //Check if the repeating charge has been flagged to copy it's note into the billing note of the procedure.
            if (repeatCharge.CopyNoteToProc)
            {
                procedure.BillingNote = repeatCharge.Note;
                if (repeatCharge.ErxAccountId != "")
                {
                    procedure.BillingNote =
                        "NPI=" + repeatCharge.Npi + "  " + "ErxAccountId=" + repeatCharge.ErxAccountId;
                    if (!string.IsNullOrEmpty(repeatCharge.ProviderName))                     //Provider name would be empty if older and no longer updated from eRx.
                    {
                        procedure.BillingNote += "\r\nProviderName=" + repeatCharge.ProviderName;
                    }
                    if (!string.IsNullOrEmpty(repeatCharge.Note))
                    {
                        procedure.BillingNote += "\r\n" + repeatCharge.Note;
                    }
                }
            }
            if (!PrefC.GetBool(PrefName.EasyHidePublicHealth))
            {
                procedure.SiteNum = pat.SiteNum;
            }
            Procedures.Insert(procedure);             //no recall synch needed because dental offices don't use this feature
            //Using Prepayments for this Procedure
            if (repeatCharge.UsePrepay)
            {
                //NOTE: ProvNum=0 on these splits, so I'm pretty sure they aren't allocated to anything.
                List <PaySplit> prePaySplits             = PaySplits.GetPrepayForFam(Patients.GetFamily(repeatCharge.PatNum));
                List <PaySplit> paySplitsForPrePaySplits = PaySplits.GetSplitsForPrepay(prePaySplits);
                Payment         payCur = new Payment();
                payCur.ClinicNum = procedure.ClinicNum;
                payCur.DateEntry = billingDate;
                payCur.IsSplit   = true;
                payCur.PatNum    = repeatCharge.PatNum;
                payCur.PayDate   = billingDate;
                payCur.PayType   = 0;           //Income transfer (will always be income transfer)
                payCur.PayAmt    = 0;           //Income transfer payment
                payCur.PayNum    = Payments.Insert(payCur);
                decimal payAmt   = 0;
                string  noteText = "";
                foreach (PaySplit prePaySplit in prePaySplits)
                {
                    prePaySplit.SplitAmt += paySplitsForPrePaySplits.Where(x => x.FSplitNum == prePaySplit.SplitNum).Sum(y => y.SplitAmt);                //Reduce prepay split amount.
                    PaySplit split  = new PaySplit();
                    PaySplit split2 = new PaySplit();
                    if (prePaySplit.SplitAmt > procedure.ProcFee - (double)payAmt)
                    {
                        //Split amount is more than the remainder of the procfee requires, use partial from split
                        split.SplitAmt  = procedure.ProcFee - (double)payAmt;
                        split2.SplitAmt = 0 - (procedure.ProcFee - (double)payAmt);
                        payAmt          = (decimal)procedure.ProcFee;
                    }
                    else
                    {
                        //Split amount is less than or equal to the remainder of the procfee
                        split.SplitAmt  = prePaySplit.SplitAmt;
                        split2.SplitAmt = 0 - prePaySplit.SplitAmt;
                        payAmt         += (decimal)prePaySplit.SplitAmt;
                    }
                    if (split.SplitAmt == 0)
                    {
                        continue;                        //Don't make splits for 0 amount.
                    }
                    //Positive split, attached to proc and for proc's prov and clinic
                    split.DateEntry = billingDate;
                    split.DatePay   = billingDate;
                    split.PatNum    = procedure.PatNum;
                    split.PayNum    = payCur.PayNum;
                    split.ProcNum   = procedure.ProcNum;
                    split.ProvNum   = procedure.ProvNum;
                    split.ClinicNum = procedure.ClinicNum;
                    if (noteText != "")
                    {
                        noteText += ", ";
                    }
                    noteText += split.SplitAmt.ToString("c");
                    PaySplits.Insert(split);
                    //Negative split, attached to prepay's prov and clinic, but not proc
                    split2.DateEntry = billingDate;
                    split2.DatePay   = billingDate;
                    split2.PatNum    = procedure.PatNum;
                    split2.PayNum    = payCur.PayNum;
                    split2.FSplitNum = prePaySplit.SplitNum;
                    split2.ProvNum   = prePaySplit.ProvNum;
                    split2.ClinicNum = prePaySplit.ClinicNum;
                    PaySplits.Insert(split2);
                    if (payAmt >= (decimal)procedure.ProcFee)
                    {
                        //Break out of loop
                        break;
                    }
                }
                payCur.PayNote = "Allocated " + noteText + " prepayments to repeating charge.";
                Payments.Update(payCur, false);
            }
            return(procedure);
        }
예제 #18
0
        ///<summary>Only called from Chart for now.  No validation is performed here.  Validate before calling.  There are many validtion checks, including the NPI must be exactly 10 digits.</summary>
        public static string BuildClickThroughXml(Provider prov, Employee emp, Patient pat)
        {
            NCScript ncScript = new NCScript();

            ncScript.Credentials                = new CredentialsType();
            ncScript.Credentials.partnerName    = NewCropPartnerName;
            ncScript.Credentials.name           = NewCropAccountName;
            ncScript.Credentials.password       = NewCropAccountPasssword;
            ncScript.Credentials.productName    = NewCropProductName;
            ncScript.Credentials.productVersion = NewCropProductVersion;
            ncScript.UserRole = new UserRoleType();
            if (emp == null)
            {
                ncScript.UserRole.user = UserType.LicensedPrescriber;
                ncScript.UserRole.role = RoleType.doctor;
            }
            else
            {
                ncScript.UserRole.user = UserType.Staff;
                ncScript.UserRole.role = RoleType.nurse;
            }
            ncScript.Destination = new DestinationType();
            ncScript.Destination.requestedPage = RequestedPageType.compose;                                //This is the tab that the user will want 90% of the time.
            string practiceTitle    = PrefC.GetString(PrefName.PracticeTitle);                             //May be blank.
            string practicePhone    = PrefC.GetString(PrefName.PracticePhone);                             //Validated to be 10 digits within the chart.
            string practiceFax      = PrefC.GetString(PrefName.PracticeFax);                               //Validated to be 10 digits within the chart.
            string practiceAddress  = PrefC.GetString(PrefName.PracticeAddress);                           //Validated to exist in chart.
            string practiceAddress2 = PrefC.GetString(PrefName.PracticeAddress2);                          //May be blank.
            string practiceCity     = PrefC.GetString(PrefName.PracticeCity);                              //Validated to exist in chart.
            string practiceState    = PrefC.GetString(PrefName.PracticeST);                                //Validated to be a US state code in chart.
            string practiceZip      = Regex.Replace(PrefC.GetString(PrefName.PracticeZip), "[^0-9]*", ""); //Zip with all non-numeric characters removed. Validated to be 9 digits in chart.
            string practiceZip4     = practiceZip.Substring(5);                                            //Last 4 digits of zip.

            practiceZip = practiceZip.Substring(0, 5);                                                     //First 5 digits of zip.
            string country = "US";                                                                         //Always United States for now.

            //if(CultureInfo.CurrentCulture.Name.Length>=2) {
            //  country=CultureInfo.CurrentCulture.Name.Substring(CultureInfo.CurrentCulture.Name.Length-2);
            //}
            ncScript.Account = new AccountTypeRx();
            //Each LicensedPrescriberID must be unique within an account. Since we send ProvNum for LicensedPrescriberID, each OD database must have a unique AccountID.
            ncScript.Account.ID                        = PrefC.GetString(PrefName.NewCropAccountId); //Customer account number then a dash then a random alpha-numeric string of 3 characters, followed by 2 digits.
            ncScript.Account.accountName               = practiceTitle;                              //May be blank.
            ncScript.Account.siteID                    = "1";                                        //Always send 1.  For each AccountID/SiteID pair, a separate database will be created in NewCrop.
            ncScript.Account.AccountAddress            = new AddressType();
            ncScript.Account.AccountAddress.address1   = practiceAddress;                            //Validated to exist in chart.
            ncScript.Account.AccountAddress.address2   = practiceAddress2;                           //May be blank.
            ncScript.Account.AccountAddress.city       = practiceCity;                               //Validated to exist in chart.
            ncScript.Account.AccountAddress.state      = practiceState;                              //Validated to be a US state code in chart.
            ncScript.Account.AccountAddress.zip        = practiceZip;                                //Validated to be 9 digits in chart. First 5 digits go in this field.
            ncScript.Account.AccountAddress.zip4       = practiceZip4;                               //Validated to be 9 digits in chart. Last 4 digits go in this field.
            ncScript.Account.AccountAddress.country    = country;                                    //Validated above.
            ncScript.Account.accountPrimaryPhoneNumber = practicePhone;                              //Validated to be 10 digits within the chart.
            ncScript.Account.accountPrimaryFaxNumber   = practiceFax;                                //Validated to be 10 digits within the chart.
            ncScript.Location = new LocationType();
            if (PrefC.GetBool(PrefName.EasyNoClinics) || pat.ClinicNum == 0)                         //No clinics.
            {
                ncScript.Location.ID                       = "0";                                    //Always 0, since clinicnums must be >= 1, will never overlap with a clinic if the office turns clinics on after first use.
                ncScript.Location.locationName             = practiceTitle;                          //May be blank.
                ncScript.Location.LocationAddress          = new AddressType();
                ncScript.Location.LocationAddress.address1 = practiceAddress;                        //Validated to exist in chart.
                ncScript.Location.LocationAddress.address2 = practiceAddress2;                       //May be blank.
                ncScript.Location.LocationAddress.city     = practiceCity;                           //Validated to exist in chart.
                ncScript.Location.LocationAddress.state    = practiceState;                          //Validated to be a US state code in chart.
                ncScript.Location.LocationAddress.zip      = practiceZip;                            //Validated to be 9 digits in chart. First 5 digits go in this field.
                ncScript.Location.LocationAddress.zip4     = practiceZip4;                           //Validated to be 9 digits in chart. Last 4 digits go in this field.
                ncScript.Location.LocationAddress.country  = country;                                //Validated above.
                ncScript.Location.primaryPhoneNumber       = practicePhone;                          //Validated to be 10 digits within the chart.
                ncScript.Location.primaryFaxNumber         = practiceFax;                            //Validated to be 10 digits within the chart.
                ncScript.Location.pharmacyContactNumber    = practicePhone;                          //Validated to be 10 digits within the chart.
            }
            else                                                                                     //Using clinics.
            {
                Clinic clinic = Clinics.GetClinic(pat.ClinicNum);
                ncScript.Location.ID                       = clinic.ClinicNum.ToString(); //A positive integer.
                ncScript.Location.locationName             = clinic.Description;          //May be blank.
                ncScript.Location.LocationAddress          = new AddressType();
                ncScript.Location.LocationAddress.address1 = clinic.Address;              //Validated to exist in chart.
                ncScript.Location.LocationAddress.address2 = clinic.Address2;             //May be blank.
                ncScript.Location.LocationAddress.city     = clinic.City;                 //Validated to exist in chart.
                ncScript.Location.LocationAddress.state    = clinic.State;                //Validated to be a US state code in chart.
                string clinicZip  = Regex.Replace(clinic.Zip, "[^0-9]*", "");             //Zip with all non-numeric characters removed. Validated to be 9 digits in chart.
                string clinicZip4 = clinicZip.Substring(5);                               //Last 4 digits of zip.
                clinicZip = clinicZip.Substring(0, 5);                                    //First 5 digits of zip.
                ncScript.Location.LocationAddress.zip     = clinicZip;                    //Validated to be 9 digits in chart. First 5 digits go in this field.
                ncScript.Location.LocationAddress.zip4    = clinicZip4;                   //Validated to be 9 digits in chart. Last 4 digits go in this field.
                ncScript.Location.LocationAddress.country = country;                      //Validated above.
                ncScript.Location.primaryPhoneNumber      = clinic.Phone;                 //Validated to be 10 digits within the chart.
                ncScript.Location.primaryFaxNumber        = clinic.Fax;                   //Validated to be 10 digits within the chart.
                ncScript.Location.pharmacyContactNumber   = clinic.Phone;                 //Validated to be 10 digits within the chart.
            }
            ncScript.LicensedPrescriber = new LicensedPrescriberType();
            //Each unique provider ID sent to NewCrop will cause a billing charge.
            //Some customer databases have provider duplicates, because they have one provider record per clinic with matching NPIs.
            //We send NPI as the ID to prevent extra NewCrop charges.
            //Conversation with NewCrop:
            //Question: If one of our customers clicks through to NewCrop with 2 different LicensedPrescriber.ID values,
            //          but with the same provider name and NPI, will Open Dental be billed twice or just one time for the NPI used?
            //Answer:   "They would be billed twice. The IDs you send us should always be maintained and unique.
            //          Users are always identified by LicensedPrescriber ID, since their name or credentials could potentially change."
            ncScript.LicensedPrescriber.ID = prov.NationalProvID;
            //UPIN is obsolete
            ncScript.LicensedPrescriber.LicensedPrescriberName        = new PersonNameType();
            ncScript.LicensedPrescriber.LicensedPrescriberName.last   = prov.LName.Trim();    //Cannot be blank.
            ncScript.LicensedPrescriber.LicensedPrescriberName.first  = prov.FName.Trim();    //Cannot be blank.
            ncScript.LicensedPrescriber.LicensedPrescriberName.middle = prov.MI;              //May be blank.
            ncScript.LicensedPrescriber.LicensedPrescriberName.suffix = PersonNameSuffix.DDS; //There is no blank or none option, so we have to pick a default value. DDS=0, so would be default anyway.
            string[] suffixes = prov.Suffix.ToUpper().Split(' ', '.');
            for (int i = 0; i < suffixes.Length; i++)
            {
                if (suffixes[i] == "I")
                {
                    ncScript.LicensedPrescriber.LicensedPrescriberName.suffix = PersonNameSuffix.I;
                    break;
                }
                else if (suffixes[i] == "II")
                {
                    ncScript.LicensedPrescriber.LicensedPrescriberName.suffix = PersonNameSuffix.II;
                    break;
                }
                else if (suffixes[i] == "III")
                {
                    ncScript.LicensedPrescriber.LicensedPrescriberName.suffix = PersonNameSuffix.III;
                    break;
                }
                else if (suffixes[i] == "JR")
                {
                    ncScript.LicensedPrescriber.LicensedPrescriberName.suffix = PersonNameSuffix.Jr;
                    break;
                }
                else if (suffixes[i] == "SR")
                {
                    ncScript.LicensedPrescriber.LicensedPrescriberName.suffix = PersonNameSuffix.Sr;
                    break;
                }
            }
            if (prov.DEANum.ToLower() == "none")
            {
                ncScript.LicensedPrescriber.dea = "NONE";
            }
            else
            {
                ncScript.LicensedPrescriber.dea = prov.DEANum;
            }
            ncScript.LicensedPrescriber.licenseState  = prov.StateWhereLicensed; //Validated to be a US state code in the chart.
            ncScript.LicensedPrescriber.licenseNumber = prov.StateLicense;       //Validated to exist in chart.
            ncScript.LicensedPrescriber.npi           = prov.NationalProvID;     //Validated to be 10 digits in chart.
            //ncScript.LicensedPrescriber.freeformCredentials=;//This is where DDS and DMD should go, but we don't support this yet. Probably not necessary anyway.
            if (emp != null)
            {
                ncScript.Staff                  = new StaffType();
                ncScript.Staff.ID               = "emp" + emp.EmployeeNum.ToString(); //A positive integer. Returned in the ExternalUserID field when retreiving prescriptions from NewCrop. Also, provider ID is returned in the same field if a provider created the prescription, so that we can create a distintion between employee IDs and provider IDs.
                ncScript.Staff.StaffName        = new PersonNameType();
                ncScript.Staff.StaffName.first  = emp.FName;                          //First name or last name will not be blank. Validated in Chart.
                ncScript.Staff.StaffName.last   = emp.LName;                          //First name or last name will not be blank. Validated in Chart.
                ncScript.Staff.StaffName.middle = emp.MiddleI;                        //May be blank.
            }
            ncScript.Patient                     = new PatientType();
            ncScript.Patient.ID                  = pat.PatNum.ToString(); //A positive integer.
            ncScript.Patient.PatientName         = new PersonNameType();
            ncScript.Patient.PatientName.last    = pat.LName;             //Validated to exist in Patient Edit window.
            ncScript.Patient.PatientName.first   = pat.FName;             //May be blank.
            ncScript.Patient.PatientName.middle  = pat.MiddleI;           //May be blank.
            ncScript.Patient.medicalRecordNumber = pat.PatNum.ToString(); //A positive integer.
            //NewCrop specifically requested that we do not send SSN.
            //ncScript.Patient.socialSecurityNumber=Regex.Replace(pat.SSN,"[^0-9]*","");//Removes all non-numerical characters.
            ncScript.Patient.PatientAddress               = new AddressOptionalType();
            ncScript.Patient.PatientAddress.address1      = pat.Address;                        //May be blank.
            ncScript.Patient.PatientAddress.address2      = pat.Address2;                       //May be blank.
            ncScript.Patient.PatientAddress.city          = pat.City;                           //May be blank.
            ncScript.Patient.PatientAddress.state         = pat.State;                          //May be blank. Validated in chart to be blank or to be a valid US state code.
            ncScript.Patient.PatientAddress.zip           = pat.Zip;                            //May be blank.
            ncScript.Patient.PatientAddress.country       = country;                            //Validated above.
            ncScript.Patient.PatientContact               = new ContactType();
            ncScript.Patient.PatientContact.homeTelephone = pat.HmPhone;                        //May be blank. Does not need to be 10 digits.
            ncScript.Patient.PatientCharacteristics       = new PatientCharacteristicsType();
            ncScript.Patient.PatientCharacteristics.dob   = pat.Birthdate.ToString("yyyyMMdd"); //DOB must be in CCYYMMDD format.
            if (pat.Gender == PatientGender.Male)
            {
                ncScript.Patient.PatientCharacteristics.gender = GenderType.M;
            }
            else if (pat.Gender == PatientGender.Female)
            {
                ncScript.Patient.PatientCharacteristics.gender = GenderType.F;
            }
            else
            {
                ncScript.Patient.PatientCharacteristics.gender = GenderType.U;
            }
            ncScript.Patient.PatientCharacteristics.genderSpecified = true;
            //NewCrop programmer's comments regarding other fields we are not currently using (these fields are sent back when fetching prescriptions in the Chart):
            //ExternalPrescriptionId = your unique identifier for the prescription, only to be used if you are generating the prescription on your own UI.
            //	This is referenced by NewCrop, and cannot be populated with any other value.
            //EncounterIdentifier = unique ID for the patient visit (e.g. John Doe, 11/11/2013).
            //	This is used by NewCrop for reporting events against a visit, but otherwise does not impact the session.
            //EpisodeIdentifier = unique ID for the patient’s issue (e.g. John Doe’s broken leg) which may include multiple visits.
            //	Currently not used by NewCrop except for being echoed back; it is possible this functionality would be expanded in the future based on its intent as noted.
            //ExternalSource = a codified field noting the origin of the prescription. This may not be used.
            //Serialize
            MemoryStream  memoryStream  = new MemoryStream();
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(NCScript));

            xmlSerializer.Serialize(memoryStream, ncScript);
            byte[] memoryStreamInBytes = memoryStream.ToArray();
            return(Encoding.UTF8.GetString(memoryStreamInBytes, 0, memoryStreamInBytes.Length));
        }
예제 #19
0
        ///<summary>Gets the DataTable to display for treatment finder report</summary>
        ///<param name="listProviders">Include '0' in the list to get for all providers.</param>
        ///<param name="listBilling">Include '0' in the list to get for all billing types.</param>
        ///<param name="listClinicNums">Pass in an empty list to get for all clinics.</param>
        public static DataTable GetTreatmentFinderList(bool noIns, bool patsWithAppts, int monthStart, DateTime dateSince, double aboveAmount,
                                                       List <long> listProviders, List <long> listBilling, string code1, string code2, List <long> listClinicNums, bool isProcsGeneral)
        {
            //No remoting role check; no call to db
            Stopwatch sw     = null;
            Stopwatch sTotal = null;

            if (ODBuild.IsDebug())
            {
                sw     = Stopwatch.StartNew();
                sTotal = Stopwatch.StartNew();
            }
            DataTable table = new DataTable();

            //columns that start with lowercase are altered for display rather than being raw data.
            table.Columns.Add("PatNum");
            table.Columns.Add("LName");
            table.Columns.Add("FName");
            table.Columns.Add("contactMethod");
            table.Columns.Add("address");
            table.Columns.Add("City");
            table.Columns.Add("State");
            table.Columns.Add("Zip");
            table.Columns.Add("annualMaxInd");
            table.Columns.Add("annualMaxFam");
            table.Columns.Add("amountUsedInd");
            table.Columns.Add("amountUsedFam");
            table.Columns.Add("amountPendingInd");
            table.Columns.Add("amountPendingFam");
            table.Columns.Add("amountRemainingInd");
            table.Columns.Add("amountRemainingFam");
            table.Columns.Add("treatmentPlan");
            table.Columns.Add("carrierName");
            table.Columns.Add("clinicAbbr");
            //dictionary with Key=PatNum, Value=AmtPlanned
            Dictionary <long, double> dictAmtPlanned = new Dictionary <long, double>();

            using (DataTable tablePlanned = GetDictAmtPlanned(patsWithAppts, dateSince, listProviders, listBilling, code1, code2, listClinicNums)) {
                if (ODBuild.IsDebug())
                {
                    sw.Stop();
                    Console.WriteLine("Get tablePlanned: " + sw.Elapsed.TotalSeconds + " sec, Rows: " + tablePlanned.Rows.Count);
                    sw = Stopwatch.StartNew();
                }
                if (tablePlanned.Rows.Count == 0)
                {
                    return(table);
                }
                dictAmtPlanned = tablePlanned.Select().ToDictionary(x => PIn.Long(x["PatNum"].ToString()), x => PIn.Double(x["AmtPlanned"].ToString()));
            }
            string   patNumStr = string.Join(",", dictAmtPlanned.Keys.Select(x => POut.Long(x)));
            DateTime renewDate = BenefitLogic.ComputeRenewDate(DateTime.Now, monthStart);
            //dictionary with Key=PatPlanNum, Value=Tuple(AmtPending,AmtUsed)
            Dictionary <long, Tuple <double, double> > dictPatInfo = new Dictionary <long, Tuple <double, double> >();

            using (DataTable tablePat = GetPatInfo(isProcsGeneral, renewDate, patNumStr)) {
                dictPatInfo = tablePat.Select().ToDictionary(x => PIn.Long(x["PatPlanNum"].ToString()),
                                                             x => Tuple.Create(PIn.Double(x["AmtPending"].ToString()), PIn.Double(x["AmtUsed"].ToString())));
            }
            if (ODBuild.IsDebug())
            {
                sw.Stop();
                Console.WriteLine("Get dictPatInfo: " + sw.Elapsed.TotalSeconds + " sec, Count: " + dictPatInfo.Count);
                sw = Stopwatch.StartNew();
            }
            //dictionary with Key=InsSubNum, Value=Tuple(AmtPending,AmtUsed)
            Dictionary <long, Tuple <double, double> > dictFamInfo = new Dictionary <long, Tuple <double, double> >();

            using (DataTable tableFam = GetFamInfo(isProcsGeneral, renewDate, patNumStr)) {
                dictFamInfo = tableFam.Select().ToDictionary(x => PIn.Long(x["InsSubNum"].ToString()),
                                                             x => Tuple.Create(PIn.Double(x["AmtPending"].ToString()), PIn.Double(x["AmtUsed"].ToString())));
            }
            if (ODBuild.IsDebug())
            {
                sw.Stop();
                Console.WriteLine("Get dictFamInfo: " + sw.Elapsed.TotalSeconds + " sec, Rows: " + dictFamInfo.Count);
                sw = Stopwatch.StartNew();
            }
            //dictionary with Key=PlanNum, Value=Tuple(AnnualMaxInd,AnnualMaxFam)
            Dictionary <long, Tuple <double, double> > dictAnnualMax = new Dictionary <long, Tuple <double, double> >();

            using (DataTable tableAnnualMax = GetAnnualMaxInfo(patNumStr)) {
                dictAnnualMax = tableAnnualMax.Select().ToDictionary(x => PIn.Long(x["PlanNum"].ToString()),
                                                                     x => Tuple.Create(PIn.Double(x["AnnualMaxInd"].ToString()), PIn.Double(x["AnnualMaxFam"].ToString())));
            }
            if (ODBuild.IsDebug())
            {
                sw.Stop();
                Console.WriteLine("Get dictAnnualMax: " + sw.Elapsed.TotalSeconds + " sec, Rows: " + dictAnnualMax.Count);
                sw = Stopwatch.StartNew();
            }
            using (DataTable rawtable = GetTableRaw(noIns, monthStart, patNumStr)) {
                if (ODBuild.IsDebug())
                {
                    sw.Stop();
                    Console.WriteLine("Get RawTable: " + sw.Elapsed.TotalSeconds + " sec, Rows: " + rawtable.Rows.Count);
                    sw = Stopwatch.StartNew();
                }
                DataRow row;
                foreach (DataRow rawRow in rawtable.Rows)
                {
                    row = table.NewRow();
                    long   patNum     = PIn.Long(rawRow["PatNum"].ToString());
                    long   patPlanNum = PIn.Long(rawRow["PatPlanNum"].ToString());
                    long   planNum    = PIn.Long(rawRow["PlanNum"].ToString());
                    long   insSubNum  = PIn.Long(rawRow["InsSubNum"].ToString());
                    double amtPlanned = dictAmtPlanned.TryGetValue(patNum, out amtPlanned)?amtPlanned:0;
                    Tuple <double, double> tuplePatInfo = dictPatInfo.TryGetValue(patPlanNum, out tuplePatInfo)?tuplePatInfo:Tuple.Create(0d, 0d);
                    double patAmtPending = tuplePatInfo.Item1;
                    double patAmtUsed    = tuplePatInfo.Item2;
                    Tuple <double, double> tupleFamInfo = dictFamInfo.TryGetValue(insSubNum, out tupleFamInfo)?tupleFamInfo:Tuple.Create(0d, 0d);
                    double famAmtPending = tupleFamInfo.Item1;
                    double famAmtUsed    = tupleFamInfo.Item2;
                    Tuple <double, double> tupleAnnualMax = dictAnnualMax.TryGetValue(planNum, out tupleAnnualMax)?tupleAnnualMax:Tuple.Create(0d, 0d);
                    double patAnnualMax = tupleAnnualMax.Item1;
                    double famAnnualMax = tupleAnnualMax.Item2;
                    if (aboveAmount > 0)
                    {
                        if (dictAnnualMax.ContainsKey(planNum) &&
                            ((patAnnualMax != -1 && patAnnualMax - patAmtUsed <= aboveAmount) || (famAnnualMax != -1 && famAnnualMax - famAmtUsed <= aboveAmount)))
                        {
                            continue;
                        }
                    }
                    row["PatNum"] = patNum;
                    row["LName"]  = rawRow["LName"].ToString();
                    row["FName"]  = rawRow["FName"].ToString();
                    ContactMethod contmeth = PIn.Enum <ContactMethod>(rawRow["PreferRecallMethod"].ToString());
                    switch (contmeth)
                    {
                    case ContactMethod.None:
                        if (PrefC.GetBool(PrefName.RecallUseEmailIfHasEmailAddress) && !string.IsNullOrEmpty(rawRow["Email"].ToString()))
                        {
                            row["contactMethod"] = rawRow["Email"].ToString();
                        }
                        else
                        {
                            row["contactMethod"] = Lans.g("FormRecallList", "Hm:") + rawRow["HmPhone"].ToString();
                        }
                        break;

                    case ContactMethod.HmPhone:
                        row["contactMethod"] = Lans.g("FormRecallList", "Hm:") + rawRow["HmPhone"].ToString();
                        break;

                    case ContactMethod.WkPhone:
                        row["contactMethod"] = Lans.g("FormRecallList", "Wk:") + rawRow["WkPhone"].ToString();
                        break;

                    case ContactMethod.WirelessPh:
                        row["contactMethod"] = Lans.g("FormRecallList", "Cell:") + rawRow["WirelessPhone"].ToString();
                        break;

                    case ContactMethod.Email:
                        row["contactMethod"] = rawRow["Email"].ToString();
                        break;

                    case ContactMethod.Mail:
                    case ContactMethod.DoNotCall:
                    case ContactMethod.SeeNotes:
                        row["contactMethod"] = Lans.g("enumContactMethod", contmeth.ToString());
                        break;
                    }
                    row["address"]            = rawRow["Address"].ToString() + (string.IsNullOrEmpty(rawRow["Address2"].ToString())?"":("\r\n" + rawRow["Address2"].ToString()));
                    row["City"]               = rawRow["City"].ToString();
                    row["State"]              = rawRow["State"].ToString();
                    row["Zip"]                = rawRow["Zip"].ToString();
                    row["annualMaxInd"]       = patAnnualMax.ToString("N");
                    row["annualMaxFam"]       = famAnnualMax.ToString("N");
                    row["amountUsedInd"]      = patAmtUsed.ToString("N");
                    row["amountUsedFam"]      = famAmtUsed.ToString("N");
                    row["amountPendingInd"]   = patAmtPending.ToString("N");
                    row["amountPendingFam"]   = famAmtPending.ToString("N");
                    row["amountRemainingInd"] = (patAnnualMax - patAmtUsed - patAmtPending).ToString("N");
                    row["amountRemainingFam"] = (famAnnualMax - famAmtUsed - famAmtPending).ToString("N");
                    row["treatmentPlan"]      = amtPlanned.ToString("N");
                    row["carrierName"]        = rawRow["carrierName"].ToString();
                    if (PrefC.HasClinicsEnabled)
                    {
                        row["clinicAbbr"] = rawRow["clinicAbbr"].ToString();
                    }
                    table.Rows.Add(row);
                }
            }
            if (ODBuild.IsDebug())
            {
                sw.Stop();
                sTotal.Stop();
                Console.WriteLine("Finished Filling DataTable: {0}\r\n\tTotal time: {1}\r\n\tRows: {2}",
                                  (sw.Elapsed.Minutes > 0?(sw.Elapsed.Minutes + " min "):"") + (sw.Elapsed.TotalSeconds - sw.Elapsed.Minutes * 60) + " sec",
                                  (sTotal.Elapsed.Minutes > 0?(sTotal.Elapsed.Minutes + " min "):"") + (sTotal.Elapsed.TotalSeconds - sTotal.Elapsed.Minutes * 60) + " sec",
                                  table.Rows.Count);
            }
            return(table);
        }
예제 #20
0
        public static List <DisplayField> GetAllAvailableList(DisplayFieldCategory category)
        {
            //No need to check RemotingRole; no call to db.
            List <DisplayField> list = new List <DisplayField>();

            if (category == DisplayFieldCategory.None)           //Currently only used for ChartViews
            {
                list.Add(new DisplayField("Date", 67, category));
                list.Add(new DisplayField("Time", 40, category));
                list.Add(new DisplayField("Th", 27, category));
                list.Add(new DisplayField("Surf", 40, category));
                list.Add(new DisplayField("Dx", 28, category));
                list.Add(new DisplayField("Description", 218, category));
                list.Add(new DisplayField("Stat", 25, category));
                list.Add(new DisplayField("Prov", 42, category));
                list.Add(new DisplayField("Amount", 48, category));
                list.Add(new DisplayField("ADA Code", 62, category));
                list.Add(new DisplayField("User", 62, category));
                list.Add(new DisplayField("Signed", 55, category));
                list.Add(new DisplayField("Priority", 44, category));
                list.Add(new DisplayField("Date TP", 67, category));
                list.Add(new DisplayField("Date Entry", 67, category));
                list.Add(new DisplayField("Prognosis", 60, category));
                list.Add(new DisplayField("Length", 40, category));
                list.Add(new DisplayField("Abbr", 50, category));
                list.Add(new DisplayField("Locked", 50, category));
                if (Programs.UsingOrion)
                {
                    list.Add(new DisplayField("DPC", 33, category));
                    list.Add(new DisplayField("Schedule By", 72, category));
                    list.Add(new DisplayField("Stop Clock", 67, category));
                    list.Add(new DisplayField("Stat 2", 36, category));
                    list.Add(new DisplayField("On Call", 45, category));
                    list.Add(new DisplayField("Effective Comm", 90, category));
                    list.Add(new DisplayField("End Time", 56, category));                  //not visible unless orion
                    list.Add(new DisplayField("Quadrant", 55, category));                  //behavior is specific to orion
                    list.Add(new DisplayField("DPCpost", 52, category));
                }
            }
            else if (category == DisplayFieldCategory.PatientSelect)
            {
                list.Add(new DisplayField("LastName", 75, category));
                list.Add(new DisplayField("First Name", 75, category));
                list.Add(new DisplayField("MI", 25, category));
                list.Add(new DisplayField("Pref Name", 60, category));
                list.Add(new DisplayField("Age", 30, category));
                list.Add(new DisplayField("SSN", 65, category));
                list.Add(new DisplayField("Hm Phone", 90, category));
                list.Add(new DisplayField("Wk Phone", 90, category));
                if (PrefC.GetBool(PrefName.DistributorKey))                 //if for OD HQ
                {
                    list.Add(new DisplayField("OtherPhone", 90, category));
                }
                list.Add(new DisplayField("PatNum", 80, category));
                list.Add(new DisplayField("ChartNum", 60, category));
                list.Add(new DisplayField("Address", 100, category));
                list.Add(new DisplayField("Status", 65, category));
                list.Add(new DisplayField("Bill Type", 90, category));
                list.Add(new DisplayField("City", 80, category));
                list.Add(new DisplayField("State", 55, category));
                list.Add(new DisplayField("Pri Prov", 85, category));
                list.Add(new DisplayField("Birthdate", 70, category));
                list.Add(new DisplayField("Site", 90, category));
                list.Add(new DisplayField("Email", 90, category));
            }
            else if (category == DisplayFieldCategory.PatientInformation)
            {
                list.Add(new DisplayField("Last", 0, category));
                list.Add(new DisplayField("First", 0, category));
                list.Add(new DisplayField("Middle", 0, category));
                list.Add(new DisplayField("Preferred", 0, category));
                list.Add(new DisplayField("Title", 0, category));
                list.Add(new DisplayField("Salutation", 0, category));
                list.Add(new DisplayField("Status", 0, category));
                list.Add(new DisplayField("Gender", 0, category));
                list.Add(new DisplayField("Position", 0, category));
                list.Add(new DisplayField("Birthdate", 0, category));
                list.Add(new DisplayField("Age", 0, category));
                list.Add(new DisplayField("SS#", 0, category));
                list.Add(new DisplayField("Address", 0, category));
                list.Add(new DisplayField("Address2", 0, category));
                list.Add(new DisplayField("City", 0, category));
                list.Add(new DisplayField("State", 0, category));
                if (PrefC.GetBool(PrefName.DockPhonePanelShow))
                {
                    list.Add(new DisplayField("Country", 0, category));
                }
                list.Add(new DisplayField("Zip", 0, category));
                list.Add(new DisplayField("Hm Phone", 0, category));
                list.Add(new DisplayField("Wk Phone", 0, category));
                list.Add(new DisplayField("Wireless Ph", 0, category));
                list.Add(new DisplayField("E-mail", 0, category));
                list.Add(new DisplayField("Contact Method", 0, category));
                list.Add(new DisplayField("ABC0", 0, category));
                list.Add(new DisplayField("Chart Num", 0, category));
                list.Add(new DisplayField("Billing Type", 0, category));
                list.Add(new DisplayField("Ward", 0, category));
                list.Add(new DisplayField("AdmitDate", 0, category));
                list.Add(new DisplayField("Primary Provider", 0, category));
                list.Add(new DisplayField("Sec. Provider", 0, category));
                list.Add(new DisplayField("Payor Types", 0, category));
                list.Add(new DisplayField("Language", 0, category));
                list.Add(new DisplayField("Clinic", 0, category));
                list.Add(new DisplayField("ResponsParty", 0, category));
                list.Add(new DisplayField("Referrals", 0, category));
                list.Add(new DisplayField("Addr/Ph Note", 0, category));
                list.Add(new DisplayField("PatFields", 0, category));
                list.Add(new DisplayField("Guardians", 0, category));
                list.Add(new DisplayField("Arrive Early", 0, category));
                list.Add(new DisplayField("Super Head", 0, category));
                if (PrefC.GetBool(PrefName.DistributorKey))
                {
                    list.Add(new DisplayField("References", 0, category));
                }
            }
            else if (category == DisplayFieldCategory.AccountModule)
            {
                list.Add(new DisplayField("Date", 65, category));
                list.Add(new DisplayField("Patient", 100, category));
                list.Add(new DisplayField("Prov", 40, category));
                list.Add(new DisplayField("Clinic", 50, category));
                list.Add(new DisplayField("Code", 46, category));
                list.Add(new DisplayField("Tth", 26, category));
                list.Add(new DisplayField("Description", 270, category));
                list.Add(new DisplayField("Charges", 60, category));
                list.Add(new DisplayField("Credits", 60, category));
                list.Add(new DisplayField("Balance", 60, category));
            }
            else if (category == DisplayFieldCategory.RecallList)
            {
                list.Add(new DisplayField("Due Date", 75, category));
                list.Add(new DisplayField("Patient", 120, category));
                list.Add(new DisplayField("Age", 30, category));
                list.Add(new DisplayField("Type", 60, category));
                list.Add(new DisplayField("Interval", 50, category));
                list.Add(new DisplayField("#Remind", 55, category));
                list.Add(new DisplayField("LastRemind", 75, category));
                list.Add(new DisplayField("Contact", 120, category));
                list.Add(new DisplayField("Status", 130, category));
                list.Add(new DisplayField("Note", 215, category));
                list.Add(new DisplayField("BillingType", 100, category));
            }
            else if (category == DisplayFieldCategory.ChartPatientInformation)
            {
                list.Add(new DisplayField("Age", 0, category));
                list.Add(new DisplayField("ABC0", 0, category));
                list.Add(new DisplayField("Billing Type", 0, category));
                list.Add(new DisplayField("Referred From", 0, category));
                list.Add(new DisplayField("Date First Visit", 0, category));
                list.Add(new DisplayField("Prov. (Pri, Sec)", 0, category));
                list.Add(new DisplayField("Pri Ins", 0, category));
                list.Add(new DisplayField("Sec Ins", 0, category));
                list.Add(new DisplayField("Payor Types", 0, category));
                if (PrefC.GetBool(PrefName.DistributorKey))
                {
                    list.Add(new DisplayField("Registration Keys", 0, category));
                    list.Add(new DisplayField("Ehr Provider Keys", 0, category));
                    list.Add(new DisplayField("References", 0, category));
                }
                list.Add(new DisplayField("Premedicate", 0, category));
                list.Add(new DisplayField("Problems", 0, category));
                list.Add(new DisplayField("Med Urgent", 0, category));
                list.Add(new DisplayField("Medical Summary", 0, category));
                list.Add(new DisplayField("Service Notes", 0, category));
                list.Add(new DisplayField("Medications", 0, category));
                list.Add(new DisplayField("Allergies", 0, category));
                list.Add(new DisplayField("PatFields", 0, category));
                list.Add(new DisplayField("Birthdate", 0, category));
                list.Add(new DisplayField("City", 0, category));
                list.Add(new DisplayField("AskToArriveEarly", 0, category));
                list.Add(new DisplayField("Super Head", 0, category));
                list.Add(new DisplayField("Patient Portal", 0, category));
            }
            else if (category == DisplayFieldCategory.ProcedureGroupNote)
            {
                list.Add(new DisplayField("Date", 67, category));
                list.Add(new DisplayField("Th", 27, category));
                list.Add(new DisplayField("Surf", 40, category));
                list.Add(new DisplayField("Description", 218, category));
                list.Add(new DisplayField("Stat", 25, category));
                list.Add(new DisplayField("Prov", 42, category));
                list.Add(new DisplayField("Amount", 48, category));
                list.Add(new DisplayField("ADA Code", 62, category));
                if (Programs.UsingOrion)
                {
                    list.Add(new DisplayField("Stat 2", 36, category));
                    list.Add(new DisplayField("On Call", 45, category));
                    list.Add(new DisplayField("Effective Comm", 90, category));
                    list.Add(new DisplayField("Repair", 45, category));
                    list.Add(new DisplayField("DPCpost", 52, category));
                }
            }
            else if (category == DisplayFieldCategory.TreatmentPlanModule)
            {
                list.Add(new DisplayField("Done", 50, category));
                list.Add(new DisplayField("Priority", 50, category));
                list.Add(new DisplayField("Tth", 40, category));
                list.Add(new DisplayField("Surf", 45, category));
                list.Add(new DisplayField("Code", 50, category));
                list.Add(new DisplayField("Description", 235, category));
                list.Add(new DisplayField("Fee", 50, category));
                list.Add(new DisplayField("Pri Ins", 50, category));
                list.Add(new DisplayField("Sec Ins", 50, category));
                list.Add(new DisplayField("Discount", 55, category));
                list.Add(new DisplayField("Pat", 50, category));
                list.Add(new DisplayField("Prognosis", 60, category));
                list.Add(new DisplayField("Dx", 28, category));
            }
            else if (category == DisplayFieldCategory.OrthoChart)
            {
                list = GetForCategory(DisplayFieldCategory.OrthoChart);              //The display fields that the user has already saved
                List <OrthoChart> listDistinctOrthoCharts = OrthoCharts.GetByDistinctFieldNames();
                for (int i = 0; i < listDistinctOrthoCharts.Count; i++)
                {
                    bool addToList = true;
                    for (int j = 0; j < list.Count; j++)
                    {
                        if (list[j].Description == listDistinctOrthoCharts[i].FieldName)
                        {
                            addToList = false;
                        }
                    }
                    if (addToList)
                    {
                        DisplayField df = new DisplayField("", 20, DisplayFieldCategory.OrthoChart);
                        df.Description = listDistinctOrthoCharts[i].FieldName;
                        list.Add(df);
                    }
                }
            }
            return(list);
        }
예제 #21
0
        ///<summary>For orderBy, use 0 for BillingType and 1 for PatientName.</summary>
        public static DataTable GetBilling(bool isSent, int orderBy, DateTime dateFrom, DateTime dateTo, long clinicNum)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetTable(MethodBase.GetCurrentMethod(), isSent, orderBy, dateFrom, dateTo, clinicNum));
            }
            DataTable table = new DataTable();
            DataRow   row;

            //columns that start with lowercase are altered for display rather than being raw data.
            table.Columns.Add("amountDue");
            table.Columns.Add("balTotal");
            table.Columns.Add("billingType");
            table.Columns.Add("insEst");
            table.Columns.Add("IsSent");
            table.Columns.Add("lastStatement");
            table.Columns.Add("mode");
            table.Columns.Add("name");
            table.Columns.Add("PatNum");
            table.Columns.Add("payPlanDue");
            table.Columns.Add("StatementNum");
            List <DataRow> rows    = new List <DataRow>();
            string         command = "SELECT BalTotal,BillingType,FName,InsEst,statement.IsSent,"
                                     + "IFNULL(MAX(s2.DateSent)," + POut.Date(DateTime.MinValue) + ") LastStatement,"
                                     + "LName,MiddleI,statement.Mode_,PayPlanDue,Preferred,"
                                     + "statement.PatNum,statement.StatementNum "
                                     + "FROM statement "
                                     + "LEFT JOIN patient ON statement.PatNum=patient.PatNum "
                                     + "LEFT JOIN statement s2 ON s2.PatNum=patient.PatNum "
                                     + "AND s2.IsSent=1 ";

            if (PrefC.GetBool(PrefName.BillingIgnoreInPerson))
            {
                command += "AND s2.Mode_ !=1 ";
            }
            if (orderBy == 0)          //BillingType
            {
                command += "LEFT JOIN definition ON patient.BillingType=definition.DefNum ";
            }
            command += "WHERE statement.IsSent=" + POut.Bool(isSent) + " ";
            //if(dateFrom.Year>1800){
            command += "AND statement.DateSent>=" + POut.Date(dateFrom) + " ";      //greater than midnight this morning
            //}
            //if(dateFrom.Year>1800){
            command += "AND statement.DateSent<" + POut.Date(dateTo.AddDays(1)) + " ";      //less than midnight tonight
            //}
            if (clinicNum > 0)
            {
                command += "AND patient.ClinicNum=" + clinicNum + " ";
            }
            command += "GROUP BY BalTotal,BillingType,FName,InsEst,statement.IsSent,"
                       + "LName,MiddleI,statement.Mode_,PayPlanDue,Preferred,"
                       + "statement.PatNum,statement.StatementNum ";
            if (orderBy == 0)          //BillingType
            {
                command += "ORDER BY definition.ItemOrder,LName,FName,MiddleI,PayPlanDue";
            }
            else
            {
                command += "ORDER BY LName,FName";
            }
            DataTable     rawTable = Db.GetTable(command);
            Patient       pat;
            StatementMode mode;
            double        balTotal;
            double        insEst;
            double        payPlanDue;
            DateTime      lastStatement;

            for (int i = 0; i < rawTable.Rows.Count; i++)
            {
                row                = table.NewRow();
                balTotal           = PIn.Double(rawTable.Rows[i]["BalTotal"].ToString());
                insEst             = PIn.Double(rawTable.Rows[i]["InsEst"].ToString());
                payPlanDue         = PIn.Double(rawTable.Rows[i]["PayPlanDue"].ToString());
                row["amountDue"]   = (balTotal - insEst).ToString("F");
                row["balTotal"]    = balTotal.ToString("F");;
                row["billingType"] = DefC.GetName(DefCat.BillingTypes, PIn.Long(rawTable.Rows[i]["BillingType"].ToString()));
                if (insEst == 0)
                {
                    row["insEst"] = "";
                }
                else
                {
                    row["insEst"] = insEst.ToString("F");
                }
                row["IsSent"] = rawTable.Rows[i]["IsSent"].ToString();
                lastStatement = PIn.Date(rawTable.Rows[i]["LastStatement"].ToString());
                if (lastStatement.Year < 1880)
                {
                    row["lastStatement"] = "";
                }
                else
                {
                    row["lastStatement"] = lastStatement.ToShortDateString();
                }
                mode          = (StatementMode)PIn.Long(rawTable.Rows[i]["Mode_"].ToString());
                row["mode"]   = Lans.g("enumStatementMode", mode.ToString());
                pat           = new Patient();
                pat.LName     = rawTable.Rows[i]["LName"].ToString();
                pat.FName     = rawTable.Rows[i]["FName"].ToString();
                pat.Preferred = rawTable.Rows[i]["Preferred"].ToString();
                pat.MiddleI   = rawTable.Rows[i]["MiddleI"].ToString();
                row["name"]   = pat.GetNameLF();
                row["PatNum"] = rawTable.Rows[i]["PatNum"].ToString();
                if (payPlanDue == 0)
                {
                    row["payPlanDue"] = "";
                }
                else
                {
                    row["payPlanDue"] = payPlanDue.ToString("F");
                }
                row["StatementNum"] = rawTable.Rows[i]["StatementNum"].ToString();
                rows.Add(row);
            }
            for (int i = 0; i < rows.Count; i++)
            {
                table.Rows.Add(rows[i]);
            }
            return(table);
        }
예제 #22
0
        public static List <DisplayField> GetDefaultList(DisplayFieldCategory category)
        {
            //No need to check RemotingRole; no call to db.
            List <DisplayField> list = new List <DisplayField>();

            if (category == DisplayFieldCategory.None)
            {
                list.Add(new DisplayField("Date", 67, category));
                //list.Add(new DisplayField("Time",40));
                list.Add(new DisplayField("Th", 27, category));
                list.Add(new DisplayField("Surf", 40, category));
                list.Add(new DisplayField("Dx", 28, category));
                list.Add(new DisplayField("Description", 218, category));
                list.Add(new DisplayField("Stat", 25, category));
                list.Add(new DisplayField("Prov", 42, category));
                list.Add(new DisplayField("Amount", 48, category));
                list.Add(new DisplayField("ADA Code", 62, category));
                list.Add(new DisplayField("User", 62, category));
                list.Add(new DisplayField("Signed", 55, category));
                //list.Add(new DisplayField("Priority",65,category));
                //list.Add(new DisplayField("Date TP",67,category));
                //list.Add(new DisplayField("Date Entry",67,category));
                //list.Add(new DisplayField("Prognosis",60,category));
                //list.Add(new DisplayField("Length",40,category));
                //list.Add(new DisplayField("Abbr",50,category));
                //list.Add(new DisplayField("Locked",50,category));
                //if(Programs.UsingOrion){
                //list.Add(new DisplayField("DPC",33,category));
                //list.Add(new DisplayField("Schedule By",72,category));
                //list.Add(new DisplayField("Stop Clock",67,category));
                //list.Add(new DisplayField("Stat 2",36,category));
                //list.Add(new DisplayField("On Call",45,category));
                //list.Add(new DisplayField("Effective Comm",90,category));
                //list.Add(new DisplayField("End Time",56,category));
                //list.Add(new DisplayField("Quadrant",55,category));
                //list.Add(new DisplayField("DPCpost",52,category));
                //}
            }
            else if (category == DisplayFieldCategory.PatientSelect)
            {
                list.Add(new DisplayField("LastName", 75, category));
                list.Add(new DisplayField("First Name", 75, category));
                //list.Add(new DisplayField("MI",25,category));
                list.Add(new DisplayField("Pref Name", 60, category));
                list.Add(new DisplayField("Age", 30, category));
                list.Add(new DisplayField("SSN", 65, category));
                list.Add(new DisplayField("Hm Phone", 90, category));
                list.Add(new DisplayField("Wk Phone", 90, category));
                if (PrefC.GetBool(PrefName.DistributorKey))                 //if for OD HQ
                //list.Add(new DisplayField("OtherPhone",90,category));
                {
                }
                list.Add(new DisplayField("PatNum", 80, category));
                //list.Add(new DisplayField("ChartNum",60,category));
                list.Add(new DisplayField("Address", 100, category));
                list.Add(new DisplayField("Status", 65, category));
                //list.Add(new DisplayField("Bill Type",90,category));
                //list.Add(new DisplayField("City",80,category));
                //list.Add(new DisplayField("State",55,category));
                //list.Add(new DisplayField("Pri Prov",85,category));
                //list.Add(new DisplayField("Birthdate",70,category));
                //list.Add(new DisplayField("Site",90,category));
                //list.Add(new DisplayField("Email",90,category));
            }
            else if (category == DisplayFieldCategory.PatientInformation)
            {
                list.Add(new DisplayField("Last", 0, category));
                list.Add(new DisplayField("First", 0, category));
                list.Add(new DisplayField("Middle", 0, category));
                list.Add(new DisplayField("Preferred", 0, category));
                list.Add(new DisplayField("Title", 0, category));
                list.Add(new DisplayField("Salutation", 0, category));
                list.Add(new DisplayField("Status", 0, category));
                list.Add(new DisplayField("Gender", 0, category));
                list.Add(new DisplayField("Position", 0, category));
                list.Add(new DisplayField("Birthdate", 0, category));
                list.Add(new DisplayField("Age", 0, category));
                list.Add(new DisplayField("SS#", 0, category));
                list.Add(new DisplayField("Address", 0, category));
                list.Add(new DisplayField("Address2", 0, category));
                list.Add(new DisplayField("City", 0, category));
                list.Add(new DisplayField("State", 0, category));
                if (PrefC.GetBool(PrefName.DockPhonePanelShow))
                {
                    list.Add(new DisplayField("Country", 0, category));
                }
                list.Add(new DisplayField("Zip", 0, category));
                list.Add(new DisplayField("Hm Phone", 0, category));
                list.Add(new DisplayField("Wk Phone", 0, category));
                list.Add(new DisplayField("Wireless Ph", 0, category));
                list.Add(new DisplayField("E-mail", 0, category));
                list.Add(new DisplayField("Contact Method", 0, category));
                list.Add(new DisplayField("ABC0", 0, category));
                //list.Add(new DisplayField("Chart Num",0,category));
                list.Add(new DisplayField("Billing Type", 0, category));
                //list.Add(new DisplayField("Ward",0,category));
                //list.Add(new DisplayField("AdmitDate",0,category));
                list.Add(new DisplayField("Primary Provider", 0, category));
                list.Add(new DisplayField("Sec. Provider", 0, category));
                list.Add(new DisplayField("Payor Types", 0, category));
                list.Add(new DisplayField("Language", 0, category));
                //list.Add(new DisplayField("Clinic",0,category));
                //list.Add(new DisplayField("ResponsParty",0,category));
                list.Add(new DisplayField("Referrals", 0, category));
                list.Add(new DisplayField("Addr/Ph Note", 0, category));
                list.Add(new DisplayField("PatFields", 0, category));
                //list.Add(new DisplayField("Guardians",0,category));
                //list.Add(new DisplayField("Arrive Early",0,category));
                //list.Add(new DisplayField("Super Head",0,category));
                if (PrefC.GetBool(PrefName.DistributorKey))
                {
                    list.Add(new DisplayField("References", 0, category));
                }
            }
            else if (category == DisplayFieldCategory.AccountModule)
            {
                list.Add(new DisplayField("Date", 65, category));
                list.Add(new DisplayField("Patient", 100, category));
                list.Add(new DisplayField("Prov", 40, category));
                //list.Add(new DisplayField("Clinic",50,category));
                list.Add(new DisplayField("Code", 46, category));
                list.Add(new DisplayField("Tth", 26, category));
                list.Add(new DisplayField("Description", 270, category));
                list.Add(new DisplayField("Charges", 60, category));
                list.Add(new DisplayField("Credits", 60, category));
                list.Add(new DisplayField("Balance", 60, category));
            }
            else if (category == DisplayFieldCategory.RecallList)
            {
                list.Add(new DisplayField("Due Date", 75, category));
                list.Add(new DisplayField("Patient", 120, category));
                list.Add(new DisplayField("Age", 30, category));
                list.Add(new DisplayField("Type", 60, category));
                list.Add(new DisplayField("Interval", 50, category));
                list.Add(new DisplayField("#Remind", 55, category));
                list.Add(new DisplayField("LastRemind", 75, category));
                list.Add(new DisplayField("Contact", 120, category));
                list.Add(new DisplayField("Status", 130, category));
                list.Add(new DisplayField("Note", 215, category));
                //list.Add(new DisplayField("BillingType",100,category));
            }
            else if (category == DisplayFieldCategory.ChartPatientInformation)
            {
                list.Add(new DisplayField("Age", 0, category));
                list.Add(new DisplayField("ABC0", 0, category));
                list.Add(new DisplayField("Billing Type", 0, category));
                list.Add(new DisplayField("Referred From", 0, category));
                list.Add(new DisplayField("Date First Visit", 0, category));
                list.Add(new DisplayField("Prov. (Pri, Sec)", 0, category));
                list.Add(new DisplayField("Pri Ins", 0, category));
                list.Add(new DisplayField("Sec Ins", 0, category));
                list.Add(new DisplayField("Payor Types", 0, category));
                if (PrefC.GetBool(PrefName.DistributorKey))
                {
                    list.Add(new DisplayField("Registration Keys", 0, category));
                    list.Add(new DisplayField("Ehr Provider Keys", 0, category));
                    list.Add(new DisplayField("References", 0, category));
                }
                //different default list for eCW:
                if (!Programs.UsingEcwTightOrFullMode())
                {
                    list.Add(new DisplayField("Premedicate", 0, category));
                    list.Add(new DisplayField("Problems", 0, category));
                    list.Add(new DisplayField("Med Urgent", 0, category));
                    list.Add(new DisplayField("Medical Summary", 0, category));
                    list.Add(new DisplayField("Service Notes", 0, category));
                    list.Add(new DisplayField("Medications", 0, category));
                    list.Add(new DisplayField("Allergies", 0, category));
                }
                //list.Add(new DisplayField("PatFields",0,category));
                //list.Add(new DisplayField("Birthdate",0,category));
                //list.Add(new DisplayField("City",0,category));
                //list.Add(new DisplayField("AskToArriveEarly",0,category));
                //list.Add(new DisplayField("Super Head",0,category));
                //list.Add(new DisplayField("Patient Portal",0,category));
            }
            else if (category == DisplayFieldCategory.ProcedureGroupNote)
            {
                list.Add(new DisplayField("Date", 67, category));
                list.Add(new DisplayField("Th", 27, category));
                list.Add(new DisplayField("Surf", 40, category));
                list.Add(new DisplayField("Description", 203, category));
                list.Add(new DisplayField("Stat", 25, category));
                list.Add(new DisplayField("Prov", 42, category));
                list.Add(new DisplayField("Amount", 48, category));
                list.Add(new DisplayField("ADA Code", 62, category));
                //if(Programs.UsingOrion){
                //  list.Add(new DisplayField("Stat 2",36,category));
                //  list.Add(new DisplayField("On Call",45,category));
                //  list.Add(new DisplayField("Effective Comm",90,category));
                //  list.Add(new DisplayField("Repair",45,category));
                //	list.Add(new DisplayField("DPCpost",52,category));
                //}
            }
            else if (category == DisplayFieldCategory.TreatmentPlanModule)
            {
                list.Add(new DisplayField("Done", 50, category));
                list.Add(new DisplayField("Priority", 50, category));
                list.Add(new DisplayField("Tth", 40, category));
                list.Add(new DisplayField("Surf", 45, category));
                list.Add(new DisplayField("Code", 50, category));
                list.Add(new DisplayField("Description", 235, category));
                list.Add(new DisplayField("Fee", 50, category));
                list.Add(new DisplayField("Pri Ins", 50, category));
                list.Add(new DisplayField("Sec Ins", 50, category));
                list.Add(new DisplayField("Discount", 55, category));
                list.Add(new DisplayField("Pat", 50, category));
                //list.Add(new DisplayField("Prognosis",60,category));
                //list.Add(new DisplayField("Dx",28,category));
            }
            else if (category == DisplayFieldCategory.OrthoChart)
            {
                //Ortho chart has no default columns.  User must explicitly set up columns.
            }
            return(list);
        }
예제 #23
0
        /// <summary>Only Called only from FormPayment.butOK click.  Only called if the user did not enter any splits.  Usually just adds one split for the current patient.  But if that would take the balance negative, then it loops through all other family members and creates splits for them.  It might still take the current patient negative once all other family members are zeroed out.</summary>
        public static List <PaySplit> Allocate(Payment pay)        //double amtTot,int patNum,Payment payNum){
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <List <PaySplit> >(MethodBase.GetCurrentMethod(), pay));
            }
            string command =
                "SELECT Guarantor FROM patient "
                + "WHERE PatNum = " + POut.Long(pay.PatNum);
            DataTable table = Db.GetTable(command);

            if (table.Rows.Count == 0)
            {
                return(new List <PaySplit>());
            }
            command =
                "SELECT patient.PatNum,EstBalance,PriProv,SUM(InsPayEst)+SUM(Writeoff) insEst_ "
                + "FROM patient "
                + "LEFT JOIN claimproc ON patient.PatNum=claimproc.PatNum "
                + "AND Status=0 "               //NotReceived
                + "WHERE Guarantor = " + table.Rows[0][0].ToString() + " "
                + "GROUP BY  patient.PatNum,EstBalance,PriProv";
            //+" ORDER BY PatNum!="+POut.PInt(pay.PatNum);//puts current patient in position 0 //Oracle does not allow
            table = Db.GetTable(command);
            List <Patient> pats = new List <Patient>();
            Patient        pat;

            //first, put the current patient at position 0.
            for (int i = 0; i < table.Rows.Count; i++)
            {
                if (table.Rows[i]["PatNum"].ToString() == pay.PatNum.ToString())
                {
                    pat            = new Patient();
                    pat.PatNum     = PIn.Long(table.Rows[i][0].ToString());
                    pat.EstBalance = PIn.Double(table.Rows[i][1].ToString());
                    if (!PrefC.GetBool(PrefName.BalancesDontSubtractIns))
                    {
                        pat.EstBalance -= PIn.Double(table.Rows[i]["insEst_"].ToString());
                    }
                    pat.PriProv = PIn.Long(table.Rows[i][2].ToString());
                    pats.Add(pat.Copy());
                }
            }
            //then, do all the rest of the patients.
            for (int i = 0; i < table.Rows.Count; i++)
            {
                if (table.Rows[i]["PatNum"].ToString() == pay.PatNum.ToString())
                {
                    continue;
                }
                pat            = new Patient();
                pat.PatNum     = PIn.Long(table.Rows[i][0].ToString());
                pat.EstBalance = PIn.Double(table.Rows[i][1].ToString());
                if (!PrefC.GetBool(PrefName.BalancesDontSubtractIns))
                {
                    pat.EstBalance -= PIn.Double(table.Rows[i]["insEst_"].ToString());
                }
                pat.PriProv = PIn.Long(table.Rows[i][2].ToString());
                pats.Add(pat.Copy());
            }
            //first calculate all the amounts
            double amtRemain = pay.PayAmt;          //start off with the full amount

            double[] amtSplits = new double[pats.Count];
            //loop through each family member, starting with current
            for (int i = 0; i < pats.Count; i++)
            {
                if (pats[i].EstBalance == 0 || pats[i].EstBalance < 0)
                {
                    continue;                       //don't apply paysplits to anyone with a negative balance
                }
                if (amtRemain < pats[i].EstBalance) //entire remainder can be allocated to this patient
                {
                    amtSplits[i] = amtRemain;
                    amtRemain    = 0;
                    break;
                }
                else                 //amount remaining is more than or equal to the estBal for this family member
                {
                    amtSplits[i] = pats[i].EstBalance;
                    amtRemain   -= pats[i].EstBalance;
                }
            }
            //add any remainder to the split for this patient
            amtSplits[0] += amtRemain;
            //now create a split for each non-zero amount
            PaySplit        PaySplitCur;
            List <PaySplit> retVal = new List <PaySplit>();

            for (int i = 0; i < pats.Count; i++)
            {
                if (amtSplits[i] == 0)
                {
                    continue;
                }
                PaySplitCur           = new PaySplit();
                PaySplitCur.PatNum    = pats[i].PatNum;
                PaySplitCur.PayNum    = pay.PayNum;
                PaySplitCur.DatePay   = pay.PayDate;
                PaySplitCur.ClinicNum = pay.ClinicNum;
                PaySplitCur.ProvNum   = Patients.GetProvNum(pats[i]);
                PaySplitCur.SplitAmt  = Math.Round(amtSplits[i], CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalDigits);
                //PaySplitCur.InsertOrUpdate(true);
                retVal.Add(PaySplitCur);
            }
            //finally, adjust each EstBalance, but no need to do current patient
            //This no longer works here.  Must do it when closing payment window somehow

            /*for(int i=1;i<pats.Length;i++){
             *      if(amtSplits[i]==0){
             *              continue;
             *      }
             *      command="UPDATE patient SET EstBalance=EstBalance-"+POut.PDouble(amtSplits[i])
             +" WHERE PatNum="+POut.PInt(pats[i].PatNum);
             *      Db.NonQ(command);
             * }*/
            return(retVal);
        }
예제 #24
0
        ///<summary>Returns a SerializableDictionary with key=PatNum, value=PatAgingData with the filters applied.</summary>
        public static SerializableDictionary <long, PatAgingData> GetAgingData(bool isSinglePatient, bool includeChanged, bool excludeInsPending,
                                                                               bool excludeIfUnsentProcs, bool isSuperBills, List <long> listClinicNums)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <SerializableDictionary <long, PatAgingData> >(MethodBase.GetCurrentMethod(), isSinglePatient, includeChanged,
                                                                                     excludeInsPending, excludeIfUnsentProcs, isSuperBills, listClinicNums));
            }
            SerializableDictionary <long, PatAgingData> dictPatAgingData = new SerializableDictionary <long, PatAgingData>();
            string command   = "";
            string guarOrPat = "guar";

            if (isSinglePatient)
            {
                guarOrPat = "patient";
            }
            string whereAndClinNum = "";

            if (!listClinicNums.IsNullOrEmpty())
            {
                whereAndClinNum = $@"AND {guarOrPat}.ClinicNum IN ({string.Join(",",listClinicNums)})";
            }
            if (includeChanged || excludeIfUnsentProcs)
            {
                command = $@"SELECT {guarOrPat}.PatNum,{guarOrPat}.ClinicNum,MAX(procedurelog.ProcDate) MaxProcDate";
                if (excludeIfUnsentProcs)
                {
                    command += ",MAX(CASE WHEN insplan.IsMedical=1 THEN 0 ELSE COALESCE(claimproc.ProcNum,0) END)>0 HasUnsentProcs";
                }
                command += $@" FROM patient
					INNER JOIN patient guar ON guar.PatNum=patient.Guarantor
					INNER JOIN procedurelog ON procedurelog.PatNum = patient.PatNum "                    ;
                if (excludeIfUnsentProcs)
                {
                    command += $@"LEFT JOIN claimproc ON claimproc.ProcNum = procedurelog.ProcNum
						AND claimproc.NoBillIns=0
						AND claimproc.Status = {POut.Int((int)ClaimProcStatus.Estimate)}
						AND procedurelog.ProcDate > CURDATE()-INTERVAL 6 MONTH
					LEFT JOIN insplan ON insplan.PlanNum=claimproc.PlanNum "                    ;
                }
                command += $@"WHERE procedurelog.ProcFee > 0
					AND procedurelog.ProcStatus = {POut.Int((int)ProcStat.C)}
					{whereAndClinNum}
					GROUP BY {guarOrPat}.PatNum
					ORDER BY NULL"                    ;
                using (DataTable tableChangedAndUnsent = Db.GetTable(command)) {
                    foreach (DataRow row in tableChangedAndUnsent.Rows)
                    {
                        long patNum = PIn.Long(row["PatNum"].ToString());
                        if (!dictPatAgingData.ContainsKey(patNum))
                        {
                            dictPatAgingData[patNum] = new PatAgingData(PIn.Long(row["ClinicNum"].ToString()));
                        }
                        if (includeChanged)
                        {
                            dictPatAgingData[patNum].ListPatAgingTransactions
                            .Add(new PatAgingTransaction(PatAgingTransaction.TransactionTypes.Procedure, PIn.Date(row["MaxProcDate"].ToString())));
                        }
                        if (excludeIfUnsentProcs)
                        {
                            dictPatAgingData[patNum].HasUnsentProcs = PIn.Bool(row["HasUnsentProcs"].ToString());
                        }
                    }
                }
            }
            if (includeChanged)
            {
                command = $@"SELECT {guarOrPat}.PatNum,{guarOrPat}.ClinicNum,MAX(claimproc.DateCP) maxDateCP
					FROM claimproc
					INNER JOIN patient ON patient.PatNum = claimproc.PatNum
					INNER JOIN patient guar ON guar.PatNum=patient.Guarantor
					WHERE claimproc.InsPayAmt > 0
					{whereAndClinNum}
					GROUP BY {guarOrPat}.PatNum"                    ;
                using (DataTable tableMaxPayDate = Db.GetTable(command)) {
                    foreach (DataRow row in tableMaxPayDate.Rows)
                    {
                        long patNum = PIn.Long(row["PatNum"].ToString());
                        if (!dictPatAgingData.ContainsKey(patNum))
                        {
                            dictPatAgingData[patNum] = new PatAgingData(PIn.Long(row["ClinicNum"].ToString()));
                        }
                        dictPatAgingData[patNum].ListPatAgingTransactions
                        .Add(new PatAgingTransaction(PatAgingTransaction.TransactionTypes.ClaimProc, PIn.Date(row["maxDateCP"].ToString())));
                    }
                }
                command = $@"SELECT {guarOrPat}.PatNum,{guarOrPat}.ClinicNum,MAX(payplancharge.ChargeDate) maxDatePPC,
						MAX(payplancharge.SecDateTEntry) maxDatePPCSDTE
					FROM payplancharge
					INNER JOIN patient ON patient.PatNum = payplancharge.PatNum
					INNER JOIN patient guar ON guar.PatNum=patient.Guarantor
					INNER JOIN payplan ON payplan.PayPlanNum = payplancharge.PayPlanNum
						AND payplan.PlanNum = 0 "                                                                                                                                                                                                                                                                                                                                                                                            //don't want insurance payment plans to make patients appear in the billing list
                          + $@"WHERE payplancharge.Principal + payplancharge.Interest>0
					AND payplancharge.ChargeType = {(int)PayPlanChargeType.Debit} "
                                                                                                                                                                                                                                                                                                                                                                                                                                             //include all charges in the past or due 'PayPlanBillInAdvance' days into the future.
                          + $@"AND payplancharge.ChargeDate <= {POut.Date(DateTime.Today.AddDays(PrefC.GetDouble(PrefName.PayPlansBillInAdvanceDays)))}
					{whereAndClinNum}
					GROUP BY {guarOrPat}.PatNum"                    ;
                using (DataTable tableMaxPPCDate = Db.GetTable(command)) {
                    foreach (DataRow row in tableMaxPPCDate.Rows)
                    {
                        long patNum = PIn.Long(row["PatNum"].ToString());
                        if (!dictPatAgingData.ContainsKey(patNum))
                        {
                            dictPatAgingData[patNum] = new PatAgingData(PIn.Long(row["ClinicNum"].ToString()));
                        }
                        dictPatAgingData[patNum].ListPatAgingTransactions
                        .Add(new PatAgingTransaction(
                                 PatAgingTransaction.TransactionTypes.PayPlanCharge,
                                 PIn.Date(row["maxDatePPC"].ToString()),
                                 secDateTEntryTrans: PIn.Date(row["maxDatePPCSDTE"].ToString()))
                             );
                    }
                }
            }
            if (excludeInsPending)
            {
                command = $@"SELECT {guarOrPat}.PatNum,{guarOrPat}.ClinicNum
					FROM claim
					INNER JOIN patient ON patient.PatNum=claim.PatNum
					INNER JOIN patient guar ON guar.PatNum=patient.Guarantor
					WHERE claim.ClaimStatus IN ('U','H','W','S')
					AND claim.ClaimType IN ('P','S','Other')
					{whereAndClinNum}
					GROUP BY {guarOrPat}.PatNum"                    ;
                using (DataTable tableInsPending = Db.GetTable(command)) {
                    foreach (DataRow row in tableInsPending.Rows)
                    {
                        long patNum = PIn.Long(row["PatNum"].ToString());
                        if (!dictPatAgingData.ContainsKey(patNum))
                        {
                            dictPatAgingData[patNum] = new PatAgingData(PIn.Long(row["ClinicNum"].ToString()));
                        }
                        dictPatAgingData[patNum].HasPendingIns = true;
                    }
                }
            }
            DateTime dateAsOf = DateTime.Today;                               //used to determine when the balance on this date began

            if (PrefC.GetBool(PrefName.AgingCalculatedMonthlyInsteadOfDaily)) //if aging calculated monthly, use the last aging date instead of today
            {
                dateAsOf = PrefC.GetDate(PrefName.DateLastAging);
            }
            List <PatComm> listPatComms = new List <PatComm>();

            using (DataTable tableDateBalsBegan = Ledgers.GetDateBalanceBegan(null, dateAsOf, isSuperBills, listClinicNums)) {
                foreach (DataRow row in tableDateBalsBegan.Rows)
                {
                    long patNum = PIn.Long(row["PatNum"].ToString());
                    if (!dictPatAgingData.ContainsKey(patNum))
                    {
                        dictPatAgingData[patNum] = new PatAgingData(PIn.Long(row["ClinicNum"].ToString()));
                    }
                    dictPatAgingData[patNum].DateBalBegan = PIn.Date(row["DateAccountAge"].ToString());
                    dictPatAgingData[patNum].DateBalZero  = PIn.Date(row["DateZeroBal"].ToString());
                }
                listPatComms = Patients.GetPatComms(tableDateBalsBegan.Select().Select(x => PIn.Long(x["PatNum"].ToString())).ToList(), null);
            }
            foreach (PatComm pComm in listPatComms)
            {
                if (!dictPatAgingData.ContainsKey(pComm.PatNum))
                {
                    dictPatAgingData[pComm.PatNum] = new PatAgingData(pComm.ClinicNum);
                }
                dictPatAgingData[pComm.PatNum].PatComm = pComm;
            }
            return(dictPatAgingData);
        }
예제 #25
0
        public static DataTable GetPatientFormsTable(long patNum)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetTable(MethodBase.GetCurrentMethod(), patNum));
            }
            //DataConnection dcon=new DataConnection();
            DataTable table = new DataTable("");
            DataRow   row;

            //columns that start with lowercase are altered for display rather than being raw data.
            table.Columns.Add("date");
            table.Columns.Add("dateOnly", typeof(DateTime));           //to help with sorting
            table.Columns.Add("dateTime", typeof(DateTime));
            table.Columns.Add("description");
            table.Columns.Add("DocNum");
            table.Columns.Add("imageCat");
            table.Columns.Add("SheetNum");
            table.Columns.Add("showInTerminal");
            table.Columns.Add("time");
            table.Columns.Add("timeOnly", typeof(TimeSpan));           //to help with sorting
            //but we won't actually fill this table with rows until the very end.  It's more useful to use a List<> for now.
            List <DataRow> rows = new List <DataRow>();
            //sheet---------------------------------------------------------------------------------------
            string command = "SELECT DateTimeSheet,SheetNum,Description,ShowInTerminal "
                             + "FROM sheet WHERE IsDeleted=0 "
                             + "AND PatNum =" + POut.Long(patNum) + " "
                             + "AND (SheetType=" + POut.Long((int)SheetTypeEnum.PatientForm) + " OR SheetType=" + POut.Long((int)SheetTypeEnum.MedicalHistory);

            if (PrefC.GetBool(PrefName.PatientFormsShowConsent))
            {
                command += " OR SheetType=" + POut.Long((int)SheetTypeEnum.Consent);            //Show consent forms if pref is true.
            }
            command += ")";
            //+"ORDER BY ShowInTerminal";//DATE(DateTimeSheet),ShowInTerminal,TIME(DateTimeSheet)";
            DataTable rawSheet = Db.GetTable(command);
            DateTime  dateT;

            for (int i = 0; i < rawSheet.Rows.Count; i++)
            {
                row                = table.NewRow();
                dateT              = PIn.DateT(rawSheet.Rows[i]["DateTimeSheet"].ToString());
                row["date"]        = dateT.ToShortDateString();
                row["dateOnly"]    = dateT.Date;
                row["dateTime"]    = dateT;
                row["description"] = rawSheet.Rows[i]["Description"].ToString();
                row["DocNum"]      = "0";
                row["imageCat"]    = "";
                row["SheetNum"]    = rawSheet.Rows[i]["SheetNum"].ToString();
                if (rawSheet.Rows[i]["ShowInTerminal"].ToString() == "0")
                {
                    row["showInTerminal"] = "";
                }
                else
                {
                    row["showInTerminal"] = rawSheet.Rows[i]["ShowInTerminal"].ToString();
                }
                if (dateT.TimeOfDay != TimeSpan.Zero)
                {
                    row["time"] = dateT.ToString("h:mm") + dateT.ToString("%t").ToLower();
                }
                row["timeOnly"] = dateT.TimeOfDay;
                rows.Add(row);
            }
            //document---------------------------------------------------------------------------------------
            command = "SELECT DateCreated,DocCategory,DocNum,Description "
                      + "FROM document,definition "
                      + "WHERE document.DocCategory=definition.DefNum"
                      + " AND PatNum =" + POut.Long(patNum)
                      + " AND definition.ItemValue LIKE '%F%'";
            //+" ORDER BY DateCreated";
            DataTable rawDoc = Db.GetTable(command);
            long      docCat;

            for (int i = 0; i < rawDoc.Rows.Count; i++)
            {
                row                   = table.NewRow();
                dateT                 = PIn.DateT(rawDoc.Rows[i]["DateCreated"].ToString());
                row["date"]           = dateT.ToShortDateString();
                row["dateOnly"]       = dateT.Date;
                row["dateTime"]       = dateT;
                row["description"]    = rawDoc.Rows[i]["Description"].ToString();
                row["DocNum"]         = rawDoc.Rows[i]["DocNum"].ToString();
                docCat                = PIn.Long(rawDoc.Rows[i]["DocCategory"].ToString());
                row["imageCat"]       = Defs.GetName(DefCat.ImageCats, docCat);
                row["SheetNum"]       = "0";
                row["showInTerminal"] = "";
                if (dateT.TimeOfDay != TimeSpan.Zero)
                {
                    row["time"] = dateT.ToString("h:mm") + dateT.ToString("%t").ToLower();
                }
                row["timeOnly"] = dateT.TimeOfDay;
                rows.Add(row);
            }
            //Sorting
            for (int i = 0; i < rows.Count; i++)
            {
                table.Rows.Add(rows[i]);
            }
            DataView view = table.DefaultView;

            view.Sort = "dateOnly,showInTerminal,timeOnly";
            table     = view.ToTable();
            return(table);
        }
예제 #26
0
파일: X270.cs 프로젝트: kjb7749/testImport
        ///<summary>In progress.  Probably needs a different name.  Info must be validated first.
        ///Set dependent to the currently selected patient, compares dependent.PatNum to subscriber.PatNum to either contruct a subscriber based or dependent based benefit request.</summary>
        public static string GenerateMessageText(Clearinghouse clearinghouseClin, Carrier carrier, Provider billProv, Clinic clinic, InsPlan insPlan, Patient subscriber, InsSub insSub, Patient patForRequest)
        {
            bool          isSubscriberRequest = (subscriber.PatNum == patForRequest.PatNum);
            int           batchNum            = Clearinghouses.GetNextBatchNumber(clearinghouseClin);
            string        groupControlNumber  = batchNum.ToString();  //Must be unique within file.  We will use batchNum
            int           transactionNum      = 1;
            StringBuilder strb = new StringBuilder();

            //Interchange Control Header
            strb.Append("ISA*00*          *");            //ISA01,ISA02: 00 + 10 spaces
            if (IsEmdeonDental(clearinghouseClin))
            {
                strb.Append("00*" + Sout(clearinghouseClin.Password, 10, 10) + "*"   //ISA03,ISA04: 00 + emdeon password padded to 10 characters
                            + clearinghouseClin.ISA05 + "*"                          //ISA05: Sender ID type: ZZ=mutually defined. 30=TIN. Validated
                            + "316:" + Sout(clearinghouseClin.LoginID, 11, 11) + "*" //ISA06: Emdeon vendor number + username
                            + clearinghouseClin.ISA07 + "*"                          //ISA07: Receiver ID type: ZZ=mutually defined. 30=TIN. Validated
                            + Sout("EMDEONDENTAL", 15, 15) + "*");                   //ISA08: Receiver ID. Validated to make sure length is at least 2.
            }
            else
            {
                strb.Append("00*          *"                                 //ISA03,ISA04: 00 + 10 spaces
                            + clearinghouseClin.ISA05 + "*"                  //ISA05: Sender ID type: ZZ=mutually defined. 30=TIN. Validated
                            + X12Generator.GetISA06(clearinghouseClin) + "*" //ISA06: Sender ID(TIN). Or might be TIN of Open Dental
                            + clearinghouseClin.ISA07 + "*"                  //ISA07: Receiver ID type: ZZ=mutually defined. 30=TIN. Validated
                            + Sout(clearinghouseClin.ISA08, 15, 15) + "*");  //ISA08: Receiver ID. Validated to make sure length is at least 2.
            }
            strb.AppendLine(DateTime.Today.ToString("yyMMdd") + "*"          //ISA09: today's date
                            + DateTime.Now.ToString("HHmm") + "*"            //ISA10: current time
                            + "U*00401*"                                     //ISA11 and ISA12.
                                                                             //ISA13: interchange control number, right aligned:
                            + batchNum.ToString().PadLeft(9, '0') + "*"
                            + "0*"                                           //ISA14: no acknowledgment requested
                            + clearinghouseClin.ISA15 + "*"                  //ISA15: T=Test P=Production. Validated.
                            + ":~");                                         //ISA16: use ':'
            //Functional Group Header
            if (IsEmdeonDental(clearinghouseClin))
            {
                strb.Append("GS*HS*"                                        //GS01: HS for 270 benefit inquiry
                            + X12Generator.GetGS02(clearinghouseClin) + "*" //GS02: Senders Code. Sometimes Jordan Sparks.  Sometimes the sending clinic.
                            + Sout("EMDEONDENTAL", 15, 15) + "*");          //GS03: Application Receiver's Code
            }
            else
            {
                strb.Append("GS*HS*"                                        //GS01: HS for 270 benefit inquiry
                            + X12Generator.GetGS02(clearinghouseClin) + "*" //GS02: Senders Code. Sometimes Jordan Sparks.  Sometimes the sending clinic.
                            + Sout(clearinghouseClin.GS03, 15, 2) + "*");   //GS03: Application Receiver's Code
            }
            strb.AppendLine(DateTime.Today.ToString("yyyyMMdd") + "*"       //GS04: today's date
                            + DateTime.Now.ToString("HHmm") + "*"           //GS05: current time
                            + groupControlNumber + "*"                      //GS06: Group control number. Max length 9. No padding necessary.
                            + "X*"                                          //GS07: X
                            + "004010X092~");                               //GS08: Version
            //Beginning of transaction--------------------------------------------------------------------------------
            int seg = 0;                                                    //count segments for the ST-SE transaction

            //Transaction Set Header
            //ST02 Transact. control #. Must be unique within ISA
            seg++;
            strb.AppendLine("ST*270*"                                           //ST01
                            + transactionNum.ToString().PadLeft(4, '0') + "~"); //ST02
            seg++;
            strb.AppendLine("BHT*0022*13*"                                      //BHT02: 13=request
                            + transactionNum.ToString().PadLeft(4, '0') + "*"   //BHT03. Can be same as ST02
                            + DateTime.Now.ToString("yyyyMMdd") + "*"           //BHT04: Date
                            + DateTime.Now.ToString("HHmmss") + "~");           //BHT05: Time, BHT06: not used
            //HL Loops-----------------------------------------------------------------------------------------------
            int HLcount = 1;

            //2000A HL: Information Source--------------------------------------------------------------------------
            seg++;
            strb.AppendLine("HL*" + HLcount.ToString() + "*" //HL01: Heirarchical ID.  Here, it's always 1.
                            + "*"                            //HL02: No parent. Not used
                            + "20*"                          //HL03: Heirarchical level code. 20=Information source
                            + "1~");                         //HL04: Heirarchical child code. 1=child HL present
            //2100A NM1
            seg++;
            strb.AppendLine("NM1*PR*"                              //NM101: PR=Payer
                            + "2*"                                 //NM102: 2=Non person
                            + Sout(carrier.CarrierName, 35) + "*"  //NM103: Name Last.
                            + "****"                               //NM104-07 not used
                            + "PI*"                                //NM108: PI=PayorID
                            + Sout(carrier.ElectID, 80, 2) + "~"); //NM109: PayorID. Validated to be at least length of 2.
            HLcount++;
            //2000B HL: Information Receiver------------------------------------------------------------------------
            seg++;
            strb.AppendLine("HL*" + HLcount.ToString() + "*" //HL01: Heirarchical ID.  Here, it's always 2.
                            + "1*"                           //HL02: Heirarchical parent id number.  1 in this simple message.
                            + "21*"                          //HL03: Heirarchical level code. 21=Information receiver
                            + "1~");                         //HL04: Heirarchical child code. 1=child HL present
            seg++;
            //2100B NM1: Information Receiver Name
            strb.AppendLine("NM1*1P*"                                   //NM101: 1P=Provider
                            + (billProv.IsNotPerson?"2":"1") + "*"      //NM102: 1=person,2=non-person
                            + Sout(billProv.LName, 35) + "*"            //NM103: Last name
                            + Sout(billProv.FName, 25) + "*"            //NM104: First name
                            + Sout(billProv.MI, 25, 1) + "*"            //NM105: Middle name
                            + "*"                                       //NM106: not used
                            + "*"                                       //NM107: Name suffix. not used
                            + "XX*"                                     //NM108: ID code qualifier. 24=EIN. 34=SSN, XX=NPI
                            + Sout(billProv.NationalProvID, 80) + "~"); //NM109: ID code. NPI validated
            //2100B REF: Information Receiver ID
            if (IsEmdeonDental(clearinghouseClin) && IsDentiCalCarrier(carrier))
            {
                string        ref4aSegment            = "";
                Clearinghouse clearinghouseDentiCalHQ = Clearinghouses.GetFirstOrDefault(x => IsDentiCalClearinghouse(x), true);
                if (clearinghouseDentiCalHQ != null)
                {
                    Clearinghouse clearinghouseDentiCalClin = Clearinghouses.OverrideFields(clearinghouseDentiCalHQ, clearinghouseClin.ClinicNum);
                    if (clearinghouseDentiCalClin != null)
                    {
                        ref4aSegment = clearinghouseDentiCalClin.Password;
                    }
                }
                seg++;
                strb.Append("REF*4A*" + ref4aSegment + "~");
            }
            seg++;
            strb.Append("REF*");
            if (billProv.UsingTIN)
            {
                strb.Append("TJ*");                        //REF01: qualifier. TJ=Federal TIN
            }
            else                                           //SSN
            {
                strb.Append("SY*");                        //REF01: qualifier. SY=SSN
            }
            strb.AppendLine(Sout(billProv.SSN, 30) + "~"); //REF02: ID
            //2100B N3: Information Receiver Address
            seg++;
            if (PrefC.GetBool(PrefName.UseBillingAddressOnClaims))
            {
                strb.Append("N3*" + Sout(PrefC.GetString(PrefName.PracticeBillingAddress), 55));             //N301: Address
            }
            else if (clinic == null)
            {
                strb.Append("N3*" + Sout(PrefC.GetString(PrefName.PracticeAddress), 55));             //N301: Address
            }
            else
            {
                strb.Append("N3*" + Sout(clinic.Address, 55));             //N301: Address
            }
            if (PrefC.GetBool(PrefName.UseBillingAddressOnClaims))
            {
                if (PrefC.GetString(PrefName.PracticeBillingAddress2) == "")
                {
                    strb.AppendLine("~");
                }
                else
                {
                    //N302: Address2. Optional.
                    strb.AppendLine("*" + Sout(PrefC.GetString(PrefName.PracticeBillingAddress2), 55) + "~");
                }
            }
            else if (clinic == null)
            {
                if (PrefC.GetString(PrefName.PracticeAddress2) == "")
                {
                    strb.AppendLine("~");
                }
                else
                {
                    //N302: Address2. Optional.
                    strb.AppendLine("*" + Sout(PrefC.GetString(PrefName.PracticeAddress2), 55) + "~");
                }
            }
            else
            {
                if (clinic.Address2 == "")
                {
                    strb.AppendLine("~");
                }
                else
                {
                    //N302: Address2. Optional.
                    strb.AppendLine("*" + Sout(clinic.Address2, 55) + "~");
                }
            }
            //2100B N4: Information Receiver City/State/Zip
            seg++;
            if (PrefC.GetBool(PrefName.UseBillingAddressOnClaims))
            {
                strb.AppendLine("N4*" + Sout(PrefC.GetString(PrefName.PracticeBillingCity), 30) + "*"             //N401: City
                                + Sout(PrefC.GetString(PrefName.PracticeBillingST), 2) + "*"                      //N402: State
                                + Sout(PrefC.GetString(PrefName.PracticeBillingZip).Replace("-", ""), 15) + "~"); //N403: Zip
            }
            else if (clinic == null)
            {
                strb.AppendLine("N4*" + Sout(PrefC.GetString(PrefName.PracticeCity), 30) + "*"             //N401: City
                                + Sout(PrefC.GetString(PrefName.PracticeST), 2) + "*"                      //N402: State
                                + Sout(PrefC.GetString(PrefName.PracticeZip).Replace("-", ""), 15) + "~"); //N403: Zip
            }
            else
            {
                strb.AppendLine("N4*" + Sout(clinic.City, 30) + "*"             //N401: City
                                + Sout(clinic.State, 2) + "*"                   //N402: State
                                + Sout(clinic.Zip.Replace("-", ""), 15) + "~"); //N403: Zip
            }
            //2100B PRV: Information Receiver Provider Info
            seg++;
            //PRV*PE*ZZ*1223G0001X~
            strb.AppendLine("PRV*PE*"                                    //PRV01: Provider Code. PE=Performing.  There are many other choices.
                            + "ZZ*"                                      //PRV02: ZZ=Mutually defined = health care provider taxonomy code
                            + X12Generator.GetTaxonomy(billProv) + "~"); //PRV03: Specialty code
            HLcount++;
            //2000C HL: Subscriber-----------------------------------------------------------------------------------
            seg++;
            strb.AppendLine("HL*" + HLcount.ToString() + "*"    //HL01: Heirarchical ID.  Here, it's always 3.
                            + "2*"                              //HL02: Heirarchical parent id number.  2 in this simple message.
                            + "22*"                             //HL03: Heirarchical level code. 22=Subscriber
                            + (isSubscriberRequest?"0~":"1~")); //HL04: Heirarchical child code. 0=no child HL present (no dependent) else 1
            //2000C TRN: Subscriber Trace Number
            seg++;
            strb.AppendLine("TRN*1*"                     //TRN01: Trace Type Code.  1=Current Transaction Trace Numbers
                            + "1*"                       //TRN02: Trace Number.  We don't really have a good primary key yet.  Keep it simple. Use 1.
                            + "1" + billProv.SSN + "~"); //TRN03: Entity Identifier. First digit is 1=EIN.  Next 9 digits are EIN.  Length validated.
            //2100C NM1: Subscriber Name
            seg++;
            strb.AppendLine("NM1*IL*"                                                //NM101: IL=Insured or Subscriber
                            + "1*"                                                   //NM102: 1=Person
                            + Sout(subscriber.LName, 35) + "*"                       //NM103: LName
                            + Sout(subscriber.FName, 25) + "*"                       //NM104: FName
                            + Sout(subscriber.MiddleI, 25) + "*"                     //NM105: MiddleName
                            + "*"                                                    //NM106: not used
                            + "*"                                                    //NM107: suffix. Not present in Open Dental yet.
                            + "MI*"                                                  //NM108: MI=MemberID
                            + Sout(insSub.SubscriberID.Replace("-", ""), 80) + "~"); //NM109: Subscriber ID. Validated to be L>2.
            //2100C REF: Subscriber Additional Information.  Without this, old plans seem to be frequently returned.
            seg++;
            strb.AppendLine("REF*6P*"                            //REF01: 6P=GroupNumber
                            + Sout(insPlan.GroupNum, 30) + "~"); //REF02: Supplemental ID. Validated.
            //2100C DMG: Subscriber Demographic Information
            seg++;
            strb.AppendLine("DMG*D8*"                                           //DMG01: Date Time Period Qualifier.  D8=CCYYMMDD
                            + subscriber.Birthdate.ToString("yyyyMMdd") + "~"); //DMG02: Subscriber birthdate.  Validated
            //DMG03: Gender code.  Situational.  F or M.  Since this was left out in the example,
            //and since we don't want to send the wrong gender, we will not send this element.
            //2100C DTP: Subscriber Date.  Deduced through trial and error that this is required by EHG even though not by X12 specs.
            seg++;
            strb.AppendLine("DTP*307*"                                    //DTP01: Qualifier.  307=Eligibility
                            + "D8*"                                       //DTP02: Format Qualifier.
                            + DateTime.Today.ToString("yyyyMMdd") + "~"); //DTP03: Date
            //2000D HL: Dependent Level Hierarchical Level
            if (isSubscriberRequest)
            {
                //2110C EQ: Subscriber Eligibility or Benefit Enquiry Information
                //X12 documentation seems to say that we can loop this 99 times to request very specific benefits.
                //ClaimConnect wants to see either an EQ*30 for "an eligibility request", or an EQ*35 for "a general benefits request".
                //The director of vendor implementation at ClaimConnect has informed us that we should send an EQ*35 to get the full set of benefits.
                seg++;
                strb.AppendLine("EQ*35~"); //Dental Care
            }
            else                           //Dependent based request.
            {
                HLcount++;
                seg++;
                strb.AppendLine("HL*" + HLcount.ToString() + "*" //HL01: Heirarchical ID.
                                + (HLcount - 1).ToString() + "*" //HL02: Heirarchical parent id number.
                                + "23*"                          //HL03: Heirarchical level code. 23=Dependent
                                + "0~");                         //HL04: Heirarchical child code. 0=no child HL present (no dependent)
                //2000D TRN: Dependent Trace Number
                seg++;
                strb.AppendLine("TRN*1*"                     //TRN01: Trace Type Code.  1=Current Transaction Trace Numbers
                                + "1*"                       //TRN02: Trace Number.  We don't really have a good primary key yet.  Keep it simple. Use 1.
                                + "1" + billProv.SSN + "~"); //TRN03: Entity Identifier. First digit is 1=EIN.  Next 9 digits are EIN.  Length validated.
                //2100D NM1: Dependent Name
                seg++;
                strb.AppendLine("NM1*03*"                                 //NM101: 03=Dependent
                                + "1*"                                    //NM102: 1=Person
                                + Sout(patForRequest.LName, 35) + "*"     //NM103: Name Last or Organization Name
                                + Sout(patForRequest.FName, 25) + "*"     //NM104: Name First
                                + Sout(patForRequest.MiddleI, 25) + "~"); //NM105: Name Middle
                //2100D REF: Dependent Additional Identification
                seg++;
                strb.AppendLine("REF*6P*"                            //REF01: 6P=GroupNumber
                                + Sout(insPlan.GroupNum, 30) + "~"); //REF02: Supplemental ID. Validated.
                //2100D DMG: Dependent Demographic Information
                seg++;
                strb.AppendLine("DMG*D8*"                                              //DMG01: Date Time Period Qualifier.  D8=CCYYMMDD
                                + patForRequest.Birthdate.ToString("yyyyMMdd") + "~"); //DMG02: Dependent birthdate.  Validated
                //DMG03: Gender code.  Situational.  F or M.  Since this was left out in the example,
                //and since we don't want to send the wrong gender, we will not send this element.
                //2100D DTP: DEPENDENT Date.  Deduced through trial and error that this is required by EHG even though not by X12 specs.
                seg++;
                strb.AppendLine("DTP*307*"                                    //DTP01: Qualifier.  307=Eligibility
                                + "D8*"                                       //DTP02: Format Qualifier.
                                + DateTime.Today.ToString("yyyyMMdd") + "~"); //DTP03: Date
                seg++;
                strb.AppendLine("EQ*35~");                                    //Dental Care
            }
            //Transaction Trailer
            seg++;
            strb.AppendLine("SE*"
                            + seg.ToString() + "*" //SE01: Total segments, including ST & SE
                            + transactionNum.ToString().PadLeft(4, '0') + "~");
            //End of transaction--------------------------------------------------------------------------------------
            //Functional Group Trailer
            strb.AppendLine("GE*" + transactionNum.ToString() + "*"       //GE01: Number of transaction sets included
                            + groupControlNumber + "~");                  //GE02: Group Control number. Must be identical to GS06
            //Interchange Control Trailer
            strb.AppendLine("IEA*1*"                                      //IEA01: number of functional groups
                            + batchNum.ToString().PadLeft(9, '0') + "~"); //IEA02: Interchange control number
            return(strb.ToString());

            /*
             * return @"
             * ISA*00*          *00*          *30*AA0989922      *30*330989922      *030519*1608*U*00401*000012145*1*T*:~
             * GS*HS*AA0989922*330989922*20030519*1608*12145*X*004010X092~
             * ST*270*0001~
             * BHT*0022*13*ASX012145WEB*20030519*1608~
             * HL*1**20*1~
             * NM1*PR*2*Metlife*****PI*65978~
             * HL*2*1*21*1~
             * NM1*1P*1*PROVLAST*PROVFIRST****XX*1234567893~
             * REF*TJ*200384584~
             * N3*JUNIT ROAD~
             * N4*CHICAGO*IL*60602~
             * PRV*PE*ZZ*1223G0001X~
             * HL*3*2*22*0~
             * TRN*1*12145*1AA0989922~
             * NM1*IL*1*SUBLASTNAME*SUBFIRSTNAME****MI*123456789~
             * DMG*D8*19750323~
             * DTP*307*D8*20030519~
             * EQ*30~
             * SE*17*0001~
             * GE*1*12145~
             * IEA*1*000012145~";
             */

            //return "ISA*00*          *00*          *30*AA0989922      *30*330989922      *030519*1608*U*00401*000012145*1*T*:~GS*HS*AA0989922*330989922*20030519*1608*12145*X*004010X092~ST*270*0001~BHT*0022*13*ASX012145WEB*20030519*1608~HL*1**20*1~NM1*PR*2*Metlife*****PI*65978~HL*2*1*21*1~NM1*1P*1*PROVLAST*PROVFIRST****XX*1234567893~REF*TJ*200384584~N3*JUNIT ROAD~N4*CHICAGO*IL*60602~PRV*PE*ZZ*1223G0001X~HL*3*2*22*0~TRN*1*12145*1AA0989922~NM1*IL*1*SUBLASTNAME*SUBFIRSTNAME****MI*123456789~DMG*D8*19750323~DTP*307*D8*20030519~EQ*30~SE*17*0001~GE*1*12145~IEA*1*000012145~";
        }
예제 #27
0
        public static List <List <int> > GetProdInc(DateTime dateFrom, DateTime dateTo)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <List <List <int> > >(MethodBase.GetCurrentMethod(), dateFrom, dateTo));
            }
#if DEBUG
            _elapsedTimeProdInc = "";
            System.Diagnostics.Stopwatch stopWatch      = new System.Diagnostics.Stopwatch();
            System.Diagnostics.Stopwatch stopWatchTotal = new System.Diagnostics.Stopwatch();
            _elapsedTimeProdInc = "Elapsed time for GetProdInc:\r\n";
            stopWatch.Restart();
            stopWatchTotal.Restart();
#endif
            string command;
            command = @"SELECT procedurelog.ProcDate,
				SUM(procedurelog.ProcFee*(procedurelog.UnitQty+procedurelog.BaseUnits))-IFNULL(SUM(claimproc.WriteOff),0)
				FROM procedurelog
				LEFT JOIN claimproc ON procedurelog.ProcNum=claimproc.ProcNum
				AND claimproc.Status='7' /*only CapComplete writeoffs are subtracted here*/
				WHERE procedurelog.ProcStatus = '2'
				AND procedurelog.ProcDate >= "                 + POut.Date(dateFrom) + @"
				AND procedurelog.ProcDate <= "                 + POut.Date(dateTo) + @"
				GROUP BY MONTH(procedurelog.ProcDate)"                ;
            DataTable tableProduction = Db.GetTable(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProdInc += "tableProduction: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            command = @"SELECT AdjDate,
				SUM(AdjAmt)
				FROM adjustment
				WHERE AdjDate >= "                 + POut.Date(dateFrom) + @"
				AND AdjDate <= "                 + POut.Date(dateTo) + @"
				GROUP BY MONTH(AdjDate)"                ;
            DataTable tableAdj = Db.GetTable(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProdInc += "tableAdj: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            if (PrefC.GetBool(PrefName.ReportsPPOwriteoffDefaultToProcDate))             //use procdate
            {
                command = "SELECT "
                          + "claimproc.ProcDate,"
                          + "SUM(claimproc.WriteOff) "
                          + "FROM claimproc "
                          + "WHERE claimproc.ProcDate >= " + POut.Date(dateFrom) + " "
                          + "AND claimproc.ProcDate <= " + POut.Date(dateTo) + " "
                          + "AND (claimproc.Status=1 OR claimproc.Status=4 OR claimproc.Status=0) "              //received or supplemental or notreceived
                          + "GROUP BY MONTH(claimproc.ProcDate)";
            }
            else
            {
                command = "SELECT "
                          + "claimproc.DateCP,"
                          + "SUM(claimproc.WriteOff) "
                          + "FROM claimproc "
                          + "WHERE claimproc.DateCP >= " + POut.Date(dateFrom) + " "
                          + "AND claimproc.DateCP <= " + POut.Date(dateTo) + " "
                          + "AND (claimproc.Status=1 OR claimproc.Status=4) "             //Received or supplemental
                          + "GROUP BY MONTH(claimproc.DateCP)";
            }
            DataTable tableWriteoff = Db.GetTable(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProdInc += "tableWriteoff: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            command = "SELECT "
                      + "paysplit.DatePay,"
                      + "SUM(paysplit.SplitAmt) "
                      + "FROM paysplit "
                      + "WHERE paysplit.IsDiscount=0 "
                      + "AND paysplit.DatePay >= " + POut.Date(dateFrom) + " "
                      + "AND paysplit.DatePay <= " + POut.Date(dateTo) + " "
                      + "GROUP BY MONTH(paysplit.DatePay)";
            DataTable tablePay = Db.GetTable(command);
#if DEBUG
            stopWatch.Stop();
            _elapsedTimeProdInc += "tablePay: " + stopWatch.Elapsed.ToString() + "\r\n";
            stopWatch.Restart();
#endif
            command = "SELECT claimpayment.CheckDate,SUM(claimproc.InsPayamt) "
                      + "FROM claimpayment,claimproc WHERE "
                      + "claimproc.ClaimPaymentNum = claimpayment.ClaimPaymentNum "
                      + "AND claimpayment.CheckDate >= " + POut.Date(dateFrom) + " "
                      + "AND claimpayment.CheckDate <= " + POut.Date(dateTo) + " "
                      + " GROUP BY claimpayment.CheckDate ORDER BY checkdate";
            DataTable tableIns = Db.GetTable(command);
#if DEBUG
            stopWatch.Stop();
            stopWatchTotal.Stop();
            _elapsedTimeProdInc += "tableIns: " + stopWatch.Elapsed.ToString() + "\r\n";
            _elapsedTimeProdInc += "Total: " + stopWatchTotal.Elapsed.ToString();
            if (_showElapsedTimesForDebug)
            {
                System.Windows.Forms.MessageBox.Show(_elapsedTimeProdInc);
            }
#endif
            //production--------------------------------------------------------------------
            List <int> listInt;
            listInt = new List <int>();
            for (int i = 0; i < 12; i++)
            {
                decimal  prod        = 0;
                decimal  adjust      = 0;
                decimal  inswriteoff = 0;
                DateTime datePeriod  = dateFrom.AddMonths(i);             //only the month and year are important
                for (int j = 0; j < tableProduction.Rows.Count; j++)
                {
                    if (datePeriod.Year == PIn.Date(tableProduction.Rows[j][0].ToString()).Year &&
                        datePeriod.Month == PIn.Date(tableProduction.Rows[j][0].ToString()).Month)
                    {
                        prod += PIn.Decimal(tableProduction.Rows[j][1].ToString());
                    }
                }
                for (int j = 0; j < tableAdj.Rows.Count; j++)
                {
                    if (datePeriod.Year == PIn.Date(tableAdj.Rows[j][0].ToString()).Year &&
                        datePeriod.Month == PIn.Date(tableAdj.Rows[j][0].ToString()).Month)
                    {
                        adjust += PIn.Decimal(tableAdj.Rows[j][1].ToString());
                    }
                }
                for (int j = 0; j < tableWriteoff.Rows.Count; j++)
                {
                    if (datePeriod.Year == PIn.Date(tableWriteoff.Rows[j][0].ToString()).Year &&
                        datePeriod.Month == PIn.Date(tableWriteoff.Rows[j][0].ToString()).Month)
                    {
                        inswriteoff += PIn.Decimal(tableWriteoff.Rows[j][1].ToString());
                    }
                }
                listInt.Add((int)(prod + adjust - inswriteoff));
            }
            List <List <int> > retVal = new List <List <int> >();
            retVal.Add(listInt);
            //income----------------------------------------------------------------------
            listInt = new List <int>();
            for (int i = 0; i < 12; i++)
            {
                decimal  ptincome   = 0;
                decimal  insincome  = 0;
                DateTime datePeriod = dateFrom.AddMonths(i);              //only the month and year are important
                for (int j = 0; j < tablePay.Rows.Count; j++)
                {
                    if (datePeriod.Year == PIn.Date(tablePay.Rows[j][0].ToString()).Year &&
                        datePeriod.Month == PIn.Date(tablePay.Rows[j][0].ToString()).Month)
                    {
                        ptincome += PIn.Decimal(tablePay.Rows[j][1].ToString());
                    }
                }
                for (int j = 0; j < tableIns.Rows.Count; j++)           //
                {
                    if (datePeriod.Year == PIn.Date(tableIns.Rows[j][0].ToString()).Year &&
                        datePeriod.Month == PIn.Date(tableIns.Rows[j][0].ToString()).Month)
                    {
                        insincome += PIn.Decimal(tableIns.Rows[j][1].ToString());
                    }
                }
                listInt.Add((int)(ptincome + insincome));
            }
            retVal.Add(listInt);
            return(retVal);
        }
예제 #28
0
파일: X270.cs 프로젝트: kjb7749/testImport
        public static string Validate(Clearinghouse clearinghouseClin, Carrier carrier, Provider billProv, Clinic clinic, InsPlan insPlan, Patient subscriber, InsSub insSub, Patient patForRequest)
        {
            StringBuilder strb = new StringBuilder();

            X12Validate.ISA(clearinghouseClin, strb);
            X12Validate.Carrier(carrier, strb);
            if (carrier.ElectID.Length < 2)
            {
                if (strb.Length != 0)
                {
                    strb.Append(",");
                }
                strb.Append("Electronic ID");
            }
            if (billProv.SSN.Length != 9)
            {
                if (strb.Length != 0)
                {
                    strb.Append(",");
                }
                strb.Append("Prov TIN 9 digits");
            }
            X12Validate.BillProv(billProv, strb);
            if (PrefC.GetBool(PrefName.UseBillingAddressOnClaims))
            {
                X12Validate.BillingAddress(strb);
            }
            else if (clinic == null)
            {
                X12Validate.PracticeAddress(strb);
            }
            else
            {
                X12Validate.Clinic(clinic, strb);
            }
            if (insSub.SubscriberID.Length < 2)
            {
                if (strb.Length != 0)
                {
                    strb.Append(",");
                }
                strb.Append("SubscriberID");
            }
            if (subscriber.Birthdate.Year < 1880)
            {
                if (strb.Length != 0)
                {
                    strb.Append(",");
                }
                strb.Append("Subscriber Birthdate");
            }
            if (patForRequest.PatNum != subscriber.PatNum)           //Dependent validation.
            {
                if (patForRequest.Birthdate.Year < 1880)             //Dependent level validation.
                {
                    if (strb.Length != 0)
                    {
                        strb.Append(",");
                    }
                    strb.Append("Dependent Birthdate");
                }
            }
            ElectID eID = ElectIDs.GetID(carrier.ElectID);
            //Medicaid uses the patient First/Last/DOB to get benefits, not group number, so skip this validation if this is medicaid
            bool isMedicaid = (eID != null && eID.IsMedicaid) || carrier.CarrierName.ToLower().Contains("medicaid");

            if (!isMedicaid)
            {
                if (insPlan.GroupNum == "")
                {
                    if (strb.Length != 0)
                    {
                        strb.Append(",");
                    }
                    strb.Append("Group Number");
                }
            }
            //Darien at Dentalxchange helped us resolve one issue where the Group Number included a dash and was failing.
            //The fix suggested by Darien was to only include the numbers before the dash...  See task #705773
            if (IsClaimConnect(clearinghouseClin) && insPlan.GroupNum.Contains("-"))
            {
                if (strb.Length != 0)
                {
                    strb.Append(",");
                }
                strb.Append("Group Number: Only include the group number prior to the '-'");
            }
            return(strb.ToString());
        }
예제 #29
0
        private static void MakeCommlog(Patient pat, string phoneNumber, int statusCode)
        {
            string commText = "";

            //Status code meanings:
            //		-100: Patient had no phone number
            //		-200: Patient can't text and had no email
            //		2XX: Successfully sent message
            //		422: Message has already been sent for patient
            //		Anything else: Failure of some sort.
            switch (statusCode / 100)           //Get general http status codes e.g. -100=-1, 203=2
            {
            case -1:                            //Failure, no phone number
                commText = Lans.g("Podium", "Podium review invitation request failed because there was no phone number.  Error code:") + " " + statusCode;
                break;

            case -2:                            //Failure, no email
                commText = Lans.g("Podium", "Podium review invitation request failed because the patient doesn't accept texts "
                                  + "and there was no email address.  Error code:") + " " + statusCode;
                break;

            case 2:                     //Success https://httpstatusdogs.com/200-ok
                commText = Lans.g("Podium", "Podium review invitation request successfully sent.");
                break;

            case 4:                     //Client side communication failure https://httpstatusdogs.com/400-bad-request
                if (statusCode == 422)  //422 is Unprocessable Entity, which is sent in this case when a phone number has received an invite already.
                {
                    commText = Lans.g("Podium", "The request failed because an identical request was previously sent.");
                }
                else
                {
                    commText = Lans.g("Podium", "The request failed to reach Podium with error code:") + " " + statusCode;
                }
                break;

            case 5:                     //Server side internal failure. https://httpstatusdogs.com/500-internal-server-error
                commText = Lans.g("Podium", "The request was rejected by the Podium server with error code:") + " " + statusCode;
                break;

            default:                            //General Failure
                commText = Lans.g("Podium", "The request failed to send with error code:") + " " + statusCode;
                break;
            }
            if (!string.IsNullOrEmpty(commText))
            {
                commText += "\r\n";
            }
            commText += Lans.g("Podium", "The information sent in the request was") + ": \r\n"
                        + Lans.g("Podium", "First name") + ": \"" + pat.FName + "\", "
                        + Lans.g("Podium", "Last name") + ": \"" + pat.LName + "\", "
                        + Lans.g("Podium", "Email") + ": \"" + pat.Email + "\"";
            if (phoneNumber != "")           //If "successful".
            {
                commText += ", " + Lans.g("Podium", "Phone number") + ": \"" + phoneNumber + "\"";
            }
            else
            {
                string        wirelessPhone = new string(pat.WirelessPhone.Where(x => char.IsDigit(x)).ToArray());
                string        homePhone = new string(pat.HmPhone.Where(x => char.IsDigit(x)).ToArray());
                List <string> phonesTried = new List <string> {
                    wirelessPhone, homePhone
                }.FindAll(x => x != "");
                string phoneNumbersTried = ", " + Lans.g("Podium", "No valid phone number found.");
                if (pat.TxtMsgOk == YN.No || (pat.TxtMsgOk == YN.Unknown && PrefC.GetBool(PrefName.TextMsgOkStatusTreatAsNo)))             //Used email
                {
                    phoneNumbersTried = "";
                }
                else if (phonesTried.Count > 0)
                {
                    phoneNumbersTried = ", " + Lans.g("Podium", "Phone numbers tried") + ": " + string.Join(", ", phonesTried);
                }
                commText += phoneNumbersTried;
            }
            long    programNum = Programs.GetProgramNum(ProgramName.Podium);
            Commlog commlogCur = new Commlog();

            commlogCur.CommDateTime   = DateTime.Now;
            commlogCur.DateTimeEnd    = DateTime.Now;
            commlogCur.PatNum         = pat.PatNum;
            commlogCur.UserNum        = 0;   //run from server, no valid CurUser
            commlogCur.CommSource     = CommItemSource.ProgramLink;
            commlogCur.ProgramNum     = programNum;
            commlogCur.CommType       = Commlogs.GetTypeAuto(CommItemTypeAuto.MISC);
            commlogCur.Note           = commText;
            commlogCur.Mode_          = CommItemMode.Text;
            commlogCur.SentOrReceived = CommSentOrReceived.Sent;
            Commlogs.Insert(commlogCur);
        }
예제 #30
0
        ///<summary>For orderBy, use 0 for BillingType and 1 for PatientName.</summary>
        public static DataTable GetBilling(bool isSent, int orderBy, DateTime dateFrom, DateTime dateTo, List <long> clinicNums)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetTable(MethodBase.GetCurrentMethod(), isSent, orderBy, dateFrom, dateTo, clinicNums));
            }
            DataTable table = new DataTable();
            DataRow   row;

            //columns that start with lowercase are altered for display rather than being raw data.
            table.Columns.Add("amountDue");
            table.Columns.Add("balTotal");
            table.Columns.Add("billingType");
            table.Columns.Add("insEst");
            table.Columns.Add("IsSent");
            table.Columns.Add("lastStatement");
            table.Columns.Add("mode");
            table.Columns.Add("name");
            table.Columns.Add("PatNum");
            table.Columns.Add("payPlanDue");
            table.Columns.Add("StatementNum");
            table.Columns.Add("SuperFamily");
            string command = "SELECT patient.BalTotal,BillingType,FName,patient.InsEst,statement.IsSent,"
                             + "IFNULL(MAX(s2.DateSent)," + POut.Date(DateTime.MinValue) + ") LastStatement,"
                             + "LName,MiddleI,statement.Mode_,PayPlanDue,Preferred,"
                             + "statement.PatNum,statement.StatementNum,statement.SuperFamily "
                             + "FROM statement "
                             + "LEFT JOIN patient ON statement.PatNum=patient.PatNum "
                             + "LEFT JOIN statement s2 ON s2.PatNum=patient.PatNum "
                             + "AND s2.IsSent=1 ";

            if (PrefC.GetBool(PrefName.BillingIgnoreInPerson))
            {
                command += "AND s2.Mode_ !=1 ";
            }
            if (orderBy == 0)          //BillingType
            {
                command += "LEFT JOIN definition ON patient.BillingType=definition.DefNum ";
            }
            command += "WHERE statement.IsSent=" + POut.Bool(isSent) + " ";
            //if(dateFrom.Year>1800){
            command += "AND statement.DateSent>=" + POut.Date(dateFrom) + " ";      //greater than midnight this morning
            //}
            //if(dateFrom.Year>1800){
            command += "AND statement.DateSent<" + POut.Date(dateTo.AddDays(1)) + " ";      //less than midnight tonight
            //}
            if (clinicNums.Count > 0)
            {
                command += "AND patient.ClinicNum IN (" + string.Join(",", clinicNums) + ") ";
            }
            command += "GROUP BY patient.BalTotal,BillingType,FName,patient.InsEst,statement.IsSent,"
                       + "LName,MiddleI,statement.Mode_,PayPlanDue,Preferred,"
                       + "statement.PatNum,statement.StatementNum,statement.SuperFamily ";
            if (orderBy == 0)          //BillingType
            {
                command += "ORDER BY definition.ItemOrder,LName,FName,MiddleI,PayPlanDue";
            }
            else
            {
                command += "ORDER BY LName,FName";
            }
            DataTable      rawTable = Db.GetTable(command);
            double         balTotal;
            double         insEst;
            double         payPlanDue;
            DateTime       lastStatement;
            List <Patient> listFamilyGuarantors;

            foreach (DataRow rawRow in rawTable.Rows)
            {
                row = table.NewRow();
                if (rawRow["SuperFamily"].ToString() == "0")               //not a super statement, just get bal info from guarantor
                {
                    balTotal   = PIn.Double(rawRow["BalTotal"].ToString());
                    insEst     = PIn.Double(rawRow["InsEst"].ToString());
                    payPlanDue = PIn.Double(rawRow["PayPlanDue"].ToString());
                }
                else                  //super statement, add all guar positive balances to get bal total for super family
                {
                    listFamilyGuarantors = Patients.GetSuperFamilyGuarantors(PIn.Long(rawRow["SuperFamily"].ToString())).FindAll(x => x.HasSuperBilling);
                    //exclude fams with neg balances in the total for super family stmts (per Nathan 5/25/2016)
                    if (PrefC.GetBool(PrefName.BalancesDontSubtractIns))
                    {
                        listFamilyGuarantors = listFamilyGuarantors.FindAll(x => x.BalTotal > 0);
                        insEst = 0;
                    }
                    else
                    {
                        listFamilyGuarantors = listFamilyGuarantors.FindAll(x => (x.BalTotal - x.InsEst) > 0);
                        insEst = listFamilyGuarantors.Sum(x => x.InsEst);
                    }
                    balTotal   = listFamilyGuarantors.Sum(x => x.BalTotal);
                    payPlanDue = listFamilyGuarantors.Sum(x => x.PayPlanDue);
                }
                row["amountDue"]   = (balTotal - insEst).ToString("F");
                row["balTotal"]    = balTotal.ToString("F");;
                row["billingType"] = Defs.GetName(DefCat.BillingTypes, PIn.Long(rawRow["BillingType"].ToString()));
                if (insEst == 0)
                {
                    row["insEst"] = "";
                }
                else
                {
                    row["insEst"] = insEst.ToString("F");
                }
                row["IsSent"] = rawRow["IsSent"].ToString();
                lastStatement = PIn.Date(rawRow["LastStatement"].ToString());
                if (lastStatement.Year < 1880)
                {
                    row["lastStatement"] = "";
                }
                else
                {
                    row["lastStatement"] = lastStatement.ToShortDateString();
                }
                row["mode"]   = Lans.g("enumStatementMode", ((StatementMode)PIn.Int(rawRow["Mode_"].ToString())).ToString());
                row["name"]   = Patients.GetNameLF(rawRow["LName"].ToString(), rawRow["FName"].ToString(), rawRow["Preferred"].ToString(), rawRow["MiddleI"].ToString());
                row["PatNum"] = rawRow["PatNum"].ToString();
                if (payPlanDue == 0)
                {
                    row["payPlanDue"] = "";
                }
                else
                {
                    row["payPlanDue"] = payPlanDue.ToString("F");
                }
                row["StatementNum"] = rawRow["StatementNum"].ToString();
                row["SuperFamily"]  = rawRow["SuperFamily"].ToString();
                table.Rows.Add(row);
            }
            return(table);
        }