Example #1
0
        public PP_LedgerItem(PP_LedgerItem DLI)
        {
            PP_LedgerItem CloneCopy = (PP_LedgerItem)DLI.MemberwiseClone();


            SetConstructorValues(CloneCopy.m_LedgerItemType, CloneCopy.m_Guarantor, CloneCopy.m_PatNum,
                                 CloneCopy.m_ProvNum, CloneCopy.m_ProcNum, CloneCopy.m_ItemDate, CloneCopy.m_ItemAmt,
                                 CloneCopy.m_LedgerItemNum, CloneCopy.m_TableSource);
        }
Example #2
0
        /*
         * /// <summary>
         * /// Splits the current ledger item up into an array of items with different
         * /// payments and providers.  Each string in parameters should be of the form
         * /// xxx,yyyy
         * /// xxx= provider num
         * /// yyyy = amount
         * /// Throws exception if 'this' is not a payment or writeoff type.
         * /// </summary>
         * /// <param name="Parameters"></param>
         * /// <returns></returns>
         * public PP_LedgerItem[] SplitPaymentWriteOffItem(string[] Parameters)
         * {
         *      //   bool b1 = this.m_LedgerItemType != LedgerItemTypes.NegAdjustment;
         *      //    bool b2 = this.m_LedgerItemType != LedgerItemTypes.Payment;
         *      //    bool b3 = b1 || b2;
         *      if (!(this.m_LedgerItemType != LedgerItemTypes.NegAdjustment || this.m_LedgerItemType != LedgerItemTypes.Payment))
         *              throw new Exception("SplitPaymentWriteoffItem in DansLedger called \nfrom an object not of Payment or writeoff type!");
         *      if (Parameters[0] == "")
         *              return null;
         *      List<PP_LedgerItem> rList = new List<PP_LedgerItem>();
         *      PP_LedgerItem temp = null;
         *      ushort CurrentProvider = UInt16.Parse(Parameters[0].Split(',')[0]);
         *      //decimal runningBalance = 0;
         *      for (int i = 0; i < Parameters.Length; i++)
         *      {
         *              string[] ProvAmount = Parameters[i].Split(',');
         *              ushort Prov = UInt16.Parse(ProvAmount[0]);
         *              decimal ammount = Decimal.Parse(ProvAmount[1]);
         *              if (temp == null)
         *              {
         *                      temp = new PP_LedgerItem(this.ITEMTYPE, this.GUARANTOR, this.PATNUM,
         *                                Prov, this.PROCNUM, this.ITEMDATE, 0, 0);
         *                      rList.Add(temp);
         *              }
         *              if (temp.PROVNUM == Prov)
         *              {
         *                      temp.AMMOUNT += ammount;
         *                      temp.ALLOCATED_AMMOUNT += ammount;
         *
         *              }
         *              if (Prov != temp.PROVNUM)
         *              {
         *                      temp.ALLOCATION_STRING = temp.PROVNUM.ToString() + "," + temp.AMMOUNT;
         *                      temp.m_IsAllocated = true;
         *                      temp.ALLOCATED_AMMOUNT = temp.m_AmtAllocated;
         *
         *                      temp = new PP_LedgerItem(this.ITEMTYPE, this.GUARANTOR, this.PATNUM,
         *                                Prov, this.PROCNUM, this.ITEMDATE, ammount, 0);
         *                      rList.Add(temp);
         *              }
         *
         *              temp.ALLOCATION_STRING = temp.PROVNUM.ToString() + "," + temp.AMMOUNT;
         *              temp.m_IsAllocated = true;
         *              // temp.AmtAllocated += -37;
         *              //   rList.Add(temp);
         *      }
         *      return rList.ToArray();
         *
         *
         * }
         */
        #endregion
        #endregion
        #region IComparable Members
        /// <summary>
        /// Returns -1 if Date of this is sooner than obj, 1 if later
        /// If Dates are the same then returns -1,0,1 by giving -1
        /// to the first items in this order Charge->Adjustment->Payment
        /// if ItemTypes are the same 0 is returned
        ///
        /// </summary>
        public int CompareTo(object obj)
        {
            /* elected to elimiate this item and let the system throw the exception
             * because this method will get called a lot and
             * I want to reduce overhead.
             * if (!(obj is DansLedgerItem))
             *      throw new Exception("Obj passed to DansLedgerItem.CompareTo() is not a DansLedgerItem");
             */
            PP_LedgerItem item2  = (PP_LedgerItem)obj;
            int           rValue = this.ITEMDATE.CompareTo(item2.ITEMDATE);

            if (rValue == 0)
            {
                switch (this.ITEMTYPE)
                {
                case LedgerItemTypes.PosAdjustment:
                    if (item2.ITEMTYPE == LedgerItemTypes.PosAdjustment)
                    {
                        return(0);
                    }
                    else if (item2.ITEMTYPE == LedgerItemTypes.Charge)
                    {
                        return(1);
                    }
                    else
                    {
                        return(-1);
                    }

                //break;
                case LedgerItemTypes.Charge:
                    if (item2.ITEMTYPE == LedgerItemTypes.Charge)
                    {
                        rValue = 0;
                    }
                    else
                    {
                        rValue = 1;                                 // Charge should always come first. So compared object should compare bigger.
                    }
                    break;

                case LedgerItemTypes.Payment:
                    if (item2.ITEMTYPE == LedgerItemTypes.Payment)
                    {
                        rValue = 0;
                    }
                    else
                    {
                        rValue = 1;                                 // Payments always last
                    }
                    break;

                case LedgerItemTypes.NegAdjustment:
                    if (item2.ITEMTYPE == LedgerItemTypes.NegAdjustment)
                    {
                        rValue = 0;
                    }
                    else if (item2.ITEMTYPE == LedgerItemTypes.Charge || item2.ITEMTYPE == LedgerItemTypes.PosAdjustment)
                    {
                        rValue = 1;                  //ie this Should appear later then item2
                    }
                    else                             // item2.ITEMTYPE == LedgerItemType.Payment
                    {
                        rValue = -1;
                    }
                    break;

                default:
                    break;
                }
            }    // if (rValue == 0)
            return(rValue);
        }        //public int CompareTo(object obj)
Example #3
0
		public PP_LedgerItem(PP_LedgerItem DLI)
		{
			PP_LedgerItem CloneCopy = (PP_LedgerItem)DLI.MemberwiseClone();


			SetConstructorValues(CloneCopy.m_LedgerItemType, CloneCopy.m_Guarantor, CloneCopy.m_PatNum,
				CloneCopy.m_ProvNum, CloneCopy.m_ProcNum, CloneCopy.m_ItemDate, CloneCopy.m_ItemAmt,
				CloneCopy.m_LedgerItemNum, CloneCopy.m_TableSource);

		}
		/// <summary>
		/// Fill the Ledger Object with data from the database.
		/// Flushes old data in this object first
		/// If you are running lots of data you may want to control the GC 
		/// to collect when you want.
		/// 
		/// 
		/// 
		/// Method Roadmap:
		/// 
		///		1. Generate 2 Tables
		///			i.		Table1:		dt_ODItems			Contains all the items of Ledger Interest from OpenDental Tables
		///			ii.		Table2:		dt2_AllocTbl_Items	Contains all the Allocation Data that exists in the allocation_provider table
		///		2. Look For Differences
		///			i.		Build a Ledger Item from the dt_ODItems (ie from the opendental tables)
		///			ii.		Find the Splits in dt2_AllocTbl_Items that are associated with the dt_ODItems that are payments
		///						a.		For Payment items (in dt_ODItems)Find he dt2_AllocTbl_Items that have the same PayTableSource and PaySourceNumber
		///						b.		Make a split [] out of the dt2_AllocTbl_Items that were found
		///			iii.	Add LI and Splits to MasterList  (this) with call to AddToCollection(LI,splits);
		///						a.  The method will determine if LI is a payment and if splits are not null create a PP_PaymentItem and attach the splits to this PP_PaymentItem and then add the PP_PaymentItem to the master list
		///						b.  Adding PaySplits needs to calculate the allocated ammount
		/// 
		/// Need to determine what to do if an item exists in the allocation_provider (ie dt2_AllocTble_Items) table but not in the
		/// opendental data (ie dt_ODItems) // use Update2() to Clear these entries from data that 
		/// has been deleted from OD but not from allocation_provider.
		/// </summary>
		private bool _Fill(bool Suppress_GC_Collection) {

			//PU.Ex = "Not Implemented Yet Flag 6";
			Flush(Suppress_GC_Collection);
			bool rValSuccess = true;
			try {



				//	QueryResult qr = QueryResult.RunQuery(PP_ODSQLPullStrings_LedgerItem.PullAll_FromOD(m_GuarantorNumber, false));
				DataTable dt_ODItems = Db.GetTableOld(PP_ODSQLPullStrings_LedgerItem.PullAll_FromOD(m_GuarantorNumber,false));

				string cmd2 = "SELECT PayTableSource, PaySourceNum, " //0 ,1
								+ " IsFullyAllocated, Amount, ProvNum, " // 2, 3, 4
								+ " AllocToTableSource, AllocToSourceNum  FROM " // 5, 6
					+ MyAllocator1_ProviderPayment.TABLENAME
					+ "\nWHERE Guarantor = " + this.GUARANTOR_NUMBER;
				DataTable dt2_AllocTbl_Items = Db.GetTableOld(cmd2);


				if(dt_ODItems.Rows.Count != 0 && dt_ODItems.Columns.Count != 0) {
#if DEBUG
					// just check to see if columns line up.
					PP_ODSQLPullStrings_LedgerItem.SetColumnNames(ref dt_ODItems);
#endif

					for(int i = 0;i < dt_ODItems.Rows.Count;i++) {
						//public enum HeaderOfQueryEnum 
						//    { LedgerItemType, Guarantor, PatNum,
						//      ProvNum, ItemDate, Ammount, 
						//      ItemNum, TableSource	};

						DataRow dr = dt_ODItems.Rows[i];

						LedgerItemTypes type = (LedgerItemTypes)Int32.Parse(dr[0].ToString());
						uint uiGuarantor = uint.Parse(dr[1].ToString());
						uint uiPatnum = uint.Parse(dr[2].ToString()); ;
						ushort usProvNum = ushort.Parse(dr[3].ToString());
						DateTime ItemDate = (DateTime)dr[4]; // need to make sure this doesn't crash here.
						Decimal dAmmount = Decimal.Parse(dr[5].ToString());
						uint uiItemNum = uint.Parse(dr[6].ToString()); ;
						MyAllocator1.ODTablesUsed.ODTablesPulled iTableEnum = 
							(MyAllocator1.ODTablesUsed.ODTablesPulled)int.Parse(dr[7].ToString());

						PP_LedgerItem LI = new PP_LedgerItem(
							type,uiGuarantor,uiPatnum,usProvNum,
							uiItemNum,ItemDate,dAmmount,0,iTableEnum);
						//if (uiItemNum == 95693)
						//    1.ToString();

						///////////////////////////////////////////////////////////////////
						//  Before make an Item Load the Allocation Status for Payments from Allocation_Provider Table.
						//		Remember All payments get fully split
						//		If there is no provider to allocate split to ProvNum is 
						//			assigned to zero.
						///////////////////////////////////////////////////////////////////
						PP_PaySplitItem[] splits = null;
						if(type == LedgerItemTypes.Payment && dt2_AllocTbl_Items.Rows.Count != 0) {
							//if (i == 66)
							//    1.ToString();
							string s1 = "PayTableSource = " + ((int)iTableEnum).ToString() + " AND PaySourceNum = " + uiItemNum;
							DataRow[] rows = dt2_AllocTbl_Items.Select(s1);

							#region Just Code so I can use the Visual Studio Runtime DataSet Visulizer on the DataTable
							//DataTable dtTest = new DataTable();
							//for (int jj =0; jj < dt2_AllocTbl_Items.Columns.Count; jj++)
							//{
							//    dtTest.Columns.Add(new DataColumn(dt2_AllocTbl_Items.Columns[jj].ColumnName, typeof(string))   );

							//}
							//for (int jj = 0; jj < rows.Length; jj++)
							//{
							//    DataRow drkk = dtTest.NewRow();
							//    for (int kk = 0; kk < dtTest.Columns.Count; kk++)
							//    {
							//        drkk[kk] = rows[jj][kk].ToString();
							//    }
							//    dtTest.Rows.Add(drkk);
							//}
							#endregion
							
#if DEBUG
							bool MarkedAllocated;
							decimal sum = 0; // don't need the sum just checking things out.
							MarkedAllocated = true;  // can be used to make sure there is not a miss recorrded IsAllocated.
#endif
							bool fullyAllocated = false;
							if(rows != null && rows.Length != 0) {
								splits = new PP_PaySplitItem[rows.Length];
								fullyAllocated = true;
								for(int j = 0;j < rows.Length;j++) {
									decimal amount2 = decimal.Parse(rows[j][3].ToString());
									int prov2 = int.Parse(rows[j][4].ToString());

									MyAllocator1.ODTablesUsed.ODTablesPulled AllocatedToTable =
										(MyAllocator1.ODTablesUsed.ODTablesPulled)int.Parse(rows[j][5].ToString());

									ulong AllocatedToNum = ulong.Parse(rows[j][6].ToString());
									splits[j] = new PP_PaySplitItem(amount2,prov2,AllocatedToNum,AllocatedToTable);
									fullyAllocated = fullyAllocated && (prov2 != 0); // If one item == 0 then it has not been allocated.

#if DEBUG
									// checking method only
									sum += amount2;
									//MarkedAllocated = MarkedAllocated && (rows[i][2].ToString() == "1");
#endif
								}
								//LI.IS_ALLOCATED = fullyAllocated;


							}
#if DEBUG
							else
								MarkedAllocated = false; // no splits to match against payment item (should be a new payment)
#endif
							//if (fullyAllocated)
							//    LI.ALLOCATED_AMMOUNT = sum; // if Allocated_ammount = amount the fully allocated = true (property of LI)
#if DEBUG
							if(sum == LI.AMMOUNT) {
								if(!MarkedAllocated)
									PU.Ex = "Record states that allocation is not fully allocated but summed ammounts in the\n"
                                        + "allocation table show that the allocation is fully allocated.";


							}
							else
								if(MarkedAllocated)
									PU.Ex = "Allocation Table shows that the procedures are fully allocated\n"
                                        + "but sums do not match. Sums should always match";
#endif
						}
						///////////////////////////////////////////////////////////////////
						//  Now add item to collection
						///////////////////////////////////////////////////////////////////
						AddToCollection(LI,splits); // Just Makes a PaymentItem out of the LI and Splits then adds the PaymentItem to the list



					}
					// What about the case of an Item being in the Allocation_Provider Table but not in the 
					// ODTable data? Let Update2() take care of these
				}
			}
			catch(Exception exc) {
				PU.MB = "Error in method:  " + PU.Method + "\n\n" + exc.Message;
				rValSuccess = false;
			}
			if(rValSuccess)
				this.m_isFilled = true;
			//DataTable dtv1 = ViewLedgerObject(true);
			//DataTable dtv1 = ViewLedgerObject(new LedgerItemTypes[] { LedgerItemTypes.Payment });
			return rValSuccess;
		}
		/// <summary>
		/// Adds to the full list
		/// adds to chargesandrefunds list or paymentsandadjustments lists as
		/// apporpriate.
		/// </summary>
		/// <param name="dli"></param>
		private void AddToCollection(PP_LedgerItem dli,PP_PaySplitItem[] splits) {
			PP_LedgerItem item_to_add = dli;
			if(dli.ITEMTYPE == LedgerItemTypes.Charge)
				m_ChargesAndRefundsList.Add(dli);
			else if(dli.ITEMTYPE == LedgerItemTypes.Payment) {

				PP_PaymentItem ppi = dli.CreatePaymentItem();
				if(splits != null)
					ppi.PAYMENT_SPLITS.AddRange(splits);
				if(ppi.ALLOCATED_AMMOUNT != 0)
					1.ToString();
				for(int i = 0;i < ppi.PAYMENT_SPLITS.Count;i++) {
					ppi.ALLOCATED_AMMOUNT += ppi.PAYMENT_SPLITS[i].AMMOUNT;
				}
				item_to_add = ppi;
				m_PaymentsAndAdjustList.Add(ppi);
			}
			else if(dli.ITEMTYPE == LedgerItemTypes.NegAdjustment)
				if(dli.AMMOUNT < 0) {
					PP_PaymentItem ppi = dli.CreatePaymentItem();
					item_to_add = ppi;
					m_PaymentsAndAdjustList.Add(ppi);
				}
				else
					m_ChargesAndRefundsList.Add(dli);//ie +ve adjusment reflects a refund
			else if(dli.ITEMTYPE == LedgerItemTypes.PosAdjustment)
				m_ChargesAndRefundsList.Add(dli); // ie treat positive adjustment just like a charge
			m_FullLedgerList.Add(item_to_add);

			this.m_isEqualized = false;
		}
		/// <summary>
		/// Used in EqualizePayments. Recursive Method
		/// </summary>
		private decimal AllocateToCharge(List<PP_LedgerItem> dliChargeRefundList,PP_LedgerItem dliPaymentItem) {
			////////////-----------> Recursive Method !!!
			if(dliPaymentItem.AmtUnallocated == 0)
				return 0;
			decimal AmtAllocated = 0;
			PP_LedgerItem dliNext = NextUnallocatedItem(dliChargeRefundList);
			if(dliNext != null) {
				AmtAllocated = dliNext.AddAllocation(dliPaymentItem.ITEMNUM,dliPaymentItem.AmtUnallocated);
				if(AmtAllocated != 0) {
					//    dliPaymentItem.PROVNUM = dliNext.PROVNUM;
					dliPaymentItem.AddAllocation(dliNext.ITEMNUM,AmtAllocated,dliNext.PROVNUM);
				}
				else
					dliNext.IsAllocated_OLD = true;  // if nothing to allocate
				if(dliNext.IsAllocated_OLD == true)
					dliChargeRefundList.Remove(dliNext);
				if(dliPaymentItem.AmtUnallocated != 0) // will loop infinately if no allocation occurs and Chargeitems are still left
				{
					AmtAllocated += AllocateToCharge(dliChargeRefundList,dliPaymentItem); //recursion
				}
			}
			return AmtAllocated;

		}
Example #7
0
        /// <summary>
        /// Provides a data table that gives a running balance for each provider.
        ///
        /// Will run the EqualizeGuarantorPayments(guarantor) first if this instance has not
        /// done so yet.
        ///
        /// // Setup DataTable
        ///
        /// Date				   Provider #							          Provider #
        ///			   Charges  Payments  Adjustments  Balances	    Charges  Payments  Adjustments Balances
        /// [ 0   ][1][   2   ][   3    ][     4     ][    5   ][6][    7  ][    8   ][  etc......
        /// </summary>
        /// <param name="uGuarantor"></param>
        /// <returns></returns>
        public DataTable ProviderBalancesDetail()        //uint uGuarantor)
        {
            DataTable dt = new DataTable();

            string [] cols    = { "Date", "Provider" };
            string[]  subcols = { "Charges", "Payments", "Adjustment", "Balance" };
            if (Ledger == null)
            {
                PU.Ex = "Guarantor not set in " + PU.Method;
            }
            if (!Ledger.IS_FILLED)
            {
                Ledger.Fill(false);
            }
            if (!Ledger.IS_EQUALIZED)
            {
                Ledger.EqualizePaymentsV2();
            }
            if (!Ledger.IS_FILLED || !Ledger.IS_EQUALIZED)
            {
                dt.Columns.Add("ERROR");
                dt.Rows.Add(dt.NewRow()[0] = "Error Getting table filled");
                return(dt);
            }
            Ledger.FullLedger.Sort();

            // Generate List of Providers
            List <int> ProviderNums = new List <int>();

            foreach (PP_LedgerItem li in Ledger.FullLedger)
            {
                if (li is PP_PaymentItem)
                {
                    foreach (PP_PaySplitItem psi in ((PP_PaymentItem)li).PAYMENT_SPLITS)
                    {
                        if (!ProviderNums.Contains(psi.PROVNUM))
                        {
                            ProviderNums.Add(psi.PROVNUM);
                        }
                    }
                }
                else
                if (!ProviderNums.Contains(li.PROVNUM))
                {
                    ProviderNums.Add(li.PROVNUM);
                }
            }
            // Setup DataTable
            ///
            /// Date				   Provider #							          Provider #
            ///			   Charges  Payments  Adjustments  Balances	    Charges  Payments  Adjustments Balances
            /// [ 0   ][1][   2   ][   3    ][     4     ][    5   ][6][    7  ][    8   ][  etc......
            dt.Columns.Add(new DataColumn("Date"));
            System.Collections.Hashtable ht_dtProvNumOffsets = new System.Collections.Hashtable();
            for (int i = 0; i < ProviderNums.Count; i++)
            {
                dt.Columns.Add(new DataColumn(""));                 // Blank Column
                dt.Columns.Add(new DataColumn(""));
                dt.Columns.Add(new DataColumn(""));
                dt.Columns.Add(new DataColumn());
                dt.Columns.Add(new DataColumn(""));
            }
            // Add Header Rows
            DataRow dr1 = dt.NewRow();
            DataRow dr2 = dt.NewRow();

            dr2[0] = "Date";
            for (int i = 0; i < ProviderNums.Count; i++)
            {
                dr1[3 + 5 * i] = "Provider";
                dr1[4 + 5 * i] = "# " + ProviderNums[i].ToString();
                for (int j = 0; j < subcols.Length; j++)
                {
                    dr2[2 + 5 * i + j] = subcols[j];                     // Charges, Payments, Adjustments, Balances
                }
            }
            dt.Rows.Add(dr1);
            dt.Rows.Add(dr2);

            // Generate Provider Balances
            System.Collections.Hashtable htProvBalance             = new System.Collections.Hashtable();
            System.Collections.Hashtable htProvBalance_Cummulative = new System.Collections.Hashtable();
            DateTime curDate = DateTime.MinValue;

            if (Ledger.FullLedger.Count != 0)
            {
                curDate = Ledger.FullLedger[0].ITEMDATE;
            }
            foreach (int ProvNum in ProviderNums)
            {
                htProvBalance[ProvNum]             = new ProviderBalance(ProvNum, curDate);
                htProvBalance_Cummulative[ProvNum] = new ProviderBalance(ProvNum, curDate);
            }



            for (int i = 0; i < Ledger.FullLedger.Count; i++)
            {
                PP_LedgerItem li = Ledger.FullLedger[i];


                #region Making the DataRow
                if (curDate < li.ITEMDATE || i == Ledger.FullLedger.Count - 1)
                {
                    DataRow dr3 = this.MakeProviderBalanceDataRow(curDate, dt, htProvBalance, htProvBalance_Cummulative, subcols, ProviderNums);
                    dt.Rows.Add(dr3);

                    foreach (int ProvNum in ProviderNums)
                    {
                        htProvBalance[ProvNum] = new ProviderBalance(ProvNum, li.ITEMDATE);
                        ((ProviderBalance)htProvBalance_Cummulative[ProvNum]).Date_of_Balance = li.ITEMDATE;
                    }
                    curDate = li.ITEMDATE;
                }
                #endregion

                #region Calculate Balances
                if (li is PP_PaymentItem)
                {
                    foreach (PP_PaySplitItem psi in ((PP_PaymentItem)li).PAYMENT_SPLITS)
                    {
                        ProviderBalance pb            = (ProviderBalance)htProvBalance[psi.PROVNUM];
                        ProviderBalance pb_Cumulative = (ProviderBalance)htProvBalance_Cummulative[psi.PROVNUM];
                        pb.Ammounts[(int)li.ITEMTYPE]            += psi.AMMOUNT;
                        pb_Cumulative.Ammounts[(int)li.ITEMTYPE] += psi.AMMOUNT;
                    }
                }
                else
                {
                    ProviderBalance pb            = (ProviderBalance)htProvBalance[li.PROVNUM];
                    ProviderBalance pb_Cumulative = (ProviderBalance)htProvBalance_Cummulative[li.PROVNUM];
                    pb.Ammounts[(int)li.ITEMTYPE]            += li.AMMOUNT;
                    pb_Cumulative.Ammounts[(int)li.ITEMTYPE] += li.AMMOUNT;
                }

                #endregion
            }
            #region Adding the End DataRow

            {
                DataRow dr3 = this.MakeProviderBalanceDataRow(curDate, dt, htProvBalance, htProvBalance_Cummulative, subcols, ProviderNums);
                dt.Rows.Add(dr3);
            }
            #endregion

            return(dt);
        }