Esempio n. 1
0
        ///<summary>Only one dimension to the list for now.</summary>
        public static List <List <int> > GetAR(DateTime dateFrom, DateTime dateTo, List <DashboardAR> listDashAR)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <List <List <int> > >(MethodBase.GetCurrentMethod(), dateFrom, dateTo, listDashAR));
            }
            //assumes that dateFrom is the first of the month and that there are 12 periods
            //listDashAR may be empty, in which case, this routine will take about 18 seconds, but the user was warned.
            //listDashAR may also me incomplete, especially the most recent month(s).
            string     command;
            List <int> listInt;

            listInt = new List <int>();
            bool agingWasRun = false;

            for (int i = 0; i < 12; i++)
            {
                DateTime    dateLastOfMonth = dateFrom.AddMonths(i + 1).AddDays(-1);
                DashboardAR dash            = null;
                for (int d = 0; d < listDashAR.Count; d++)
                {
                    if (listDashAR[d].DateCalc != dateLastOfMonth)
                    {
                        continue;
                    }
                    dash = listDashAR[d];
                }
                if (dash != null)               //we found a DashboardAR object from the database for this month, so use it.
                {
                    listInt.Add((int)dash.BalTotal);
                    continue;
                }
                agingWasRun = true;
                //run historical aging on all patients based on the date entered.
                Ledgers.ComputeAging(0, dateLastOfMonth, true);
                command = @"SELECT SUM(Bal_0_30+Bal_31_60+Bal_61_90+BalOver90),SUM(InsEst) FROM patient";
                DataTable table = Db.GetTable(command);
                dash          = new DashboardAR();
                dash.DateCalc = dateLastOfMonth;
                dash.BalTotal = PIn.Double(table.Rows[0][0].ToString());
                dash.InsEst   = PIn.Double(table.Rows[0][1].ToString());
                DashboardARs.Insert(dash);                //save it to the db for later.
                listInt.Add((int)dash.BalTotal);          //and also use it now.
            }
            if (agingWasRun)
            {
                Ledgers.RunAging();                //set aging back to normal
            }
            List <List <int> > retVal = new List <List <int> >();

            retVal.Add(listInt);
            return(retVal);
        }
Esempio n. 2
0
        ///<summary>Returns all DashbaordAR(s) for the given time period. Caution, this will run aging and calculate a/r if a month within the given range is missing.
        ///This can take several seconds per month missing.</summary>
        public static List <DashboardAR> GetAR(DateTime dateFrom, DateTime dateTo, List <DashboardAR> listDashAR)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetObject <List <DashboardAR> >(MethodBase.GetCurrentMethod(), dateFrom, dateTo, listDashAR));
            }
            //assumes that dateFrom is the first of the month.
            string             command;
            List <DashboardAR> listRet = new List <DashboardAR>();

#if DEBUG
            _elapsedTimeAR = "";
            System.Diagnostics.Stopwatch stopWatch      = new System.Diagnostics.Stopwatch();
            System.Diagnostics.Stopwatch stopWatchTotal = new System.Diagnostics.Stopwatch();
            _elapsedTimeAR = "Elapsed time for GetAR:\r\n";
            stopWatchTotal.Start();
#endif
            int months = 0;
            while (dateTo >= dateFrom.AddMonths(months))             //calculate the number of months between the two dates.
            {
                months++;
            }
            for (int i = 0; i < months; i++)
            {
                DateTime    dateLastOfMonth = dateFrom.AddMonths(i + 1).AddDays(-1);
                DashboardAR dash            = null;
                for (int d = 0; d < listDashAR.Count; d++)
                {
                    if (listDashAR[d].DateCalc != dateLastOfMonth)
                    {
                        continue;
                    }
                    dash = listDashAR[d];
                }
                if (dash != null)               //we found a DashboardAR object from the database for this month, so use it.
                {
                    listRet.Add(dash);
                    continue;
                }
#if DEBUG
                stopWatch.Restart();
#endif
                //run historical aging on all patients based on the date entered.
                command = "SELECT SUM(Bal_0_30+Bal_31_60+Bal_61_90+BalOver90),SUM(InsEst) "
                          + "FROM (" + Ledgers.GetAgingQueryString(dateLastOfMonth, isHistoric: true) + ") guarBals";
                DataTable table = ReportsComplex.RunFuncOnReportServer(() => Db.GetTable(command));
#if DEBUG
                stopWatch.Stop();
                _elapsedTimeAR += "Aging using Ledgers.GetHistoricAgingQueryString() #" + i + " : " + stopWatch.Elapsed.ToString() + "\r\n";
#endif
                dash          = new DashboardAR();
                dash.DateCalc = dateLastOfMonth;
                dash.BalTotal = PIn.Double(table.Rows[0][0].ToString());
                dash.InsEst   = PIn.Double(table.Rows[0][1].ToString());
                DashboardARs.Insert(dash);                                                   //save it to the db for later.
                if (!string.IsNullOrEmpty(PrefC.ReportingServer.Server))                     //only attempt to insert into the reporting server if the reporting server is set up.
                {
                    ReportsComplex.RunFuncOnReportServer(() => (DashboardARs.Insert(dash))); //save it to the db for later.
                }
                listRet.Add(dash);                                                           //and also use it now.
            }
#if DEBUG
            stopWatchTotal.Stop();
            _elapsedTimeAR += "Total: " + stopWatchTotal.Elapsed.ToString();
            if (_showElapsedTimesForDebug)
            {
                System.Windows.Forms.MessageBox.Show(_elapsedTimeAR);
            }
#endif
            return(listRet);
        }
Esempio n. 3
0
        public static DataTable GetUnearnedAllocationData(List <long> listClinicNums, List <long> listProvNums,
                                                          List <long> listUnearnedTypeNums, bool isExcludeNetZeroUnearned)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetTable(MethodBase.GetCurrentMethod(), listClinicNums, listProvNums, listUnearnedTypeNums, isExcludeNetZeroUnearned));
            }
            //get all families that have an unallocated unearned balance.
            //from those, remove families that have not had procedures charted/completed after the unearned amount.

            //All families
            //DatePay = the earliest date of unallocated unearned.
            //Unallocated Amt = the total unallocated amt for the patient.
            string command = @"
				SELECT patient.Guarantor, MIN(paysplit.DatePay) DatePay, SUM(COALESCE(paysplit.SplitAmt,0)) + SUM(COALESCE(alloc.AllocAmt,0)) UnallocAmt
				FROM paysplit
				LEFT JOIN (
					SELECT paysplit.FSplitNum,SUM(paysplit.SplitAmt) AllocAmt
					FROM paysplit
					WHERE paysplit.FSplitNum != 0 
					GROUP BY paysplit.FSplitNum
				)alloc ON paysplit.SplitNum = alloc.FSplitNum
				INNER JOIN patient ON patient.PatNum = paysplit.PatNum "                ;

            if (listClinicNums.Count > 0 || listProvNums.Count > 0)
            {
                command += @"
					INNER JOIN patient guar ON guar.PatNum = patient.Guarantor "                    ;
                if (listClinicNums.Count > 0)
                {
                    command += @"
					AND guar.ClinicNum IN ("                     + string.Join(",", listClinicNums.Select(x => POut.Long(x))) + ") ";
                }
                if (listProvNums.Count > 0)
                {
                    command += @"
					AND guar.PriProv IN ("                     + string.Join(",", listProvNums.Select(x => POut.Long(x))) + ") ";
                }
            }
            command += @"
				WHERE paysplit.UnearnedType != 0 "                ;
            if (listUnearnedTypeNums.Count > 0)
            {
                command += @"
					AND paysplit.UnearnedType IN ("                     + string.Join(",", listUnearnedTypeNums.Select(x => POut.Long(x))) + ") ";
            }
            command += @"
				AND paysplit.FSplitNum = 0
				AND (ABS(paysplit.SplitAmt + alloc.AllocAmt) > 0.005 OR alloc.AllocAmt IS NULL) 
				GROUP BY patient.Guarantor "                ;
            if (isExcludeNetZeroUnearned)
            {
                command += @"
				HAVING ABS(UnallocAmt) > 0.005 "                ;
            }
            //one row per family
            DataTable   tableUnallocatedUnearned = ReportsComplex.RunFuncOnReportServer(() => Db.GetTable(command));
            List <long> listGuarantors           = tableUnallocatedUnearned.Rows.OfType <DataRow>().Select(x => PIn.Long(x["Guarantor"].ToString())).ToList();
            //all procedures for the families that have not been explicitly paid off.
            //Key: GuarantorNum | Val:ListRemainingProcsForFam
            List <UnearnedProc> listRemProcs = ReportsComplex.RunFuncOnReportServer(() => Procedures.GetRemainingProcsForFamilies(listGuarantors));
            Dictionary <long, List <UnearnedProc> > dictFamRemainingProcs = listRemProcs.GroupBy(x => x.GuarNum)
                                                                            .ToDictionary(x => x.Key, y => y.ToList());
            Dictionary <long, double> dictFamilyBalances = ReportsComplex.RunFuncOnReportServer(() => Ledgers.GetBalancesForFamilies(listGuarantors));
            Dictionary <long, string> dictPatNames       = ReportsComplex.RunFuncOnReportServer(() =>
                                                                                                Patients.GetPatientNames(Patients.GetAllFamilyPatNums(listGuarantors)));
            List <ProcedureCode> listProcCodes = ReportsComplex.RunFuncOnReportServer(() => ProcedureCodes.GetAllCodes());
            DataTable            retVal        = new DataTable();

            retVal.Columns.Add("Guar");
            retVal.Columns.Add("FamBal");
            retVal.Columns.Add("FamUnearned");
            retVal.Columns.Add("FamRemAmt");
            retVal.Columns.Add("Patient");
            retVal.Columns.Add("Code");
            retVal.Columns.Add("Date");
            retVal.Columns.Add("Fee");
            retVal.Columns.Add("RemAmt");
            foreach (DataRow guarRowCur in tableUnallocatedUnearned.Rows)
            {
                long                guarNum          = PIn.Long(guarRowCur["Guarantor"].ToString());
                DateTime            dateFirstUnalloc = PIn.Date(guarRowCur["DatePay"].ToString());
                double              unallocAmt       = PIn.Double(guarRowCur["UnallocAmt"].ToString());
                List <UnearnedProc> listUnearnedProcsForGuar;
                if (!dictFamRemainingProcs.TryGetValue(guarNum, out listUnearnedProcsForGuar))
                {
                    continue;                    //This family does not have any procedures that need to have money allocated to.
                }
                listUnearnedProcsForGuar = listUnearnedProcsForGuar.Where(x => x.Proc.ProcDate >= dateFirstUnalloc).OrderBy(x => x.Proc.ProcDate).ToList();
                if (listUnearnedProcsForGuar.Count == 0)
                {
                    continue;                    //We only want to show families where the procedure was completed after the unallocated prepayment.
                }
                decimal famRemAmt = listUnearnedProcsForGuar.Sum(x => x.UnallocatedAmt);
                DataRow guarRow   = retVal.NewRow();
                string  guarName;
                double  famBal;
                dictPatNames.TryGetValue(guarNum, out guarName);
                dictFamilyBalances.TryGetValue(guarNum, out famBal);
                guarRow["Guar"]        = guarName;
                guarRow["FamBal"]      = famBal.ToString("f");
                guarRow["FamUnearned"] = unallocAmt.ToString("f");
                guarRow["FamRemAmt"]   = famRemAmt.ToString("f");
                retVal.Rows.Add(guarRow);
                foreach (UnearnedProc unearnedProc in listUnearnedProcsForGuar)
                {
                    DataRow newRow = retVal.NewRow();
                    dictPatNames.TryGetValue(guarNum, out guarName);
                    string patName;
                    if (dictPatNames.TryGetValue(unearnedProc.Proc.PatNum, out patName))
                    {
                        newRow["Patient"] = patName;
                    }
                    newRow["Code"]   = ProcedureCodes.GetStringProcCode(unearnedProc.Proc.CodeNum, listProcCodes);
                    newRow["Date"]   = unearnedProc.Proc.ProcDate.ToShortDateString();
                    newRow["Fee"]    = (unearnedProc.Proc.ProcFee * (unearnedProc.Proc.UnitQty + unearnedProc.Proc.BaseUnits)).ToString("f");
                    newRow["RemAmt"] = unearnedProc.UnallocatedAmt.ToString("f");
                    retVal.Rows.Add(newRow);
                }
            }
            return(retVal);
        }
Esempio n. 4
0
        public static DataTable GetNetUnearnedData(List <long> listClinicNums, List <long> listProvNums,
                                                   List <long> listUnearnedTypeNums, bool isExcludeNetZero)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetTable(MethodBase.GetCurrentMethod(), listClinicNums, listProvNums, listUnearnedTypeNums, isExcludeNetZero));
            }
            //show all families where unearned income was collected and no unallocated procedures exist.
            /*All families with unallocated paysplits*/
            DataTable retVal = new DataTable();

            retVal.Columns.Add("PatientName");
            retVal.Columns.Add("GuarantorName");
            retVal.Columns.Add("PatUnearnedAmt");
            retVal.Columns.Add("FamBal");
            string command = @"
			SELECT patient.Guarantor, paysplit.PatNum, patient.FName, patient.LName,
			guar.FName GuarF, guar.LName GuarL, 
			SUM(IFNULL(paysplit.SplitAmt,0)) + SUM(IFNULL(alloc.AllocAmt,0)) UnallocatedAmt
			FROM paysplit
			LEFT JOIN (
				SELECT paysplit.FSplitNum, SUM(paysplit.SplitAmt) AllocAmt
				FROM paysplit
				WHERE paysplit.FSplitNum != 0 
				GROUP BY paysplit.FSplitNum
			)alloc ON paysplit.SplitNum = alloc.FSplitNum
			INNER JOIN patient ON patient.PatNum = paysplit.PatNum "            ;

            if (listClinicNums.Count > 0)
            {
                command += @"
					AND patient.ClinicNum IN ("                     + string.Join(",", listClinicNums.Select(x => POut.Long(x))) + ") ";
            }
            if (listProvNums.Count > 0)
            {
                command += @"
					AND patient.PriProv IN ("                     + string.Join(",", listProvNums.Select(x => POut.Long(x))) + ") ";
            }
            command += @"
			INNER JOIN patient guar ON guar.PatNum = patient.Guarantor
			WHERE paysplit.UnearnedType != 0 "            ;
            if (listUnearnedTypeNums.Count > 0)
            {
                command += @"
					AND paysplit.UnearnedType IN ("                     + string.Join(",", listUnearnedTypeNums.Select(x => POut.Long(x))) + ") ";
            }
            command += @"
			AND paysplit.FSplitNum = 0
			AND (paysplit.SplitAmt + alloc.AllocAmt != 0 OR alloc.AllocAmt IS NULL)
			GROUP BY paysplit.PatNum,patient.Guarantor,patient.FName,patient.LName,guar.FName,guar.LName "            ;
            if (isExcludeNetZero)
            {
                command += @"
				HAVING ABS(UnallocatedAmt) > 0.005"                ;
            }
            DataTable tableUnallocatedPrepayments = ReportsComplex.RunFuncOnReportServer(() => Db.GetTable(command));
            //get remaining amount for all procedures of the returned families.
            List <long> listGuarantorNums = tableUnallocatedPrepayments.Rows.OfType <DataRow>().Select(x => PIn.Long(x["Guarantor"].ToString())).ToList();

            if (listGuarantorNums.Count == 0)
            {
                return(retVal);               //No families have paysplits with unallocated prepayments. Return empty table.
            }
            /*As long as any patient in the family has AT LEAST ONE procedure that is not fully, explicitly paid off, they will not show in this report.*/
            List <UnearnedProc> listGuarantorRemainingProcs = ReportsComplex.RunFuncOnReportServer(() =>
                                                                                                   Procedures.GetRemainingProcsForFamilies(listGuarantorNums));
            Dictionary <long, double> dictFamilyBalances = ReportsComplex.RunFuncOnReportServer(() => Ledgers.GetBalancesForFamilies(listGuarantorNums));

            foreach (DataRow rowCur in tableUnallocatedPrepayments.Rows)
            {
                long unallocatedGuarantor = PIn.Long(rowCur["Guarantor"].ToString());
                if (listGuarantorRemainingProcs.Select(x => x.GuarNum).Contains(unallocatedGuarantor))
                {
                    continue;                    //Has at least one procedure that is not fully paid off.
                }
                double famBal;
                if (!dictFamilyBalances.TryGetValue(unallocatedGuarantor, out famBal))
                {
                    famBal = 0;
                }
                DataRow newRow = retVal.NewRow();
                newRow["PatientName"]    = rowCur["LName"].ToString() + ", " + rowCur["FName"].ToString();
                newRow["GuarantorName"]  = rowCur["GuarL"].ToString() + ", " + rowCur["GuarF"].ToString();
                newRow["PatUnearnedAmt"] = PIn.Double(rowCur["UnallocatedAmt"].ToString());
                newRow["FamBal"]         = famBal.ToString("f");
                retVal.Rows.Add(newRow);
            }
            return(retVal);
        }
Esempio n. 5
0
        public static DataTable GetUnearnedAllocationData(List <long> listClinicNums, List <long> listProvNums,
                                                          List <long> listUnearnedTypeNums, bool isExcludeNetZeroUnearned, bool showProvider)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetTable(MethodBase.GetCurrentMethod(), listClinicNums, listProvNums, listUnearnedTypeNums, isExcludeNetZeroUnearned, showProvider));
            }
            List <long> listHiddenUnearnedDefNums = ReportsComplex.RunFuncOnReportServer(() =>
                                                                                         Defs.GetDefsNoCache(DefCat.PaySplitUnearnedType).FindAll(x => !string.IsNullOrEmpty(x.ItemValue)).Select(x => x.DefNum).ToList()
                                                                                         );
            //get all families that have an unallocated unearned balance.
            //from those, remove families that have not had procedures charted/completed after the unearned amount.

            //All families
            //DatePay = the earliest date of unallocated unearned.
            //Unallocated Amt = the total unallocated amt for the patient.
            string command = $@"
				SELECT patient.Guarantor, MIN(paysplit.DatePay) DatePay, SUM(paysplit.SplitAmt) UnallocAmt{(showProvider ? ", provider.Abbr" : "")}
				FROM paysplit
				INNER JOIN patient ON patient.PatNum = paysplit.PatNum "                ;

            if (listClinicNums.Count > 0 || listProvNums.Count > 0)
            {
                command += "INNER JOIN patient guar ON guar.PatNum = patient.Guarantor ";
                if (listClinicNums.Count > 0)
                {
                    command += "AND guar.ClinicNum IN (" + string.Join(",", listClinicNums.Select(x => POut.Long(x))) + ") ";
                }
                if (listProvNums.Count > 0)
                {
                    command += "AND guar.PriProv IN (" + string.Join(",", listProvNums.Select(x => POut.Long(x))) + ") ";
                }
            }
            if (showProvider)
            {
                command += "LEFT JOIN provider ON provider.ProvNum = paysplit.ProvNum ";
            }
            command += "WHERE paysplit.UnearnedType != 0 ";
            if (listUnearnedTypeNums.Count > 0)
            {
                command += "AND paysplit.UnearnedType IN (" + string.Join(",", listUnearnedTypeNums.Select(x => POut.Long(x))) + ") ";
            }
            if (listHiddenUnearnedDefNums.Count > 0)
            {
                command += $"AND paysplit.UnearnedType NOT IN ({string.Join(",",listHiddenUnearnedDefNums)}) ";
            }
            command += $"GROUP BY patient.Guarantor{(showProvider ? ", provider.Abbr" : "")} ";
            if (isExcludeNetZeroUnearned)
            {
                command += "HAVING ABS(UnallocAmt) > 0.005 ";
            }
            //one row per family
            DataTable   tableUnallocatedUnearned = ReportsComplex.RunFuncOnReportServer(() => Db.GetTable(command));
            List <long> listGuarantors           = tableUnallocatedUnearned.Rows.OfType <DataRow>().Select(x => PIn.Long(x["Guarantor"].ToString())).ToList();
            //all procedures for the families that have not been explicitly paid off.
            //Key: GuarantorNum | Val:ListRemainingProcsForFam
            List <UnearnedProc> listRemProcs = ReportsComplex.RunFuncOnReportServer(() => Procedures.GetRemainingProcsForFamilies(listGuarantors));
            Dictionary <long, List <UnearnedProc> > dictFamRemainingProcs = listRemProcs.GroupBy(x => x.GuarNum)
                                                                            .ToDictionary(x => x.Key, y => y.ToList());
            Dictionary <long, double> dictFamilyBalances = ReportsComplex.RunFuncOnReportServer(() => Ledgers.GetBalancesForFamilies(listGuarantors));
            Dictionary <long, string> dictPatNames       = ReportsComplex.RunFuncOnReportServer(() =>
                                                                                                Patients.GetPatientNames(Patients.GetAllFamilyPatNums(listGuarantors)));
            List <ProcedureCode> listProcCodes = ReportsComplex.RunFuncOnReportServer(() => ProcedureCodes.GetAllCodes());
            DataTable            retVal        = new DataTable();

            retVal.Columns.Add("Guar");
            retVal.Columns.Add("FamBal");
            retVal.Columns.Add("FamUnearned");
            retVal.Columns.Add("FamRemAmt");
            if (showProvider)
            {
                retVal.Columns.Add("Prov");
            }
            retVal.Columns.Add("Patient");
            retVal.Columns.Add("Code");
            retVal.Columns.Add("Date");
            retVal.Columns.Add("Fee");
            retVal.Columns.Add("RemAmt");
            int rowCount = tableUnallocatedUnearned.Rows.Count;          //For brevity

            //This has to be a for-loop instead of foreach so we can access the guarantor number from the next iteration
            //prior to adding the procedures to the report (to validate whether or not we should add another guarantor row
            //for a provider
            for (int i = 0; i < rowCount; i++)
            {
                DataRow             guarRowCur       = tableUnallocatedUnearned.Rows[i];
                int                 nextIndex        = i + 1;
                long                guarNum          = PIn.Long(guarRowCur["Guarantor"].ToString());
                DateTime            dateFirstUnalloc = PIn.Date(guarRowCur["DatePay"].ToString());
                double              unallocAmt       = PIn.Double(guarRowCur["UnallocAmt"].ToString());
                List <UnearnedProc> listUnearnedProcsForGuar;
                if (!dictFamRemainingProcs.TryGetValue(guarNum, out listUnearnedProcsForGuar))
                {
                    continue;                    //This family does not have any procedures that need to have money allocated to.
                }
                listUnearnedProcsForGuar = listUnearnedProcsForGuar.Where(x => x.Proc.ProcDate >= dateFirstUnalloc).OrderBy(x => x.Proc.ProcDate).ToList();
                if (listUnearnedProcsForGuar.Count == 0)
                {
                    continue;                    //We only want to show families where the procedure was completed after the unallocated prepayment.
                }
                decimal famRemAmt = listUnearnedProcsForGuar.Sum(x => x.UnallocatedAmt);
                DataRow guarRow   = retVal.NewRow();
                string  guarName;
                double  famBal;
                dictPatNames.TryGetValue(guarNum, out guarName);
                dictFamilyBalances.TryGetValue(guarNum, out famBal);
                guarRow["Guar"]        = guarName;
                guarRow["FamBal"]      = famBal.ToString("f");
                guarRow["FamUnearned"] = unallocAmt.ToString("f");
                guarRow["FamRemAmt"]   = famRemAmt.ToString("f");
                if (showProvider)
                {
                    guarRow["Prov"] = guarRowCur["Abbr"];
                }
                retVal.Rows.Add(guarRow);
                //If the next row has the same guarantor, then we know that it is another provider for this account and we should not populate the procedures yet
                if (nextIndex < rowCount && guarNum == PIn.Long(tableUnallocatedUnearned.Rows[nextIndex]["Guarantor"].ToString()))
                {
                    continue;
                }
                foreach (UnearnedProc unearnedProc in listUnearnedProcsForGuar)
                {
                    DataRow newRow = retVal.NewRow();
                    dictPatNames.TryGetValue(guarNum, out guarName);
                    string patName;
                    if (dictPatNames.TryGetValue(unearnedProc.Proc.PatNum, out patName))
                    {
                        newRow["Patient"] = patName;
                    }
                    newRow["Code"]   = ProcedureCodes.GetStringProcCode(unearnedProc.Proc.CodeNum, listProcCodes);
                    newRow["Date"]   = unearnedProc.Proc.ProcDate.ToShortDateString();
                    newRow["Fee"]    = unearnedProc.Proc.ProcFeeTotal.ToString("f");
                    newRow["RemAmt"] = unearnedProc.UnallocatedAmt.ToString("f");
                    retVal.Rows.Add(newRow);
                }
            }
            return(retVal);
        }
Esempio n. 6
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);
        }
Esempio n. 7
0
        public static string GetQueryString(RpAgingParamObject rpo)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetString(MethodBase.GetCurrentMethod(), rpo));
            }
            //patient aging---------------------------------------------------------------------------
            //The aging report always shows historical numbers based on the date entered.
            //the selected columns have to remain in this order due to the way the report complex populates the returned sheet
            string queryAg = "SELECT ";

            if (rpo.IsForInsAging)              //get patNum for insAgingReport only
            {
                queryAg += "patient.PatNum, ";
            }
            if (ReportsComplex.RunFuncOnReportServer(() => (Prefs.GetBoolNoCache(PrefName.ReportsShowPatNum))))
            {
                queryAg += DbHelper.Concat("patient.PatNum", "' - '", "patient.LName", "', '", "patient.FName", "' '", "patient.MiddleI");
            }
            else
            {
                queryAg += DbHelper.Concat("patient.LName", "', '", "patient.FName", "' '", "patient.MiddleI");
            }
            queryAg += " patName,guarAging.Bal_0_30,guarAging.Bal_31_60,guarAging.Bal_61_90,guarAging.BalOver90,guarAging.BalTotal,"
                       + "guarAging.InsWoEst,guarAging.InsPayEst,guarAging.BalTotal-guarAging.InsPayEst-guarAging.InsWoEst AS ";
            if (DataConnection.DBtype == DatabaseType.MySql)
            {
                queryAg += "$pat";
            }
            else               //Oracle needs quotes.
            {
                queryAg += "\"$pat\"";
            }
            //Must select "blankCol" for use with reportComplex to fix spacing of final column
            queryAg += (rpo.HasDateLastPay ? ",'' blankCol,guarAging.DateLastPay " : " ")
                       + "FROM ("
                       + ReportsComplex.RunFuncOnReportServer(() => Ledgers.GetAgingQueryString(asOfDate: rpo.AsOfDate, isHistoric: rpo.IsHistoric,
                                                                                                isInsPayWoCombined: rpo.IsInsPayWoCombined, hasDateLastPay: rpo.HasDateLastPay, isGroupByGuar: rpo.IsGroupByFam, isWoAged: rpo.IsWoAged,
                                                                                                isForceAgeNegAdj: rpo.IsForceAgeNegAdj, doAgePatPayPlanPayments: rpo.DoAgePatPayPlanPayments))
                       + ") guarAging "
                       + "INNER JOIN patient ON patient.PatNum=guarAging.PatNum ";
            List <string> listWhereAnds = new List <string>();

            //InsAging will filter for age, but we need to return all in here order for the filtering to be correct
            if (!rpo.IsForInsAging)
            {
                List <string> listAgeOrs = new List <string>();
                if (rpo.IsIncludeNeg || rpo.IsOnlyNeg)
                {
                    listAgeOrs.Add("guarAging.BalTotal <= -0.005");
                }
                if (rpo.IsIncludeInsNoBal || rpo.IsOnlyInsNoBal)
                {
                    listAgeOrs.Add("((ABS(guarAging.InsPayEst) >= 0.005 OR ABS(guarAging.InsWoEst) >= 0.005) "
                                   + "AND guarAging.Bal_0_30 < 0.005 AND guarAging.Bal_31_60 < 0.005 AND guarAging.Bal_61_90 < 0.005 AND guarAging.BalOver90 < 0.005)");
                }
                if (!rpo.IsOnlyNeg && !rpo.IsOnlyInsNoBal)
                {
                    listAgeOrs.Add("guarAging.BalOver90 >= 0.005");                    //applies to all ages
                    if (rpo.AccountAge <= AgeOfAccount.Over60)
                    {
                        listAgeOrs.Add("guarAging.Bal_61_90 >= 0.005");
                    }
                    if (rpo.AccountAge <= AgeOfAccount.Over30)
                    {
                        listAgeOrs.Add("guarAging.Bal_31_60 >= 0.005");
                    }
                    if (rpo.AccountAge == AgeOfAccount.Any)                   //only applies to Any age
                    {
                        listAgeOrs.Add("guarAging.Bal_0_30 >= 0.005");
                    }
                }
                listWhereAnds.Add("(" + string.Join(" OR ", listAgeOrs) + ")");
            }
            if (rpo.IsExcludeInactive)
            {
                listWhereAnds.Add("patient.PatStatus != " + (int)PatientStatus.Inactive);
            }
            if (rpo.IsExcludeArchive)
            {
                listWhereAnds.Add("patient.PatStatus != " + (int)PatientStatus.Archived);
            }
            if (rpo.IsExcludeBadAddress)
            {
                listWhereAnds.Add("patient.Zip != ''");
            }
            if (rpo.ListBillTypes.Count > 0)           //if all bill types is selected, list will be empty
            {
                listWhereAnds.Add("patient.BillingType IN (" + string.Join(",", rpo.ListBillTypes.Select(x => POut.Long(x))) + ")");
            }
            if (rpo.ListProvNums.Count > 0)           //if all provs is selected, list will be empty
            {
                listWhereAnds.Add("patient.PriProv IN (" + string.Join(",", rpo.ListProvNums.Select(x => POut.Long(x))) + ")");
            }
            if (ReportsComplex.RunFuncOnReportServer(() => (!Prefs.GetBoolNoCache(PrefName.EasyNoClinics))))             //if clinics enabled, at least one clinic will be selected
            //listClin may contain "Unassigned" clinic with ClinicNum 0, in which case it will also be in the query string
            {
                listWhereAnds.Add("patient.ClinicNum IN (" + string.Join(",", rpo.ListClinicNums.Select(x => POut.Long(x))) + ")");
            }
            if (listWhereAnds.Count > 0)
            {
                queryAg += "WHERE " + string.Join(" AND ", listWhereAnds) + " ";
            }
            queryAg += "ORDER BY patient.LName,patient.FName";
            return(queryAg);
        }
Esempio n. 8
0
        public static string GetQueryString(DateTime asOfDate, bool isWoAged, bool hasDateLastPay, bool isGroupByFam, bool isOnlyNeg, AgeOfAccount accountAge,
                                            bool isIncludeNeg, bool isExcludeInactive, bool isExcludeBadAddress, List <long> listProv, List <long> listClinicNums, List <long> listBillType,
                                            bool isExcludeArchive, bool isIncludeInsNoBal, bool isOnlyInsNoBal, bool?isForceAgeNegAdj, bool isForInsAging, bool doAgePatPayPlanPayments)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetString(MethodBase.GetCurrentMethod(), asOfDate, isWoAged, hasDateLastPay, isGroupByFam, isOnlyNeg, accountAge, isIncludeNeg,
                                      isExcludeInactive, isExcludeBadAddress, listProv, listClinicNums, listBillType, isExcludeArchive, isIncludeInsNoBal, isOnlyInsNoBal,
                                      isForceAgeNegAdj, isForInsAging, doAgePatPayPlanPayments));
            }
            //patient aging---------------------------------------------------------------------------
            //The aging report always shows historical numbers based on the date entered.
            //the selected columns have to remain in this order due to the way the report complex populates the returned sheet
            string queryAg = "SELECT ";

            if (isForInsAging)              //get patNum for insAgingReport only
            {
                queryAg += "patient.PatNum, ";
            }
            if (ReportsComplex.RunFuncOnReportServer(() => (Prefs.GetBoolNoCache(PrefName.ReportsShowPatNum))))
            {
                queryAg += DbHelper.Concat("patient.PatNum", "' - '", "patient.LName", "', '", "patient.FName", "' '", "patient.MiddleI");
            }
            else
            {
                queryAg += DbHelper.Concat("patient.LName", "', '", "patient.FName", "' '", "patient.MiddleI");
            }
            queryAg += "patName,guarAging.Bal_0_30,guarAging.Bal_31_60,guarAging.Bal_61_90,guarAging.BalOver90,guarAging.BalTotal,"
                       + "guarAging.InsWoEst,guarAging.InsPayEst,guarAging.BalTotal-guarAging.InsPayEst-guarAging.InsWoEst AS ";
            if (DataConnection.DBtype == DatabaseType.MySql)
            {
                queryAg += "$pat";
            }
            else               //Oracle needs quotes.
            {
                queryAg += "\"$pat\"";
            }
            bool isHistoric         = (asOfDate.Date != DateTime.Today);
            bool isInsPayWoCombined = false;

            //Must select "blankCol" for use with reportComplex to fix spacing of final column
            queryAg += (hasDateLastPay ? ",'' blankCol,guarAging.DateLastPay " : " ")
                       + "FROM ("
                       + ReportsComplex.RunFuncOnReportServer(() => Ledgers.GetAgingQueryString(asOfDate, null, isHistoric, isInsPayWoCombined, hasDateLastPay,
                                                                                                isGroupByFam, isWoAged, isForceAgeNegAdj, doAgePatPayPlanPayments))
                       + ") guarAging "
                       + "INNER JOIN patient ON patient.PatNum=guarAging.PatNum "
                       + "WHERE ";
            List <string> listAgeOrs = new List <string>();

            if (isIncludeNeg || isOnlyNeg)
            {
                listAgeOrs.Add("guarAging.BalTotal < -0.005");
            }
            if (isIncludeInsNoBal || isOnlyInsNoBal)
            {
                listAgeOrs.Add("((guarAging.InsPayEst > 0.005 OR guarAging.InsWoEst > 0.005) AND guarAging.Bal_0_30 < 0.005 AND guarAging.Bal_31_60 < 0.005 "
                               + "AND guarAging.Bal_61_90 < 0.005 AND guarAging.BalOver90 < 0.005)");
            }
            if (!isOnlyNeg && !isOnlyInsNoBal)
            {
                if (accountAge <= AgeOfAccount.Over90)
                {
                    listAgeOrs.Add("guarAging.BalOver90 > 0.005");
                }
                if (accountAge <= AgeOfAccount.Over60)
                {
                    listAgeOrs.Add("guarAging.Bal_61_90 > 0.005");
                }
                if (accountAge <= AgeOfAccount.Over30)
                {
                    listAgeOrs.Add("guarAging.Bal_31_60 > 0.005");
                }
                if (accountAge <= AgeOfAccount.Any)
                {
                    listAgeOrs.Add("guarAging.Bal_0_30 > 0.005");
                }
            }
            queryAg += "(" + string.Join(" OR ", listAgeOrs) + ") ";
            if (isExcludeInactive)
            {
                queryAg += "AND patient.PatStatus != " + (int)PatientStatus.Inactive + " ";
            }
            if (isExcludeArchive)
            {
                queryAg += "AND patient.PatStatus != " + (int)PatientStatus.Archived + " ";
            }
            if (isExcludeBadAddress)
            {
                queryAg += "AND patient.Zip != '' ";
            }
            if (listBillType.Count > 0)           //if all bill types is selected, list will be empty
            {
                queryAg += "AND patient.BillingType IN (" + string.Join(",", listBillType.Select(x => POut.Long(x))) + ") ";
            }
            if (listProv.Count > 0)           //if all provs is selected, list will be empty
            {
                queryAg += "AND patient.PriProv IN (" + string.Join(",", listProv.Select(x => POut.Long(x))) + ") ";
            }
            if (ReportsComplex.RunFuncOnReportServer(() => (!Prefs.GetBoolNoCache(PrefName.EasyNoClinics))))             //validated to have at least one clinic selected if clinics are enabled above
            //listClin may contain "Unassigned" clinic with ClinicNum 0, in which case it will also be in the query string
            {
                queryAg += "AND patient.ClinicNum IN (" + string.Join(",", listClinicNums.Select(x => POut.Long(x))) + ") ";
            }
            queryAg += "ORDER BY patient.LName,patient.FName";
            return(queryAg);
        }