Example #1
0
 public void Add(PP_PaySplitItem splitItem)
 {
     Splits.Add(splitItem);
 }
Example #2
0
 public void Remove(PP_PaySplitItem splitItem)
 {
     Splits.Remove(splitItem);
 }
Example #3
0
		public void Remove(PP_PaySplitItem splitItem)
		{
			Splits.Remove(splitItem);
		}
Example #4
0
		public void Add(PP_PaySplitItem splitItem)
		{
			Splits.Add(splitItem);
		}
		/// <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>
		/// Called by the Exposed Public Method with the similar name.  Just put 
		/// it here for organization.
		/// </summary>
		private void _EqualizePayments() {
			SortAllLists();
			GuarantorLedgerItemsCollection Ledger = this;
			List<PP_PaySplitItem> PaySplits = new List<PP_PaySplitItem>();
			List<PP_LedgerItem> ChargesAndRefundsList = Ledger.Charges;
			List<PP_PaymentItem> PaymentsAndAdjustList = Ledger.Payments;
			//List<PP_PaySplitItem> Splits = new List<PP_PaySplitItem>();
			#region Check DataValidity Should remove in future
			// I just wanted to check to make sure my ducks are in a row.  I may take this out in the future
			//for (int j = 0; j < PaymentsAndAdjustList.Count; j++)
			//    if (PaymentsAndAdjustList[j].AmtUnallocated > 0)
			//    {
			//        if (PaymentsAndAdjustList[j].PATNUM != 3859)  //Stacia SchluttenHofer had a  -ve check 
			//        throw new Exception("Figure Out Why Payment is +ve.");
			//    }
			//for (int j = 0; j < ChargesAndRefundsList.Count; j++)
			//    if (ChargesAndRefundsList[j].AmtUnallocated < 0)
			//        throw new Exception("Figure Out Why Charge is -ve.");
			#endregion





			// Allocate Adjustments First then Payments
			#region Allocate Adjustments First
			for(int j = 0;j < PaymentsAndAdjustList.Count;j++) {


				if(PaymentsAndAdjustList[j].ITEMTYPE != LedgerItemTypes.Payment
					&& !PaymentsAndAdjustList[j].IS_ALLOCATED) //Should only be LedgerItemTypes.NegAdjustment             
					for(int k = 0;k < ChargesAndRefundsList.Count;k++) {
						// Check to see if Providers are the same for the adjustment and the charge
						// And that there is enough to allocate
						if(ChargesAndRefundsList[k].AmtUnallocated > 0
							&& ChargesAndRefundsList[k].PROVNUM == PaymentsAndAdjustList[j].PROVNUM) { // Allocate amount

							decimal a = ChargesAndRefundsList[k].AmtUnallocated;
							decimal b = -PaymentsAndAdjustList[j].AmtUnallocated;

							decimal AmmountToAllocate = (a - b > 0 ? b : a);
							if(AmmountToAllocate == 0)
								1.ToString();
							// 100 - +50 = +50 --- Allocate -50
							// 100 - +60 = +40 --- Allocate -60
							// 100 - +110 =  -10  --- Allocate -100

							ChargesAndRefundsList[k].ALLOCATED_AMMOUNT += AmmountToAllocate;
							PaymentsAndAdjustList[j].ALLOCATED_AMMOUNT -= AmmountToAllocate;
							PP_PaySplitItem paysplit = new PP_PaySplitItem
								(-AmmountToAllocate,ChargesAndRefundsList[k].PROVNUM,
								ChargesAndRefundsList[k].PROCNUM,ChargesAndRefundsList[k].OD_TABLESOURCE); //, PaymentsAndAdjustList[j].ITEMNUM);
							PaymentsAndAdjustList[j].PAYMENT_SPLITS.Add(paysplit);
							//Splits.Add(paysplit);

							if(PaymentsAndAdjustList[j].AmtUnallocated == 0)
								k = ChargesAndRefundsList.Count; // end charge lookup and get another payment
						}// end if ChargeList has unallocated Ammount and Providers are the same                    
					} //end for chargeList loop
				//if (PaymentsAndAdjustList[j].AmtUnallocated > 0)
				//{
				//		Only put code here if you want to have a split assigned if no carges for that provider 
				//		are present.

				//}
			}// end for PaymentListLoop
			#endregion Alloc Adj First
			#region Now Allocate Payments

			int CurChargeIndex = 0;  // use this so that you don't have to loop through each charge each time.
			//  Now just index past the item when done.
			bool chargesLeft = CurChargeIndex < ChargesAndRefundsList.Count;

			for(int j = 0;j < PaymentsAndAdjustList.Count;j++) {
				//DataTable dtv1 = ViewLedgerObject(new LedgerItemTypes[] { LedgerItemTypes.Payment });
				int OverFlowCounter = 0;
				while(!PaymentsAndAdjustList[j].IS_ALLOCATED && chargesLeft == true) {
					OverFlowCounter++;
					if(ChargesAndRefundsList[CurChargeIndex].AmtUnallocated > 0) { // Allocate amount

						decimal a = ChargesAndRefundsList[CurChargeIndex].AmtUnallocated;
						decimal b = -PaymentsAndAdjustList[j].AmtUnallocated;

						decimal AmmountToAllocate = (a - b > 0 ? b : a);
						if(AmmountToAllocate == 0)
							2.ToString();
						// 100 + -50 = +50 --- Allocate -50
						// 100 + -60 = +40 --- Allocate -60
						// 100 + -110 =  -10  --- Allocate -100
						//if (this.Payments[4] == PaymentsAndAdjustList[j])
						//    1.ToString(); // to debug
						ChargesAndRefundsList[CurChargeIndex].ALLOCATED_AMMOUNT += AmmountToAllocate;
						PaymentsAndAdjustList[j].ALLOCATED_AMMOUNT -= AmmountToAllocate;
						if(AmmountToAllocate != 0) {
							PP_PaySplitItem paysplit = new PP_PaySplitItem
								(-AmmountToAllocate,ChargesAndRefundsList[CurChargeIndex].PROVNUM,
								ChargesAndRefundsList[CurChargeIndex].PROCNUM,
								ChargesAndRefundsList[CurChargeIndex].OD_TABLESOURCE);//, PaymentsAndAdjustList[j].ITEMNUM);

							PaymentsAndAdjustList[j].PAYMENT_SPLITS.Add(paysplit);
							//	Splits.Add(paysplit);
						}

					}
					if(ChargesAndRefundsList[CurChargeIndex].AmtUnallocated == 0)
						CurChargeIndex++;
					chargesLeft = CurChargeIndex < ChargesAndRefundsList.Count;
					if(OverFlowCounter > 100000)
						throw new Exception("Problems with while loop in GuarantorLedgerItemColection.EqualizePaymentsV2()\n\n"+PU.Method);
				} //end while(PaymentsAndAdjustList[j].AmtUnallocated > 0 && chargesLeft == true) 

				// if there are no charges left to allocate and Payment has unallocated ammount then
				// make a paysplit entry for allocated amount.  Assign Split to Provider = 0.
				if(!PaymentsAndAdjustList[j].IS_ALLOCATED) {

					PP_PaySplitItem paysplit = new PP_PaySplitItem
								(PaymentsAndAdjustList[j].AmtUnallocated,0,0,0);//, PaymentsAndAdjustList[j].ITEMNUM);
					PaymentsAndAdjustList[j].PAYMENT_SPLITS.Add(paysplit);
					//Splits.Add(paysplit);

				}

			}// end for
			#endregion
			#region Set LedgerItems  that have Unallocated Amounts (and Ammounts) = 0 as IsAllocated
			// It is possible for a LedgerItem = 0 and I don't want to have to 
			// Recycle throught these again so I am making these items as 
			// flagged to indicate that they are considered allocated.
			//Indicate which items are fully allocated.
			//for (int i = 0; i < Ledger.FullLedger.Count; i++)
			//    if (Ledger.FullLedger[i].AmtUnallocated == 0)
			//        if (!Ledger.FullLedger[i].IS_ALLOCATED)
			//        {
			//            Ledger.FullLedger[i].IS_ALLOCATED = true; // Does it get here? It does if Ammount =0.  I think ALLOCATED_AMMOUNT should take care of them
			//        }
			#endregion
			//PU.MB = "Did not implent DansPaySplitTable.WritePaySplits(Splits); Splits will not be saved in database\n\n"+PU.Method;
			//DansPaySplitTable.WritePaySplits(Splits);			
			//	DataTable dtv1 = ViewLedgerObject(true);
			//	DataTable dtv2 = ViewLedgerObject(new LedgerItemTypes[] { LedgerItemTypes.Payment });
			Ledger.Update2();
			m_isEqualized = true;
		}