public void Add(PP_PaySplitItem splitItem) { Splits.Add(splitItem); }
public void Remove(PP_PaySplitItem splitItem) { Splits.Remove(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; }