public void ValidateWorkTypes(IEnumerable <DocumentDetails> documents) { Dictionary <int, RUTROTWorkType> availableWorkTypes = GetAvailableWorkTypes(this, this.Accessinfo.BusinessDate); bool haveUnavailableWorkTypes = false; for (int i = 0; i < documents.Count(); i++) { foreach (ARTran tran in documents.ElementAt(i).Lines) { ARTranRUTROT tranRR = RUTROTHelper.GetExtensionNullable <ARTran, ARTranRUTROT>(tran); if (tranRR?.IsRUTROTDeductible == true && (tranRR.RUTROTItemType == RUTROTItemTypes.MaterialCost || tranRR.RUTROTItemType == RUTROTItemTypes.Service)) { if (!availableWorkTypes.ContainsKey(tranRR.RUTROTWorkTypeID.Value)) { haveUnavailableWorkTypes = true; PXProcessing.SetError(i, new PXException(RUTROTMessages.CannotClaimWorkType)); } } } } if (haveUnavailableWorkTypes) { throw new PXException(RUTROTMessages.CannotClaimWorkType); } }
protected virtual void ARTran_RUTROTType_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e) { ARTranRUTROT row = RUTROTHelper.GetExtensionNullable <ARTran, ARTranRUTROT>((ARTran)e.Row); if (row != null) { row.RUTROTWorkTypeID = null; } }
protected virtual void ARTran_RowInserting(PXCache sender, PXRowInsertingEventArgs e) { if (e.Row == null) { return; } ARTran row = e.Row as ARTran; ARTranRUTROT rowRR = RUTROTHelper.GetExtensionNullable <ARTran, ARTranRUTROT>(row); rowRR.CuryRUTROTTaxAmountDeductible = decimal.Zero; }
protected virtual void ARTran_RUTROTItemType_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e) { ARTran row = (ARTran)e.Row; ARTranRUTROT rowRR = RUTROTHelper.GetExtensionNullable <ARTran, ARTranRUTROT>(row); if (row != null) { PXUIFieldAttribute.SetEnabled <ARTranRUTROT.rUTROTWorkTypeID>(sender, row, rowRR.RUTROTItemType != RUTROTItemTypes.OtherCost); if (rowRR.RUTROTItemType == RUTROTItemTypes.OtherCost) { sender.SetValueExt <ARTranRUTROT.rUTROTWorkTypeID>(row, null); } } }
public virtual ARTran CreateTranFromShipLine(ARInvoice newdoc, SOOrderType ordertype, string operation, SOLine orderline, ref SOShipLine shipline, CreateTranFromShipLineDelegate baseMethod) { ARTran tran = baseMethod(newdoc, ordertype, operation, orderline, ref shipline); SOLine line = PXSelect <SOLine, Where <SOLine.orderType, Equal <Required <SOLine.orderType> >, And <SOLine.orderNbr, Equal <Required <SOLine.orderNbr> >, And <SOLine.lineNbr, Equal <Required <SOLine.lineNbr> > > > > > .Select(Base, orderline.OrderType, orderline.OrderNbr, orderline.LineNbr); SOLineRUTROT lineRR = PXCache <SOLine> .GetExtension <SOLineRUTROT>(line); ARTranRUTROT tranRR = PXCache <ARTran> .GetExtension <ARTranRUTROT>(tran); tranRR.IsRUTROTDeductible = lineRR.IsRUTROTDeductible; tranRR.RUTROTItemType = lineRR.RUTROTItemType; tranRR.RUTROTWorkTypeID = lineRR.RUTROTWorkTypeID; return(tran); }
public virtual ARTran CreateTranFromMiscLine(SOOrderShipment orderShipment, SOMiscLine2 orderline, CreateTranFromMiscLineDelegate baseMethod) { ARTran tran = baseMethod(orderShipment, orderline); SOLine line = PXSelect <SOLine, Where <SOLine.orderType, Equal <Required <SOLine.orderType> >, And <SOLine.orderNbr, Equal <Required <SOLine.orderNbr> >, And <SOLine.lineNbr, Equal <Required <SOLine.lineNbr> > > > > > .Select(Base, orderline.OrderType, orderline.OrderNbr, orderline.LineNbr); SOLineRUTROT lineRR = PXCache <SOLine> .GetExtension <SOLineRUTROT>(line); ARTranRUTROT tranRR = PXCache <ARTran> .GetExtension <ARTranRUTROT>(tran); tranRR.IsRUTROTDeductible = lineRR.IsRUTROTDeductible; tranRR.RUTROTItemType = lineRR.RUTROTItemType; tranRR.RUTROTWorkTypeID = lineRR.RUTROTWorkTypeID; return(tran); }
protected virtual void ARTran_RowPersisting(PXCache sender, PXRowPersistingEventArgs e) { ARTran row = (ARTran)e.Row; ARTranRUTROT rowRR = RUTROTHelper.GetExtensionNullable <ARTran, ARTranRUTROT>(row); if (row == null || rowRR?.IsRUTROTDeductible != true) { return; } bool isWorkTypeRequired = rowRR.RUTROTItemType == RUTROTItemTypes.MaterialCost || rowRR.RUTROTItemType == RUTROTItemTypes.Service; if (isWorkTypeRequired && rowRR.RUTROTWorkTypeID == null && sender.RaiseExceptionHandling <ARTranRUTROT.rUTROTWorkTypeID>(e.Row, rowRR.RUTROTWorkTypeID, new PXSetPropertyException(ErrorMessages.FieldIsEmpty))) { throw new PXRowPersistingException(typeof(ARTranRUTROT.rUTROTWorkTypeID).Name, rowRR.RUTROTWorkTypeID, ErrorMessages.FieldIsEmpty); } }
protected virtual void ARTran_RowSelected(PXCache sender, PXRowSelectedEventArgs e) { if (e.Row == null) { return; } ARTran row = e.Row as ARTran; ARTranRUTROT rowRR = RUTROTHelper.GetExtensionNullable <ARTran, ARTranRUTROT>(row); RUTROTWorkType workType = PXSelect <RUTROTWorkType, Where <RUTROTWorkType.workTypeID, Equal <Required <RUTROTWorkType.workTypeID> > > > .Select(this.Base, rowRR.RUTROTWorkTypeID); if (rowRR?.IsRUTROTDeductible == true && Base.Document.Current.Released != true && rowRR?.RUTROTItemType != RUTROTItemTypes.OtherCost && Base.Document.Current.Voided != true && !RUTROTHelper.IsUpToDateWorkType(workType, Base.Document.Current.DocDate ?? DateTime.Now)) { sender.RaiseExceptionHandling <ARTranRUTROT.rUTROTWorkTypeID>(row, workType?.Description, new PXSetPropertyException(RUTROTMessages.ObsoleteWorkType)); } else { sender.RaiseExceptionHandling <ARTranRUTROT.rUTROTWorkTypeID>(row, workType?.Description, null); } }
public static IEnumerable <RUTExportItem> Create(ClaimRUTROTProcess.DocumentDetails document, List <RUTROTWorkType> availableWorkTypes) { var items = new List <RUTExportItem>(); RUTROT rowRR = document.Rutrot; DateTime payDate = document.Payments.Select(p => p.Item2.AdjgDocDate).Where(d => d != null).Max(d => d.Value); string invNbr = document.Document.RefNbr; decimal otherCost = rowRR.CuryOtherCost ?? 0m; decimal workPrice = rowRR.CuryWorkPrice ?? 0m; Dictionary <int?, decimal> materialCost = new Dictionary <int?, decimal>(); Dictionary <int?, decimal> materialCostSumms = new Dictionary <int?, decimal>(); Dictionary <int?, int> hoursAmt = new Dictionary <int?, int>(); Dictionary <int?, int> hourSumms = new Dictionary <int?, int>(); foreach (RUTROTWorkType workType in availableWorkTypes) { materialCost.Add(workType.WorkTypeID, 0m); materialCostSumms.Add(workType.WorkTypeID, 0m); hoursAmt.Add(workType.WorkTypeID, 0); hourSumms.Add(workType.WorkTypeID, 0); } decimal claimedSumm = 0m; decimal paidSumm = 0m; decimal workPriceSumm = 0m; decimal otherCostSumm = 0m; decimal paidUnrounded = 0m; foreach (ARTran tran in document.Lines) { ARTranRUTROT tranRR = PXCache <ARTran> .GetExtension <ARTranRUTROT>(tran); try { if (tranRR.RUTROTItemType == RUTROTItemTypes.MaterialCost) { materialCost[tranRR.RUTROTWorkTypeID] += tran.CuryTranAmt ?? 0m; } else if (tranRR.RUTROTItemType == RUTROTItemTypes.Service) { hoursAmt[tranRR.RUTROTWorkTypeID] += (int)(tran.Qty ?? 0); } } catch { throw new PXException(RUTROTMessages.CannotClaimWorkType); } } foreach (var dp in document.Distribution.Zip(document.PaymentDistribution, (d, p) => new { Distribution = d, Payment = p })) { decimal percent = (dp.Distribution.CuryAmount / rowRR.CuryTotalAmt) ?? 1m; RUTExportItem item = new RUTExportItem() { InvoiceNbr = invNbr, OtherCost = Math.Floor(otherCost * percent), WorkPrice = Math.Floor(workPrice * percent), MaterialCost = new Dictionary <int?, decimal>(), HoursAmt = new Dictionary <int?, int>(), PaidAmt = Math.Floor(dp.Payment), PayDate = payDate, PersonID = dp.Distribution.PersonalID, ClaimedAmt = Math.Floor(dp.Distribution.CuryAmount ?? 0.0m), ROTEstate = rowRR.ROTEstate, ROTAppartment = rowRR.ROTAppartment, ROTOrganizationNbr = rowRR.ROTOrganizationNbr }; foreach (RUTROTWorkType workType in availableWorkTypes) { item.MaterialCost.Add(workType.WorkTypeID, 0m); item.HoursAmt.Add(workType.WorkTypeID, 0); } foreach (RUTROTWorkType workType in availableWorkTypes) { decimal hoursAmtCurrent = hoursAmt[workType.WorkTypeID] * percent; item.HoursAmt[workType.WorkTypeID] = hoursAmtCurrent < 1 && hoursAmtCurrent > 0 ? 1 : (int)Math.Round(hoursAmtCurrent); item.MaterialCost[workType.WorkTypeID] = Math.Floor(materialCost[workType.WorkTypeID] * percent); hourSumms[workType.WorkTypeID] += item.HoursAmt[workType.WorkTypeID]; materialCostSumms[workType.WorkTypeID] += item.MaterialCost[workType.WorkTypeID]; } claimedSumm += item.ClaimedAmt; paidSumm += item.PaidAmt; workPriceSumm += item.WorkPrice; otherCostSumm += item.OtherCost; paidUnrounded += dp.Payment; items.Add(item); } if (items.Count > 0) { decimal claimLeft = Math.Floor(rowRR.CuryTotalAmt ?? 0m) - claimedSumm; for (int i = 0; i < items.Count; i++) { if (Math.Round(claimLeft) == 0m) { break; } if (items[i].ClaimedAmt != 0) { items[i].ClaimedAmt += Math.Sign(claimLeft); claimLeft -= Math.Sign(claimLeft); } } decimal paidLeft = Math.Floor(paidUnrounded) - paidSumm; for (int i = 0; i < items.Count; i++) { if (Math.Round(paidLeft) == 0m) { break; } if (items[i].PaidAmt != 0) { items[i].PaidAmt += Math.Sign(paidLeft); paidLeft -= Math.Sign(paidLeft); } } decimal workPriceLeft = Math.Floor(workPrice) - workPriceSumm; for (int i = 0; i < items.Count; i++) { if (Math.Round(workPriceLeft) == 0m) { break; } if (items[i].WorkPrice != 0) { items[i].WorkPrice += Math.Sign(workPriceLeft); workPriceLeft -= Math.Sign(workPriceLeft); } } decimal otherCostLeft = Math.Floor(otherCost) - otherCostSumm; for (int i = 0; i < items.Count; i++) { if (Math.Round(otherCostLeft) == 0m) { break; } if (items[i].OtherCost != 0) { items[i].OtherCost += Math.Sign(otherCostLeft); otherCostLeft -= Math.Sign(otherCostLeft); } } foreach (RUTROTWorkType workType in availableWorkTypes) { int hoursLeft = hoursAmt[workType.WorkTypeID] - hourSumms[workType.WorkTypeID]; for (int j = 0; j < items.Count; j++) { if (hoursLeft == 0) { break; } if (items[j].HoursAmt[workType.WorkTypeID] != 0) { if (items[j].HoursAmt[workType.WorkTypeID] + Math.Sign(hoursLeft) >= 1) { items[j].HoursAmt[workType.WorkTypeID] += Math.Sign(hoursLeft); hoursLeft -= Math.Sign(hoursLeft); } } } } foreach (RUTROTWorkType workType in availableWorkTypes) { decimal materialCostLeft = materialCost[workType.WorkTypeID] - materialCostSumms[workType.WorkTypeID]; for (int j = 0; j < items.Count; j++) { if (materialCostLeft == 0) { break; } if (items[j].MaterialCost[workType.WorkTypeID] != 0) { if (items[j].MaterialCost[workType.WorkTypeID] + Math.Sign(materialCostLeft) >= 1) { items[j].MaterialCost[workType.WorkTypeID] += Math.Sign(materialCostLeft); materialCostLeft -= Math.Sign(materialCostLeft); } } } } } return(items); }
private static void CreateMemo(ARInvoiceEntry graph, ARRegister doc, RUTROT rutrot, string docType, bool OnRelease = false) { DuplicateFilter filter = PXCache <DuplicateFilter> .CreateCopy(graph.duplicatefilter.Current); foreach (PXResult <ARInvoice, CurrencyInfo, Terms, Customer> res in ARInvoice_CurrencyInfo_Terms_Customer.Select(graph, (object)doc.DocType, doc.RefNbr, doc.CustomerID)) { CurrencyInfo info = PXCache <CurrencyInfo> .CreateCopy((CurrencyInfo)res); info.CuryInfoID = null; info.IsReadOnly = false; info = PXCache <CurrencyInfo> .CreateCopy(graph.currencyinfo.Insert(info)); ARInvoice invoice = (ARInvoice)graph.Document.Cache.CreateInstance(); if (docType == ARDocType.CreditMemo) { invoice.DueDate = null; invoice.DiscDate = null; invoice.CustomerID = doc.CustomerID; invoice.ARAccountID = doc.ARAccountID; invoice.ARSubID = doc.ARSubID; } if (docType == ARInvoiceType.DebitMemo) { invoice.DueDate = ((ARInvoice)res).DueDate; invoice.DiscDate = ((ARInvoice)res).DiscDate; BranchRUTROT branchRUTROT = GetBranchRUTROT(graph); invoice.CustomerID = branchRUTROT.TaxAgencyAccountID; invoice.ARAccountID = null; invoice.ARSubID = null; } ARInvoiceRUTROT invoiceRUTROT = RUTROTHelper.GetExtensionNullable <ARInvoice, ARInvoiceRUTROT>(invoice); invoiceRUTROT.IsRUTROTDeductible = false; invoice.CuryInfoID = info.CuryInfoID; invoice.DocType = docType; invoice.OrigModule = GL.BatchModule.AR; invoice.RefNbr = null; invoice.OrigModule = GL.BatchModule.AR; invoice.DocDesc = PXLocalizer.LocalizeFormat(RUTROTMessages.MemoDescription, doc.RefNbr); invoice.OpenDoc = true; invoice.Released = false; invoice.Hold = false; invoice.Printed = false; invoice.Emailed = false; invoice.BatchNbr = null; invoice.ScheduleID = null; invoice.Scheduled = false; invoice.NoteID = null; invoice.RefNoteID = null; invoice.TermsID = null; invoice.InstallmentCntr = null; invoice.InstallmentNbr = null; invoice.CuryOrigDiscAmt = 0m; invoice.FinPeriodID = doc.FinPeriodID; invoice.OrigDocDate = invoice.DocDate; invoice.CuryLineTotal = 0m; invoice.IsTaxPosted = false; invoice.IsTaxValid = false; invoice.CuryVatTaxableTotal = 0m; invoice.CuryVatExemptTotal = 0m; invoice.StatementDate = null; invoice.PendingPPD = false; invoice.CustomerLocationID = null; if (!string.IsNullOrEmpty(invoice.PaymentMethodID)) { CA.PaymentMethod pm = null; if (invoice.CashAccountID.HasValue) { CA.PaymentMethodAccount pmAccount = null; PXResult <CA.PaymentMethod, CA.PaymentMethodAccount> pmResult = (PXResult <CA.PaymentMethod, CA.PaymentMethodAccount>) PXSelectJoin <CA.PaymentMethod, LeftJoin < CA.PaymentMethodAccount, On <CA.PaymentMethod.paymentMethodID, Equal <CA.PaymentMethodAccount.paymentMethodID> > >, Where < CA.PaymentMethod.paymentMethodID, Equal <Required <CA.PaymentMethod.paymentMethodID> >, And <CA.PaymentMethodAccount.cashAccountID, Equal <Required <CA.PaymentMethodAccount.cashAccountID> > > > > . Select(graph, invoice.PaymentMethodID, invoice.CashAccountID); pm = pmResult; pmAccount = pmResult; if (pm == null || pm.UseForAR == false || pm.IsActive == false) { invoice.PaymentMethodID = null; invoice.CashAccountID = null; } else if (pmAccount == null || pmAccount.CashAccountID == null || pmAccount.UseForAR != true) { invoice.CashAccountID = null; } } else { pm = PXSelect <CA.PaymentMethod, Where <CA.PaymentMethod.paymentMethodID, Equal <Required <CA.PaymentMethod.paymentMethodID> > > > .Select(graph, invoice.PaymentMethodID); if (pm == null || pm.UseForAR == false || pm.IsActive == false) { invoice.PaymentMethodID = null; invoice.CashAccountID = null; invoice.PMInstanceID = null; } } if (invoice.PMInstanceID.HasValue) { CustomerPaymentMethod cpm = PXSelect <CustomerPaymentMethod, Where <CustomerPaymentMethod.pMInstanceID, Equal <Required <CustomerPaymentMethod.pMInstanceID> > > > . Select(graph, invoice.PMInstanceID); if (string.IsNullOrEmpty(invoice.PaymentMethodID) || cpm == null || cpm.IsActive == false || cpm.PaymentMethodID != invoice.PaymentMethodID) { invoice.PMInstanceID = null; } } } else { invoice.CashAccountID = null; invoice.PMInstanceID = null; } SalesPerson sp = (SalesPerson)PXSelectorAttribute.Select <ARInvoice.salesPersonID>(graph.Document.Cache, invoice); if (sp == null || sp.IsActive == false) { invoice.SalesPersonID = null; } invoice = graph.Document.Insert(invoice); } TX.TaxAttribute.SetTaxCalc <ARTran.taxCategoryID>(graph.Transactions.Cache, null, TX.TaxCalc.ManualCalc); graph.FieldDefaulting.AddHandler <ARTran.salesPersonID>((sender, e) => { e.NewValue = null; e.Cancel = true; }); decimal roundedTotalDistributedLinesAmt = 0m; foreach (ARTran srcTran in PXSelect <ARTran, Where <ARTran.tranType, Equal <Required <ARTran.tranType> >, And <ARTran.refNbr, Equal <Required <ARTran.refNbr> > > > > .Select(graph, doc.DocType, doc.RefNbr)) { ARTran tran = PXCache <ARTran> .CreateCopy(srcTran); ARTranRUTROT tranRR = RUTROTHelper.GetExtensionNullable <ARTran, ARTranRUTROT>(tran); if (tranRR.IsRUTROTDeductible != true) { continue; } tran.TranType = graph.Document.Current.DocType; tran.RefNbr = graph.Document.Current.RefNbr; string origDrCr = tran.DrCr; tran.DrCr = null; tran.Released = null; tran.CuryInfoID = null; tran.SOOrderNbr = null; tran.SOShipmentNbr = null; tran.OrigInvoiceDate = tran.TranDate; tran.NoteID = null; tran.ManualPrice = true; tran.CuryTranAmt = Math.Floor(tranRR.CuryRUTROTAvailableAmt ?? 0m); roundedTotalDistributedLinesAmt += tran.CuryTranAmt ?? 0m; tranRR.IsRUTROTDeductible = false; if (!string.IsNullOrEmpty(tran.DeferredCode)) { DRSchedule schedule = PXSelect <DRSchedule, Where <DRSchedule.module, Equal <BQLConstants.moduleAR>, And <DRSchedule.docType, Equal <Required <DRSchedule.docType> >, And <DRSchedule.refNbr, Equal <Required <DRSchedule.refNbr> >, And <DRSchedule.lineNbr, Equal <Required <DRSchedule.lineNbr> > > > > > > . Select(graph, doc.DocType, doc.RefNbr, tran.LineNbr); if (schedule != null) { tran.DefScheduleID = schedule.ScheduleID; } } SalesPerson sp = (SalesPerson)PXSelectorAttribute.Select <ARTran.salesPersonID>(graph.Transactions.Cache, tran); if (sp == null || sp.IsActive == false) { tran.SalesPersonID = null; } ARTran insertedTran = graph.Transactions.Insert(tran); PXNoteAttribute.CopyNoteAndFiles(graph.Transactions.Cache, srcTran, graph.Transactions.Cache, insertedTran); insertedTran.ManualDisc = true; insertedTran.TaxCategoryID = null; graph.Transactions.Update(insertedTran); } decimal distributedFee = (rutrot.CuryDistributedAmt ?? 0m) - roundedTotalDistributedLinesAmt; if (distributedFee != 0m) { foreach (ARTran artran in graph.Transactions.Cache.Inserted) { if (Math.Round(distributedFee) == 0m) { break; } if (artran.CuryTranAmt != 0m) { artran.CuryTranAmt += Math.Sign(distributedFee); distributedFee -= Math.Sign(distributedFee); } graph.Transactions.Update(artran); } } graph.Document.Current.CuryOrigDocAmt = graph.Document.Current.CuryDocBal; graph.Document.Cache.Update(graph.Document.Current); graph.RowInserting.AddHandler <ARSalesPerTran>((sender, e) => { e.Cancel = true; }); foreach (ARSalesPerTran salespertran in PXSelect <ARSalesPerTran, Where <ARSalesPerTran.docType, Equal <Required <ARSalesPerTran.docType> >, And <ARSalesPerTran.refNbr, Equal <Required <ARSalesPerTran.refNbr> > > > > .Select(graph, doc.DocType, doc.RefNbr)) { ARSalesPerTran newtran = PXCache <ARSalesPerTran> .CreateCopy(salespertran); newtran.DocType = graph.Document.Current.DocType; newtran.RefNbr = graph.Document.Current.RefNbr; newtran.Released = false; newtran.CuryInfoID = null; newtran.CuryCommnblAmt *= -1m; newtran.CuryCommnAmt *= -1m; SalesPerson sp = (SalesPerson)PXSelectorAttribute.Select <ARSalesPerTran.salespersonID>(graph.salesPerTrans.Cache, newtran); if (!(sp == null || sp.IsActive == false)) { graph.salesPerTrans.Update(newtran); } } var discountDetailsSet = PXSelect <ARInvoiceDiscountDetail, Where <ARInvoiceDiscountDetail.docType, Equal <Required <ARInvoice.docType> >, And <ARInvoiceDiscountDetail.refNbr, Equal <Required <ARInvoice.refNbr> > > >, OrderBy <Asc <ARInvoiceDiscountDetail.docType, Asc <ARInvoiceDiscountDetail.refNbr> > > > .Select(graph, doc.DocType, doc.RefNbr); foreach (ARInvoiceDiscountDetail discountDetail in discountDetailsSet) { ARInvoiceDiscountDetail newDiscountDetail = PXCache <ARInvoiceDiscountDetail> .CreateCopy(discountDetail); newDiscountDetail.DocType = graph.Document.Current.DocType; newDiscountDetail.RefNbr = graph.Document.Current.RefNbr; newDiscountDetail.IsManual = true; DiscountEngineProvider.GetEngineFor <ARTran, ARInvoiceDiscountDetail>().UpdateDiscountDetail(graph.ARDiscountDetails.Cache, graph.ARDiscountDetails, newDiscountDetail); } graph.Save.Press(); if (docType == ARDocType.CreditMemo && !OnRelease) { CreateAdjustment(graph, doc, graph.Document.Current); } }
protected virtual void ARTran_RowPersisting(PXCache sender, PXRowPersistingEventArgs e) { ARTranRUTROT row = RUTROTHelper.GetExtensionNullable <ARTran, ARTranRUTROT>(e.Row as ARTran); CheckRUTROTLine(sender, RUTROTHelper.GetExtensionNullable <ARInvoice, ARInvoiceRUTROT>(Base.Document.Current), row, Rutrots.Current); }