/// <param name="deferralCode">The item-level deferral code for <paramref name="inventoryItem"/>.</param> /// <param name="inventoryItem">The inventory item from the document line.</param> /// <param name="transactionAmount">Total transaction amount (with ALL discounts applied).</param> /// <param name="fairUnitPrice">The item price from the price list.</param> /// <param name="compoundDiscountRate"> Compound discount rate of all discounts /// (including line, group and document discounts) that are applicable to deferred components.</param> public void CreateOriginalSchedule( DRProcess.DRScheduleParameters scheduleParameters, DRDeferredCode deferralCode, InventoryItem inventoryItem, AccountSubaccountPair salesOrExpenseAccountSubaccount, decimal?transactionAmount, decimal?fairUnitPrice, decimal?compoundDiscountRate, decimal?quantityInBaseUnit) { ValidateMDAConsistency(inventoryItem, deferralCode); _schedule = _drEntityStorage.CreateCopy(scheduleParameters); _schedule.IsDraft = _isDraft; _schedule.IsCustom = false; _schedule = _drEntityStorage.Insert(_schedule); CreateDetails( scheduleParameters, deferralCode, inventoryItem, salesOrExpenseAccountSubaccount, transactionAmount, fairUnitPrice, compoundDiscountRate, quantityInBaseUnit); }
/// <summary> /// Checks the presence and consistency of deferral term start / end dates, /// as well as ensures that the document date is no later than the Term End Date /// in case recognizing in past periods is forbidden. /// </summary> /// <param name="deferralSchedule"> /// Deferral schedule from which the document date will be taken. /// </param> protected virtual void ValidateTerms(DRSchedule deferralSchedule) { if (!DeferredMethodType.RequiresTerms(_code)) { return; } if (!deferralSchedule.TermStartDate.HasValue || !deferralSchedule.TermEndDate.HasValue) { throw new PXException(Messages.CannotGenerateTransactionsWithoutTerms); } if (deferralSchedule.TermStartDate > deferralSchedule.TermEndDate) { throw new PXException( Messages.TermCantBeNegative, deferralSchedule.TermEndDate, deferralSchedule.TermStartDate); } if (_code.RecognizeInPastPeriods != true && deferralSchedule.DocDate > deferralSchedule.TermEndDate) { throw new PXException(Messages.TermEndDateIsEarlierThanDocDate, _code.DeferredCodeID); } }
/// <summary> /// Tries to perform a redirect to the original AR or AP document of a given /// <see cref="DRSchedule"/> record. /// </summary> /// <param name="sourceGraph"> /// A graph through which the redirect will be processed. /// </param> /// <param name="scheduleDetail"> /// The <see cref="DRSchedule"/> record containing the document type and /// document reference number necessary for the redirect. /// </param> public static void NavigateToOriginalDocument( PXGraph sourceGraph, DRSchedule schedule) { IBqlTable originalDocument = null; if (schedule.Module == BatchModule.AR) { originalDocument = (ARRegister) PXSelect < ARRegister, Where <ARRegister.docType, Equal <Required <DRSchedule.docType> >, And <ARRegister.refNbr, Equal <Required <DRSchedule.refNbr> > > > > .Select(sourceGraph, schedule.DocType, schedule.RefNbr); } else if (schedule.Module == BatchModule.AP) { originalDocument = (APRegister) PXSelect < APRegister, Where <APRegister.docType, Equal <Required <DRSchedule.docType> >, And <APRegister.refNbr, Equal <Required <DRSchedule.refNbr> > > > > .Select(sourceGraph, schedule.DocType, schedule.RefNbr); } if (originalDocument != null) { PXRedirectHelper.TryRedirect( sourceGraph.Caches[originalDocument.GetType()], originalDocument, "ViewDocument", PXRedirectHelper.WindowMode.NewWindow); } }
/// <param name="attachedToOriginalSchedule"> /// Flag added to handle <see cref="DRScheduleDetail"/>'s status /// in the same way as <see cref="DRProcess"/> had done for documents /// attached to original schedule. /// </param> public void ReevaluateSchedule( DRSchedule schedule, DRProcess.DRScheduleParameters scheduleParameters, DRDeferredCode deferralCode, decimal?lineAmount, bool attachedToOriginalSchedule) { _schedule = schedule; _schedule.DocDate = scheduleParameters.DocDate; _schedule.BAccountID = scheduleParameters.BAccountID; _schedule.BAccountLocID = scheduleParameters.BAccountLocID; _schedule.FinPeriodID = scheduleParameters.FinPeriodID; _schedule.TranDesc = scheduleParameters.TranDesc; _schedule.IsCustom = false; _schedule.IsDraft = _isDraft; _schedule.BAccountType = _schedule.Module == BatchModule.AP ? BAccountType.VendorType : BAccountType.CustomerType; _schedule.TermStartDate = scheduleParameters.TermStartDate; _schedule.TermEndDate = scheduleParameters.TermEndDate; _schedule.ProjectID = scheduleParameters.ProjectID; _schedule.TaskID = scheduleParameters.TaskID; _schedule = _drEntityStorage.Update(_schedule); IList <DRScheduleDetail> scheduleDetails = _drEntityStorage.GetScheduleDetails(_schedule.ScheduleID); ReevaluateComponentAmounts(scheduleDetails, lineAmount); foreach (DRScheduleDetail scheduleDetail in scheduleDetails) { scheduleDetail.DocDate = _schedule.DocDate; scheduleDetail.BAccountID = _schedule.BAccountID; scheduleDetail.FinPeriodID = _schedule.FinPeriodID; if (!attachedToOriginalSchedule) { scheduleDetail.Status = _isDraft ? DRScheduleStatus.Draft : (scheduleDetail.IsResidual == null ? DRScheduleStatus.Closed : DRScheduleStatus.Open); } else { scheduleDetail.Status = _isDraft ? DRScheduleStatus.Draft : (scheduleDetail.IsOpen == true ? DRScheduleStatus.Open : DRScheduleStatus.Closed); } _drEntityStorage.Update(scheduleDetail); if (scheduleDetail.IsResidual != true) { ReevaluateOrCreateTransactions(scheduleDetail); if (_isDraft == false) { _drEntityStorage.CreateCreditLineTransaction(scheduleDetail, deferralCode, _branchID); } } } }
/// <param name="attachedToOriginalSchedule"> /// Flag added to handle <see cref="DRScheduleDetail"/>'s status /// in the same way as <see cref="DRProcess"/> had done for documents /// attached to original schedule. /// </param> public void ReevaluateSchedule( DRSchedule schedule, DRProcess.DRScheduleParameters scheduleParameters, Amount lineAmount, bool attachedToOriginalSchedule) { if (schedule.IsOverridden == true && _isDraft == false) { decimal?totalComponentAmt = _drEntityStorage.GetScheduleDetails(schedule.ScheduleID).Sum(s => s.TotalAmt); if (totalComponentAmt != lineAmount.Cury) { throw new PXException(Messages.CannotReleaseOverriden, totalComponentAmt, lineAmount.Base, _currencyInfo.BaseCuryID); } } _dataProvider.DeleteAllDetails(schedule.ScheduleID); _schedule = schedule; _schedule.DocDate = scheduleParameters.DocDate; _schedule.BAccountID = scheduleParameters.BAccountID; _schedule.BAccountLocID = scheduleParameters.BAccountLocID; _schedule.FinPeriodID = scheduleParameters.FinPeriodID; _schedule.TranDesc = scheduleParameters.TranDesc; _schedule.IsCustom = false; _schedule.IsDraft = _isDraft; _schedule.BAccountType = _schedule.Module == BatchModule.AP ? BAccountType.VendorType : BAccountType.CustomerType; _schedule.TermStartDate = scheduleParameters.TermStartDate; _schedule.TermEndDate = scheduleParameters.TermEndDate; _schedule.ProjectID = scheduleParameters.ProjectID; _schedule.TaskID = scheduleParameters.TaskID; _schedule = _drEntityStorage.Update(_schedule); CreateScheduleDetails(scheduleParameters, lineAmount); }
public virtual IEnumerable Recalculate(PXAdapter adapter) { DRSchedule schedule = Base.DocumentProperties.Current; if (schedule.IsOverridden == true) { WebDialogResult result = Base.DocumentProperties.View.Ask( Base.DocumentProperties.Current, GL.Messages.Confirmation, Messages.ClearOverriden, MessageButtons.YesNo, MessageIcon.Question); if (result != WebDialogResult.Yes) { return(adapter.Get()); } } schedule.IsOverridden = false; schedule.IsRecalculated = false; Base.DocumentProperties.Update(schedule); SingleScheduleCreator.RecalculateSchedule(Base); return(adapter.Get()); }
public virtual IEnumerable associated([PXDBString] string scheduleNbr) { IEnumerable emptyScheduleList = new List <DraftScheduleMaint.DRScheduleEx>(); if (scheduleNbr == null) { return(emptyScheduleList); } DRSchedule deferralSchedule = PXSelect <DRSchedule, Where <DRSchedule.scheduleID, Equal <Current <DRScheduleDetail.scheduleID> > > > .Select(Base); if (deferralSchedule == null) { return(emptyScheduleList); } if (deferralSchedule.Module == BatchModule.AR) { if (deferralSchedule.DocType == ARDocType.CreditMemo) { var scheduleDetailsByDocumentLine = PXSelectJoin <DraftScheduleMaint.DRScheduleEx, InnerJoin <ARTran, On <DraftScheduleMaint.DRScheduleEx.scheduleID, Equal <ARTran.defScheduleID> > >, Where <ARTran.tranType, Equal <Current <DraftScheduleMaint.DRScheduleEx.docType> >, And <ARTran.refNbr, Equal <Current <DraftScheduleMaint.DRScheduleEx.refNbr> > > > > .Select(Base); if (scheduleDetailsByDocumentLine != null && scheduleDetailsByDocumentLine.Count > 0) { return(scheduleDetailsByDocumentLine); } } else if (deferralSchedule.DocType == ARDocType.Invoice || deferralSchedule.DocType == ARDocType.DebitMemo) { var list = new List <DraftScheduleMaint.DRScheduleEx>(); foreach (DraftScheduleMaint.DRScheduleEx dRScheduleEx in PXSelectJoin <DraftScheduleMaint.DRScheduleEx, InnerJoin <ARTran, On <DraftScheduleMaint.DRScheduleEx.module, Equal <BatchModule.moduleAR>, And <DraftScheduleMaint.DRScheduleEx.docType, Equal <ARTran.tranType>, And <DraftScheduleMaint.DRScheduleEx.refNbr, Equal <ARTran.refNbr> > > > >, Where <ARTran.defScheduleID, Equal <Current <DRScheduleDetail.scheduleID> > > > .Select(Base)) { list.Add(dRScheduleEx); } return(list); } } else if (deferralSchedule.Module == BatchModule.AP) { return(Base.associated(scheduleNbr)); } return(emptyScheduleList); }
/// <summary> /// Tries to perform a redirect to the original AR or AP document of a given /// <see cref="DRScheduleDetail"/>. /// </summary> /// <param name="sourceGraph"> /// A graph through which the redirect will be processed. /// </param> /// <param name="scheduleDetail"> /// The <see cref="DRScheduleDetail"/> object containing the document type and /// document reference number necessary for the redirect. /// </param> public static void NavigateToOriginalDocument( PXGraph sourceGraph, DRScheduleDetail scheduleDetail) { DRSchedule correspondingSchedule = PXSelect < DRSchedule, Where <DRSchedule.scheduleID, Equal <Required <DRScheduleDetail.scheduleID> > > > .Select(sourceGraph, scheduleDetail.ScheduleID); NavigateToOriginalDocument(sourceGraph, correspondingSchedule); }
/// <param name="deferralCode">The item-level deferral code for the inventory item /// <param name="transactionAmount">Total transaction amount (with ALL discounts applied).</param> /// <param name="fairUnitPrice">The item price from the price list.</param> /// <param name="compoundDiscountRate"> Compound discount rate of all discounts /// (including line, group and document discounts) that are applicable to deferred components.</param> public void CreateOriginalSchedule( DRProcess.DRScheduleParameters scheduleParameters, Amount lineTotal) { _schedule = _drEntityStorage.CreateCopy(scheduleParameters); _schedule.IsDraft = _isDraft; _schedule.IsCustom = false; _schedule = _drEntityStorage.Insert(_schedule); CreateScheduleDetails(scheduleParameters, lineTotal); }
private void SetDRCounterOnOrigDoc(DRSchedule row) { ARRegister previousDocAttached = PXSelect <ARRegister, Where <ARRegister.docType, Equal <Required <DRSchedule.docType> >, And <ARRegister.refNbr, Equal <Required <DRSchedule.refNbr> > > > > .Select(Base, row.DocType, row.RefNbr); previousDocAttached.DRSchedCntr = PXSelect <ARTran, Where <ARTran.tranType, Equal <Required <ARInvoice.docType> >, And <ARTran.refNbr, Equal <Required <ARInvoice.refNbr> >, And <ARTran.deferredCode, IsNotNull, And <Where < ARTran.lineType, IsNull, Or <ARTran.lineType, NotEqual <SO.SOLineType.discount> > > > > > > > .Select(Base, row.DocType, row.RefNbr).Count; OriginalDocument.Update(previousDocAttached); }
/// <summary> /// Tries to perform a redirect to a deferral schedule by its ID. /// Does nothing if the provided ID value is <c>null</c>. /// </summary> /// <param name="sourceGraph"> /// A graph through which the redirect will be processed. /// </param> /// <param name="scheduleID"> /// The unique identifier of a <see cref="DRSchedule"/> record which /// the user should be redirected to.</param> public static void NavigateToDeferralSchedule(PXGraph sourceGraph, int?scheduleID) { DRSchedule deferralSchedule = PXSelect < DRSchedule, Where < DRSchedule.scheduleID, Equal <Required <DRSchedule.scheduleID> > > > .Select(sourceGraph, scheduleID); if (deferralSchedule != null) { PXRedirectHelper.TryRedirect( sourceGraph.Caches[typeof(DRSchedule)], deferralSchedule, "ViewDocument", PXRedirectHelper.WindowMode.NewWindow); } }
public static void ViewScheduleForDocument(PXGraph graph, ARInvoice document) { PXSelectBase <DRSchedule> correspondingScheduleView = new PXSelect < DRSchedule, Where < DRSchedule.module, Equal <BatchModule.moduleAR>, And <DRSchedule.docType, Equal <Required <ARTran.tranType> >, And <DRSchedule.refNbr, Equal <Required <ARTran.refNbr> > > > > > (graph); DRSchedule correspondingSchedule = correspondingScheduleView.Select(document.DocType, document.RefNbr); if (correspondingSchedule?.LineNbr != null && document.Released == false) { throw new PXException(Messages.CantCompleteBecauseASC606FeatureIsEnabled); } if (correspondingSchedule?.IsOverridden != true && document.Released == false) { var netLinesAmount = ASC606Helper.CalculateNetAmount(graph, document); int?defScheduleID = null; if (netLinesAmount.Cury != 0m) { DRSingleProcess process = PXGraph.CreateInstance <DRSingleProcess>(); process.CreateSingleSchedule(document, netLinesAmount, defScheduleID, true); process.Actions.PressSave(); correspondingScheduleView.Cache.Clear(); correspondingScheduleView.Cache.ClearQueryCacheObsolete(); correspondingScheduleView.View.Clear(); correspondingSchedule = correspondingScheduleView.Select(document.DocType, document.RefNbr); } } if (correspondingSchedule != null) { PXRedirectHelper.TryRedirect( graph.Caches[typeof(DRSchedule)], correspondingSchedule, "View Schedule", PXRedirectHelper.WindowMode.NewWindow); } }
public static void SetFairValueSalesPrice(DRSchedule schedule, DRScheduleDetail scheduleDetail, PXSelectBase <DRScheduleDetail> scheduleDetailsView, Location location, CurrencyInfo currencyInfo, bool takeInBaseCurrency) { if (takeInBaseCurrency) { currencyInfo.CuryID = currencyInfo.BaseCuryID; } var salesPriceItem = ARSalesPriceMaint.CalculateFairValueSalesPrice(scheduleDetailsView.Cache, location?.CPriceClassID, schedule.BAccountID, scheduleDetail.ComponentID, currencyInfo, scheduleDetail.Qty, scheduleDetail.UOM, schedule.DocDate.Value, takeInBaseCurrency); var newValue = salesPriceItem.Price; if (newValue == 0m) { InventoryItem inventoryItem = PXSelect < InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(scheduleDetailsView.Cache.Graph, scheduleDetail.ComponentID); if (scheduleDetail.ParentInventoryID == null) { throw new NoFairValuePriceFoundException(inventoryItem.InventoryCD, scheduleDetail.UOM, currencyInfo.CuryID, schedule.DocDate.Value); } else { InventoryItem parentInventoryItem = PXSelect < InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(scheduleDetailsView.Cache.Graph, scheduleDetail.ParentInventoryID); throw new NoFairValuePriceFoundException(inventoryItem.InventoryCD, parentInventoryItem.InventoryCD, scheduleDetail.UOM, currencyInfo.CuryID, schedule.DocDate.Value); } } scheduleDetail.FairValueCuryID = salesPriceItem.CuryID; scheduleDetail.FairValuePrice = newValue; scheduleDetail.EffectiveFairValuePrice = newValue * (salesPriceItem.Prorated ? scheduleDetail.CoTermRate : 1); }
public virtual IEnumerable ViewDoc(PXAdapter adapter) { DRSchedule sc = PXSelect <DRSchedule, Where <DRSchedule.scheduleID, Equal <Current <DRScheduleTran.scheduleID> > > > .Select(this); if (sc != null) { switch (sc.Module) { case BatchModule.AR: ARInvoiceEntry arTarget = PXGraph.CreateInstance <ARInvoiceEntry>(); arTarget.Clear(); ARInvoice invoice = PXSelect <ARInvoice, Where <ARInvoice.docType, Equal <Required <DRScheduleDetail.docType> >, And <ARInvoice.refNbr, Equal <Required <DRScheduleDetail.refNbr> > > > > .Select(this, sc.DocType, sc.RefNbr); if (invoice != null) { arTarget.Document.Current = invoice; throw new PXRedirectRequiredException(arTarget, true, "ViewDocument") { Mode = PXBaseRedirectException.WindowMode.NewWindow }; } break; case BatchModule.AP: APInvoiceEntry apTarget = PXGraph.CreateInstance <APInvoiceEntry>(); apTarget.Clear(); APInvoice invoice2 = PXSelect <APInvoice, Where <APInvoice.docType, Equal <Required <DRScheduleDetail.docType> >, And <APInvoice.refNbr, Equal <Required <DRScheduleDetail.refNbr> > > > > .Select(this, sc.DocType, sc.RefNbr); if (invoice2 != null) { apTarget.Document.Current = invoice2; throw new PXRedirectRequiredException(apTarget, true, "ViewInvoice") { Mode = PXBaseRedirectException.WindowMode.NewWindow }; } break; } } return(adapter.Get()); }
public virtual void ReverseDRSchedule(ARRegister doc, ARTran tran, ReverseDRScheduleDelegate baseDelegate) { if (string.IsNullOrEmpty(tran.DeferredCode)) { return; } DRSchedule schedule = PXSelect <DRSchedule, Where <DRSchedule.module, Equal <BatchModule.moduleAR>, And <DRSchedule.docType, Equal <Required <DRSchedule.docType> >, And <DRSchedule.refNbr, Equal <Required <DRSchedule.refNbr> > > > > > . Select(Base, doc.DocType, doc.RefNbr, tran.LineNbr); if (schedule != null) { tran.DefScheduleID = schedule.ScheduleID; } }
private void VerifySchedule(DRSchedule schedule) { if (schedule.RefNbr == null || (schedule.NetTranPrice ?? 0m) == 0) { return; } var currencyInfo = Base.CurrencyInfo.SelectSingle(); if (schedule.IsCustom == true && schedule.NetTranPrice < schedule.ComponentsTotal) { throw new PXException(Messages.CannotAttachCustom, schedule.ComponentsTotal, schedule.NetTranPrice, currencyInfo.BaseCuryID); } if (schedule.NetTranPrice != schedule.ComponentsTotal && schedule.IsOverridden == true) { throw new PXException(Messages.CannotModifyAttached, schedule.ComponentsTotal, schedule.NetTranPrice, currencyInfo.BaseCuryID); } }
public static Amount CalculateSalesPostingAmount(PXGraph graph, DRSchedule customSchedule) { var netLinesAmount = new Amount(0m, 0m); var processedTrans = new HashSet <ARTran>(); foreach (PXResult <ARTran, ARRegister, ARTax, Tax> item in PXSelectJoin < ARTran, InnerJoin <ARRegister, On <ARTran.tranType, Equal <ARRegister.docType>, And <ARTran.refNbr, Equal <ARRegister.refNbr> > >, LeftJoin <ARTax, On <ARTran.tranType, Equal <ARTax.tranType>, And <ARTran.refNbr, Equal <ARTax.refNbr>, And <ARTran.lineNbr, Equal <ARTax.lineNbr> > > >, LeftJoin <Tax, On <Tax.taxID, Equal <ARTax.taxID> > > > >, Where <ARTran.tranType, Equal <Required <ARInvoice.docType> >, And <ARTran.refNbr, Equal <Required <ARInvoice.refNbr> >, And <ARTran.deferredCode, IsNull, And <Where <ARTran.lineType, IsNull, Or <ARTran.lineType, NotEqual <SO.SOLineType.discount> > > > > > > > .Select(graph, customSchedule.DocType, customSchedule.RefNbr)) { ARTran line = item; ARRegister register = item; ARTax artax = item; Tax tax = item; if (processedTrans.Contains(line)) { continue; } var netLineAmount = ARReleaseProcess.GetSalesPostingAmount(graph, register, line, artax, tax, amnt => PXDBCurrencyAttribute.Round(graph.Caches[typeof(ARTran)], line, amnt, CMPrecision.TRANCURY)); netLinesAmount += netLineAmount; processedTrans.Add(line); } return(netLinesAmount); }
/// <summary> /// Checks the presence and consistency of deferral term start / end dates, /// as well as ensures that the document date is no later than the Term End Date /// in case recognizing in past periods is forbidden. /// </summary> /// <param name="deferralSchedule"> /// Deferral schedule from which the document date will be taken. /// </param> protected virtual void ValidateTerms(DRSchedule deferralSchedule) { if (!DeferredMethodType.RequiresTerms(_code)) { return; } if (!deferralSchedule.TermStartDate.HasValue || !deferralSchedule.TermEndDate.HasValue) { throw new PXException(Messages.CannotGenerateTransactionsWithoutTerms); } if (deferralSchedule.TermStartDate > deferralSchedule.TermEndDate) { throw new PXException( Messages.TermCantBeNegative, deferralSchedule.TermEndDate, deferralSchedule.TermStartDate); } }
protected virtual void DRSchedule_RowSelected(PXCache sender, PXRowSelectedEventArgs e) { DRSchedule row = e.Row as DRSchedule; if (row != null) { row.DocumentType = DRScheduleDocumentType.BuildDocumentType(row.Module, row.DocType); if (row.Module == BatchModule.AR) { row.BAccountType = CR.BAccountType.CustomerType; ARTran tran = PXSelect <ARTran, Where <ARTran.tranType, Equal <Current <DRSchedule.docType> >, And <ARTran.refNbr, Equal <Current <DRSchedule.refNbr> >, And <ARTran.lineNbr, Equal <Current <DRSchedule.lineNbr> > > > > > .Select(this); if (tran != null) { row.OrigLineAmt = tran.TranAmt; } } else { row.BAccountType = CR.BAccountType.VendorType; APTran tran = PXSelect <APTran, Where <APTran.tranType, Equal <Current <DRSchedule.docType> >, And <APTran.refNbr, Equal <Current <DRSchedule.refNbr> >, And <APTran.lineNbr, Equal <Current <DRSchedule.lineNbr> > > > > > .Select(this); if (tran != null) { row.OrigLineAmt = tran.TranAmt; } } PXUIFieldAttribute.SetVisible <DRSchedule.origLineAmt>(sender, row, row.IsCustom != true); } }
private static void DeleteAssociatedScheduleIfDeferralCodeChanged( PXGraph graph, IDocumentLine documentLine, IDocumentLine oldLine) { bool deferralCodeRemoved = documentLine.DeferredCode == null; bool deferralCodeChanged = oldLine?.DeferredCode != null && documentLine.DeferredCode != null && oldLine.DeferredCode != documentLine.DeferredCode; if (deferralCodeRemoved || deferralCodeChanged) { DRSchedule correspondingSchedule = PXSelect < DRSchedule, Where <DRSchedule.module, Equal <Required <DRSchedule.module> >, And <DRSchedule.docType, Equal <Required <DRSchedule.docType> >, And <DRSchedule.refNbr, Equal <Required <DRSchedule.refNbr> >, And <DRSchedule.lineNbr, Equal <Required <DRSchedule.lineNbr> > > > > > > .Select( graph, documentLine.Module, documentLine.TranType, documentLine.RefNbr, documentLine.LineNbr); if (correspondingSchedule == null) { return; } DraftScheduleMaint scheduleGraph = PXGraph.CreateInstance <DraftScheduleMaint>(); scheduleGraph.Schedule.Delete(correspondingSchedule); scheduleGraph.Save.Press(); } }
/// <summary> /// Checks if deferral code has been changed or removed from the line. /// If so, ensures the removal of any associated deferral schedules. /// </summary> public static void DeleteAssociatedScheduleIfDeferralCodeChanged( PXGraph graph, IDocumentLine documentLine) { IDocumentLine oldLine; // Obtain the document line last saved into the database // to check if the new line's deferral code differs from it. // - if (documentLine.Module == GL.BatchModule.AR) { oldLine = (ARTran)PXSelectReadonly < ARTran, Where < ARTran.tranType, Equal <Required <ARTran.tranType> >, And <ARTran.refNbr, Equal <Required <ARTran.refNbr> >, And <ARTran.lineNbr, Equal <Required <ARTran.lineNbr> > > > > > .Select(graph, documentLine.TranType, documentLine.RefNbr, documentLine.LineNbr); } else if (documentLine.Module == GL.BatchModule.AP) { oldLine = (APTran)PXSelectReadonly < APTran, Where < APTran.tranType, Equal <Required <APTran.tranType> >, And <APTran.refNbr, Equal <Required <APTran.refNbr> >, And <APTran.lineNbr, Equal <Required <APTran.lineNbr> > > > > > .Select(graph, documentLine.TranType, documentLine.RefNbr, documentLine.LineNbr); } else { throw new PXException(Messages.UnexpectedDocumentLineModule); } DRSchedule correspondingSchedule = PXSelect < DRSchedule, Where < DRSchedule.module, Equal <Required <DRSchedule.module> >, And <DRSchedule.docType, Equal <Required <DRSchedule.docType> >, And <DRSchedule.refNbr, Equal <Required <DRSchedule.refNbr> >, And <DRSchedule.lineNbr, Equal <Required <DRSchedule.lineNbr> > > > > > > .Select( graph, documentLine.Module, documentLine.TranType, documentLine.RefNbr, documentLine.LineNbr); if (correspondingSchedule == null) { return; } bool deferralCodeRemoved = documentLine.DeferredCode == null; bool deferralCodeChanged = oldLine?.DeferredCode != null && documentLine.DeferredCode != null && oldLine.DeferredCode != documentLine.DeferredCode; if (deferralCodeRemoved || deferralCodeChanged) { DraftScheduleMaint scheduleGraph = PXGraph.CreateInstance <DraftScheduleMaint>(); scheduleGraph.Schedule.Current = correspondingSchedule; scheduleGraph .Components .Select() .ForEach(component => scheduleGraph.Components.Delete(component)); scheduleGraph.Schedule.Delete(correspondingSchedule); scheduleGraph.Save.Press(); } }
public virtual IList <DRScheduleTran> GenerateTransactions( DRSchedule deferralSchedule, DRScheduleDetail scheduleDetail) { if (deferralSchedule == null) { throw new ArgumentNullException(nameof(deferralSchedule)); } if (scheduleDetail == null) { throw new ArgumentNullException(nameof(scheduleDetail)); } if (PXAccess.FeatureInstalled <CS.FeaturesSet.aSC606>()) { ValidateTerms(scheduleDetail); } else { ValidateTerms(deferralSchedule); } int? organizationID = PXAccess.GetParentOrganizationID(scheduleDetail.BranchID); decimal defAmount = scheduleDetail.TotalAmt.Value; List <DRScheduleTran> list = new List <DRScheduleTran>(); short lineCounter = 0; if (_code.ReconNowPct.Value > 0) { decimal recNowRaw = defAmount * _code.ReconNowPct.Value * 0.01m; decimal recNow = _roundingFunction(recNowRaw); defAmount -= recNow; lineCounter++; DRScheduleTran nowTran = new DRScheduleTran { BranchID = scheduleDetail.BranchID, AccountID = scheduleDetail.AccountID, SubID = scheduleDetail.SubID, Amount = recNow, RecDate = deferralSchedule.DocDate, FinPeriodID = scheduleDetail.FinPeriodID, TranPeriodID = scheduleDetail.TranPeriodID, LineNbr = lineCounter, DetailLineNbr = scheduleDetail.DetailLineNbr, ScheduleID = scheduleDetail.ScheduleID, ComponentID = scheduleDetail.ComponentID, Status = GetStatus(), }; list.Add(nowTran); } bool isFlexibleDeferralCode = DeferredMethodType.RequiresTerms(_code.Method); DateTime?termStartDate = null; DateTime?termEndDate = null; if (isFlexibleDeferralCode) { bool isASC606 = PXAccess.FeatureInstalled <CS.FeaturesSet.aSC606>(); termStartDate = isASC606 ? scheduleDetail.TermStartDate.Value : deferralSchedule.TermStartDate.Value; termEndDate = isASC606 ? scheduleDetail.TermEndDate.Value : deferralSchedule.TermEndDate.Value; } DateTime documentDate = deferralSchedule.DocDate.Value; FinPeriod documentFinPeriod = _finPeriodRepository.FindFinPeriodByDate(documentDate, organizationID); int occurrences = isFlexibleDeferralCode ? CalcOccurrences(termStartDate.Value, termEndDate.Value, organizationID) : _code.Occurrences.Value; List <DRScheduleTran> deferredList = new List <DRScheduleTran>(_code.Occurrences.Value); FinPeriod deferredPeriod = null; for (int i = 0; i < occurrences; i++) { try { if (deferredPeriod == null) { deferredPeriod = isFlexibleDeferralCode ? _finPeriodRepository.FindFinPeriodByDate(termStartDate, organizationID): _finPeriodRepository.GetOffsetPeriod(scheduleDetail.FinPeriodID, _code.StartOffset.Value, organizationID); } else { deferredPeriod = _finPeriodRepository.GetOffsetPeriod(deferredPeriod.FinPeriodID, _code.Frequency.Value, organizationID); } } catch (PXFinPeriodException ex) { throw new PXException(ex, Messages.NoFinPeriod, _code.DeferredCodeID); } lineCounter++; DateTime recognitionDate = GetRecognitionDate( deferredPeriod.FinPeriodID, minimumDate: isFlexibleDeferralCode ? termStartDate.Value : documentDate, maximumDate: isFlexibleDeferralCode ? termEndDate : null, organizationID: organizationID); FinPeriod finPeriod = _finPeriodRepository.FindFinPeriodByDate(recognitionDate, organizationID); DRScheduleTran deferralTransaction = new DRScheduleTran { BranchID = scheduleDetail.BranchID, AccountID = scheduleDetail.AccountID, SubID = scheduleDetail.SubID, RecDate = recognitionDate, FinPeriodID = finPeriod?.FinPeriodID, TranPeriodID = finPeriod?.MasterFinPeriodID, LineNbr = lineCounter, DetailLineNbr = scheduleDetail.DetailLineNbr, ScheduleID = scheduleDetail.ScheduleID, ComponentID = scheduleDetail.ComponentID, Status = GetStatus(), }; deferredList.Add(deferralTransaction); } SetAmounts(deferredList, defAmount, deferralSchedule.DocDate, termStartDate, termEndDate, organizationID); if (DeferredMethodType.RequiresTerms(_code) && _code.RecognizeInPastPeriods != true) { // Adjust recognition dates and financial periods // that are in the past relative to the document date. // - foreach (DRScheduleTran transaction in deferredList .Where(transaction => transaction.RecDate < documentDate)) { transaction.RecDate = documentDate; transaction.FinPeriodID = documentFinPeriod?.FinPeriodID; transaction.TranPeriodID = documentFinPeriod?.MasterFinPeriodID; } } list.AddRange(deferredList); return(list); }
protected virtual IEnumerable items() { ScheduleRecognitionFilter filter = Filter.Current; if (filter == null) { yield break; } bool found = false; foreach (ScheduledTran item in Items.Cache.Inserted) { found = true; yield return(item); } if (found) { yield break; } PXSelectBase <DRScheduleTran> select = new PXSelectJoin <DRScheduleTran, InnerJoin <DRScheduleDetail, On <DRScheduleTran.scheduleID, Equal <DRScheduleDetail.scheduleID>, And <DRScheduleTran.componentID, Equal <DRScheduleDetail.componentID> > >, InnerJoin <DRSchedule, On <DRScheduleTran.scheduleID, Equal <DRSchedule.scheduleID> >, LeftJoin <InventoryItem, On <DRScheduleTran.componentID, Equal <InventoryItem.inventoryID> > > > >, Where <DRScheduleTran.recDate, LessEqual <Current <ScheduleRecognitionFilter.recDate> >, And <DRScheduleTran.status, Equal <DRScheduleTranStatus.OpenStatus>, And <DRScheduleDetail.status, NotEqual <DRScheduleStatus.DraftStatus> > > >, OrderBy <Asc <DRScheduleTran.scheduleID, Asc <DRScheduleTran.componentID, Asc <DRScheduleTran.recDate, Asc <DRScheduleTran.lineNbr> > > > > >(this); if (!string.IsNullOrEmpty(filter.DeferredCode)) { select.WhereAnd <Where <DRScheduleDetail.defCode, Equal <Current <ScheduleRecognitionFilter.deferredCode> > > >(); } if (filter.BranchID != null) { select.WhereAnd <Where <DRScheduleDetail.branchID, Equal <Current <ScheduleRecognitionFilter.branchID> > > >(); } Dictionary <string, string> added = new Dictionary <string, string>(); foreach (PXResult <DRScheduleTran, DRScheduleDetail, DRSchedule, InventoryItem> resultSet in select.Select()) { DRScheduleTran tran = (DRScheduleTran)resultSet; DRSchedule schedule = (DRSchedule)resultSet; DRScheduleDetail scheduleDetail = (DRScheduleDetail)resultSet; InventoryItem item = (InventoryItem)resultSet; string key = string.Format("{0}.{1}", tran.ScheduleID, tran.ComponentID); bool doInsert = false; if (added.ContainsKey(key)) { string addedFinPeriod = added[key]; if (tran.FinPeriodID == addedFinPeriod) { doInsert = true; } } else { doInsert = true; added.Add(key, tran.FinPeriodID); } if (doInsert) { ScheduledTran result = new ScheduledTran(); result.BranchID = tran.BranchID; result.AccountID = tran.AccountID; result.Amount = tran.Amount; result.ComponentID = tran.ComponentID; result.DefCode = scheduleDetail.DefCode; result.FinPeriodID = tran.FinPeriodID; result.LineNbr = tran.LineNbr; result.RecDate = tran.RecDate; result.ScheduleID = tran.ScheduleID; result.ScheduleNbr = schedule.ScheduleNbr; result.SubID = tran.SubID; result.ComponentCD = item.InventoryCD; result.DocType = DRScheduleDocumentType.BuildDocumentType(scheduleDetail.Module, scheduleDetail.DocType); Items.Cache.SetStatus(result, PXEntryStatus.Inserted); yield return(result); // Items.Insert(result); } } //Virtual Records (CashReceipt): PXSelectBase <ARInvoice> s = null; if (!string.IsNullOrEmpty(filter.DeferredCode)) { s = new PXSelectJoinGroupBy <ARInvoice, InnerJoin <ARTran, On <ARTran.tranType, Equal <ARInvoice.docType>, And <ARTran.refNbr, Equal <ARInvoice.refNbr> > >, InnerJoin <DRDeferredCode, On <ARTran.deferredCode, Equal <DRDeferredCode.deferredCodeID>, And <DRDeferredCode.method, Equal <DeferredMethodType.cashReceipt>, And <DRDeferredCode.deferredCodeID, Equal <Current <ScheduleRecognitionFilter.deferredCode> > > > >, InnerJoin <DRSchedule, On <ARTran.tranType, Equal <DRSchedule.docType>, And <ARTran.refNbr, Equal <DRSchedule.refNbr>, And <ARTran.lineNbr, Equal <DRSchedule.lineNbr> > > >, InnerJoin <DRScheduleDetail, On <DRSchedule.scheduleID, Equal <DRScheduleDetail.scheduleID> > > > > >, Where <ARInvoice.released, Equal <True>, And <DRScheduleDetail.isOpen, Equal <True> > >, Aggregate <GroupBy <ARInvoice.docType, GroupBy <ARInvoice.refNbr> > > >(this); } else { s = new PXSelectJoinGroupBy <ARInvoice, InnerJoin <ARTran, On <ARTran.tranType, Equal <ARInvoice.docType>, And <ARTran.refNbr, Equal <ARInvoice.refNbr> > >, InnerJoin <DRDeferredCode, On <ARTran.deferredCode, Equal <DRDeferredCode.deferredCodeID>, And <DRDeferredCode.method, Equal <DeferredMethodType.cashReceipt> > >, InnerJoin <DRSchedule, On <ARTran.tranType, Equal <DRSchedule.docType>, And <ARTran.refNbr, Equal <DRSchedule.refNbr>, And <ARTran.lineNbr, Equal <DRSchedule.lineNbr> > > >, InnerJoin <DRScheduleDetail, On <DRSchedule.scheduleID, Equal <DRScheduleDetail.scheduleID> > > > > >, Where <ARInvoice.released, Equal <True>, And <DRScheduleDetail.isOpen, Equal <True> > >, Aggregate <GroupBy <ARInvoice.docType, GroupBy <ARInvoice.refNbr> > > >(this); } foreach (ARInvoice inv in s.Select()) { PXSelectBase <ARTran> trs = new PXSelectJoin <ARTran, InnerJoin <DRDeferredCode, On <ARTran.deferredCode, Equal <DRDeferredCode.deferredCodeID>, And <DRDeferredCode.method, Equal <DeferredMethodType.cashReceipt> > > >, Where <ARTran.tranType, Equal <Required <ARTran.tranType> >, And <ARTran.refNbr, Equal <Required <ARTran.refNbr> > > > >(this); foreach (PXResult <ARTran, DRDeferredCode> res in trs.Select(inv.DocType, inv.RefNbr)) { List <ScheduledTran> virtualRecords = new List <ScheduledTran>(); List <ScheduledTran> virtualVoidedRecords = new List <ScheduledTran>(); ARTran tr = (ARTran)res; DRDeferredCode dc = (DRDeferredCode)res; decimal trPart = 0; if (inv.LineTotal.Value != 0) { trPart = tr.TranAmt.Value / inv.LineTotal.Value; } decimal trPartRest = tr.TranAmt.Value; InventoryItem invItem = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(this, tr.InventoryID); //NOTE: Multiple Components are not supported in CashReceipt Deferred Revenue Recognition. DRSchedule schedule = GetScheduleByFID(BatchModule.AR, inv.DocType, inv.RefNbr, tr.LineNbr); DRScheduleDetail scheduleDetail = GetScheduleDetailbyID(schedule.ScheduleID, tr.InventoryID != null ? tr.InventoryID : DRScheduleDetail.EmptyComponentID); int lineNbr = scheduleDetail.LineCntr ?? 0; PXSelectBase <ARAdjust> ads = new PXSelectJoin <ARAdjust, LeftJoin <DRScheduleTran, On <ARAdjust.adjgDocType, Equal <DRScheduleTran.adjgDocType>, And <ARAdjust.adjgRefNbr, Equal <DRScheduleTran.adjgRefNbr> > > >, Where <ARAdjust.adjdDocType, Equal <Required <ARAdjust.adjdDocType> >, And <ARAdjust.adjdRefNbr, Equal <Required <ARAdjust.adjdRefNbr> >, And <DRScheduleTran.scheduleID, IsNull, And <ARAdjust.adjgDocType, NotEqual <ARDocType.creditMemo> > > > >, OrderBy <Asc <ARAdjust.adjgDocDate> > >(this); foreach (ARAdjust ad in ads.Select(inv.DocType, inv.RefNbr)) { lineNbr++; decimal amtRaw = Math.Min(trPart * ad.AdjAmt.Value, trPartRest); trPartRest -= amtRaw; decimal amt = PXDBCurrencyAttribute.BaseRound(this, amtRaw); ScheduledTran result = new ScheduledTran(); result.BranchID = ad.AdjgBranchID; result.Amount = amt; result.ComponentID = tr.InventoryID; result.DefCode = tr.DeferredCode; result.FinPeriodID = FinPeriodRepository.GetPeriodIDFromDate(ad.AdjgDocDate, PXAccess.GetParentOrganizationID(ad.AdjgBranchID)); result.LineNbr = lineNbr; result.Module = schedule.Module; result.RecDate = ad.AdjgDocDate; result.ScheduleID = schedule.ScheduleID; result.ScheduleNbr = schedule.ScheduleNbr; result.DocType = schedule.DocType; result.AdjgDocType = ad.AdjgDocType; result.AdjgRefNbr = ad.AdjgRefNbr; result.AdjNbr = ad.AdjNbr; result.IsVirtual = true; result.AccountID = scheduleDetail.AccountID; result.SubID = scheduleDetail.SubID; result.ComponentCD = invItem == null ? "" : invItem.InventoryCD; if (ad.Voided == true) { if (ad.AdjgDocType == ARDocType.VoidPayment && virtualVoidedRecords.Count > 0) { ScheduledTran tran = virtualVoidedRecords.Where <ScheduledTran>(v => (v.AdjgDocType == ARDocType.Payment && v.AdjgRefNbr == ad.AdjgRefNbr && v.AdjNbr == ad.AdjNbr)).First <ScheduledTran>(); if (tran != null) { virtualVoidedRecords.Remove(tran); } } else { virtualVoidedRecords.Add(result); } } else { virtualRecords.Add(result); } } foreach (ScheduledTran v in virtualRecords) { Items.Cache.SetStatus(v, PXEntryStatus.Inserted); yield return(v); // Items.Insert(v); } foreach (ScheduledTran v in virtualVoidedRecords) { Items.Cache.SetStatus(v, PXEntryStatus.Inserted); yield return(v); // Items.Insert(v); } } } Items.Cache.IsDirty = false; }
/// <param name="attachedToOriginalSchedule"> /// Flag added to handle <see cref="DRScheduleDetail"/>'s status /// in the same way as <see cref="DRProcess"/> had done for documents /// attached to original schedule. /// </param> public void ReevaluateSchedule( DRSchedule schedule, DRProcess.DRScheduleParameters scheduleParameters, DRDeferredCode deferralCode, decimal?lineAmount, bool attachedToOriginalSchedule) { _schedule = schedule; _schedule.DocDate = scheduleParameters.DocDate; _schedule.BAccountID = scheduleParameters.BAccountID; _schedule.BAccountLocID = scheduleParameters.BAccountLocID; _schedule.FinPeriodID = scheduleParameters.FinPeriodID; _schedule.TranDesc = scheduleParameters.TranDesc; _schedule.IsCustom = false; _schedule.IsDraft = _isDraft; _schedule.BAccountType = _schedule.Module == BatchModule.AP ? BAccountType.VendorType : BAccountType.CustomerType; _schedule.TermStartDate = scheduleParameters.TermStartDate; _schedule.TermEndDate = scheduleParameters.TermEndDate; _schedule.ProjectID = scheduleParameters.ProjectID; _schedule.TaskID = scheduleParameters.TaskID; _schedule = _drEntityStorage.Update(_schedule); IList <DRScheduleDetail> scheduleDetails = _drEntityStorage.GetScheduleDetails(_schedule.ScheduleID); ReevaluateComponentAmounts(scheduleDetails, lineAmount); foreach (DRScheduleDetail scheduleDetail in scheduleDetails) { scheduleDetail.DocDate = _schedule.DocDate; scheduleDetail.BAccountID = _schedule.BAccountID; FinPeriod detailFinPeriod = FinPeriodRepository .GetFinPeriodByMasterPeriodID(PXAccess.GetParentOrganizationID(scheduleDetail.BranchID), _schedule.FinPeriodID).GetValueOrRaiseError(); scheduleDetail.FinPeriodID = detailFinPeriod.FinPeriodID; scheduleDetail.TranPeriodID = detailFinPeriod.MasterFinPeriodID; if (!attachedToOriginalSchedule) { scheduleDetail.Status = _isDraft ? DRScheduleStatus.Draft : (scheduleDetail.IsResidual == null ? DRScheduleStatus.Closed : DRScheduleStatus.Open); } else { scheduleDetail.Status = _isDraft ? DRScheduleStatus.Draft : (scheduleDetail.IsOpen == true ? DRScheduleStatus.Open : DRScheduleStatus.Closed); } _drEntityStorage.Update(scheduleDetail); if (scheduleDetail.IsResidual != true) { DRDeferredCode detailDeferralCode = _drEntityStorage.GetDeferralCode(scheduleDetail.DefCode); IEnumerable <DRScheduleTran> componentTransactions = _drEntityStorage.GetDeferralTransactions(scheduleDetail.ScheduleID, scheduleDetail.ComponentID, scheduleDetail.DetailLineNbr); if (componentTransactions.Any()) { ReevaluateTransactionAmounts(scheduleDetail, detailDeferralCode, componentTransactions); } if (!_isDraft) { if (!componentTransactions.Any()) { componentTransactions = _drEntityStorage.CreateDeferralTransactions(_schedule, scheduleDetail, detailDeferralCode, _branchID); } _drEntityStorage.CreateCreditLineTransaction(scheduleDetail, deferralCode, _branchID); _drEntityStorage.NonDraftDeferralTransactionsPrepared(scheduleDetail, detailDeferralCode, componentTransactions); } } } }
public static Amount CalculateNetAmount(PXGraph graph, DRSchedule document) => CalculateNetAmountForDeferredLines(graph, document.DocType, document.RefNbr);
private void CreateSingleSchedule <T>(T originalDocument, Amount lineTotal, int?DefScheduleID, bool isDraft, DRScheduleParameters scheduleParameters) where T : ARRegister { ARSetup arSetup = PXSelect <ARSetup> .Select(this); DRSchedule existingSchedule = PXSelect < DRSchedule, Where < DRSchedule.module, Equal <BatchModule.moduleAR>, And <DRSchedule.docType, Equal <Required <ARRegister.docType> >, And <DRSchedule.refNbr, Equal <Required <ARRegister.refNbr> > > > > > .SelectSingleBound(this, null, originalDocument.DocType, originalDocument.RefNbr, 1); if (existingSchedule?.LineNbr != null) { throw new PXException(Messages.CantCompleteBecauseASC606FeatureIsEnabled); } if (DefScheduleID == null) { Location location = PXSelect <Location, Where <Location.locationID, Equal <Required <DRSchedule.bAccountLocID> > > > .SelectSingleBound(this, null, scheduleParameters.BAccountLocID); CurrencyInfo currencyInfo = PXSelect <CurrencyInfo, Where <CurrencyInfo.curyInfoID, Equal <Required <DRSchedule.curyInfoID> > > > .SelectSingleBound(this, null, scheduleParameters.CuryInfoID); SingleScheduleCreator scheduleCreator = new SingleScheduleCreator( this, new ARSubaccountProvider(this), this, this, this, this, this, FinPeriodRepository, roundingFunction: x => PXDBCurrencyAttribute.Round(Schedule.Cache, Schedule.Current, x, CMPrecision.TRANCURY), branchID: originalDocument.BranchID, isDraft: isDraft, location: location, currencyInfo: currencyInfo); if (existingSchedule == null) { scheduleCreator.CreateOriginalSchedule( scheduleParameters, lineTotal); } else { scheduleCreator.ReevaluateSchedule( existingSchedule, scheduleParameters, lineTotal, attachedToOriginalSchedule: false); } } else { if (originalDocument.DocType == ARDocType.CreditMemo || originalDocument.DocType == ARDocType.DebitMemo) { bool accountForPostedTransactions = originalDocument.DocType == ARDocType.CreditMemo; if (existingSchedule == null) { CreateRelatedSingleSchedule(scheduleParameters, DefScheduleID, lineTotal, isDraft, accountForPostedTransactions); } else { Location location = PXSelect <Location, Where <Location.locationID, Equal <Required <DRSchedule.bAccountLocID> > > > .SelectSingleBound(this, null, scheduleParameters.BAccountLocID); CurrencyInfo currencyInfo = PXSelect <CurrencyInfo, Where <CurrencyInfo.curyInfoID, Equal <Required <DRSchedule.curyInfoID> > > > .SelectSingleBound(this, null, scheduleParameters.CuryInfoID); var scheduleCreator = new SingleScheduleCreator( this, new ARSubaccountProvider(this), this, this, this, this, this, FinPeriodRepository, roundingFunction: x => PXCurrencyAttribute.BaseRound(this, x), branchID: originalDocument.BranchID, isDraft: !accountForPostedTransactions, location: location, currencyInfo: currencyInfo); scheduleCreator.ReevaluateSchedule( existingSchedule, scheduleParameters, lineTotal, attachedToOriginalSchedule: true); } } } }
private void CreateRelatedSingleSchedule(DRScheduleParameters scheduleParameters, int?defScheduleID, Amount tranAmt, bool isDraft, bool accountForPostedTransactions) { DRSchedule relatedSchedule = (this as IDREntityStorage).CreateCopy(scheduleParameters); relatedSchedule.IsDraft = isDraft; relatedSchedule.IsCustom = false; relatedSchedule = Schedule.Insert(relatedSchedule); DRSchedule originalDeferralSchedule = GetDeferralSchedule(defScheduleID); DRScheduleDetail originalDetailsTotalDetail = PXSelectGroupBy < DRScheduleDetail, Where < DRScheduleDetail.scheduleID, Equal <Required <DRScheduleDetail.scheduleID> > >, Aggregate <Sum <DRScheduleDetail.curyTotalAmt> > > .Select(this, originalDeferralSchedule.ScheduleID); decimal originalDetailsTotal = originalDetailsTotalDetail.CuryTotalAmt ?? 0m; decimal adjustmentTotal = tranAmt.Cury.Value; decimal newDetailTotal = 0m; var originalDetails = PXSelectJoin <DRScheduleDetail, LeftJoin <ARTran, On <DRScheduleDetail.lineNbr, Equal <ARTran.lineNbr> >, InnerJoin <InventoryItem, On <ARTran.inventoryID, Equal <InventoryItem.inventoryID> >, LeftJoin <INComponent, On <DRScheduleDetail.componentID, Equal <INComponent.inventoryID> >, InnerJoin <DRDeferredCode, On <ARTran.deferredCode, Equal <DRDeferredCode.deferredCodeID> > > > > >, Where <DRScheduleDetail.scheduleID, Equal <Required <DRSchedule.scheduleID> >, And <ARTran.tranType, Equal <Required <DRSchedule.docType> >, And <ARTran.refNbr, Equal <Required <DRSchedule.refNbr> > > > > > .Select(this, defScheduleID, scheduleParameters.DocType, scheduleParameters.RefNbr); foreach (PXResult <DRScheduleDetail, ARTran, InventoryItem, INComponent, DRDeferredCode> item in originalDetails) { DRScheduleDetail originalDetail = item; ARTran tran = item; InventoryItem inventoryItem = item; INComponent inComponent = item; DRDeferredCode defCode = item; decimal detailPartRaw = originalDetailsTotal == 0 ? 0 : originalDetail.CuryTotalAmt.Value * adjustmentTotal / originalDetailsTotal; decimal detailPart = PXDBCurrencyAttribute.BaseRound(this, detailPartRaw); decimal takeFromPostedRaw = 0; if (accountForPostedTransactions && originalDetail.CuryTotalAmt.Value != 0) { takeFromPostedRaw = detailPartRaw * (originalDetail.CuryTotalAmt.Value - originalDetail.CuryDefAmt.Value) / originalDetail.CuryTotalAmt.Value; } decimal takeFromPosted = PXDBCurrencyAttribute.BaseRound(this, takeFromPostedRaw); decimal adjustmentDeferredAmountRaw = detailPartRaw - takeFromPosted; decimal adjustmentDeferredAmount = PXDBCurrencyAttribute.BaseRound(this, adjustmentDeferredAmountRaw); INComponent inventoryItemComponent = null; DRDeferredCode componentDeferralCode = null; if (inventoryItem != null && inComponent != null) { inventoryItemComponent = GetInventoryItemComponent(inventoryItem.InventoryID, originalDetail.ComponentID); if (inventoryItemComponent != null) { componentDeferralCode = PXSelect < DRDeferredCode, Where < DRDeferredCode.deferredCodeID, Equal <Required <DRDeferredCode.deferredCodeID> > > > .Select(this, inventoryItemComponent.DeferredCode); } } InventoryItem component = GetInventoryItem(originalDetail.ComponentID); DRScheduleDetail relatedScheduleDetail; if (componentDeferralCode != null) { // Use component's deferral code // - relatedScheduleDetail = InsertScheduleDetail( tran.BranchID, relatedSchedule, inventoryItemComponent, component, componentDeferralCode, detailPart, originalDetail.DefAcctID, originalDetail.DefSubID, isDraft); } else { // Use deferral code and accounts from the document line // - relatedScheduleDetail = InsertScheduleDetail( tran.BranchID, relatedSchedule, component == null ? DRScheduleDetail.EmptyComponentID : component.InventoryID, defCode, detailPart, originalDetail.DefAcctID, originalDetail.DefSubID, tran.AccountID, tran.SubID, isDraft); } newDetailTotal += detailPart; IList <DRScheduleTran> relatedTransactions = new List <DRScheduleTran>(); DRDeferredCode relatedTransactionsDeferralCode = componentDeferralCode ?? defCode; IEnumerable <DRScheduleTran> originalPostedTransactions = null; if (accountForPostedTransactions) { originalPostedTransactions = PXSelect < DRScheduleTran, Where < DRScheduleTran.status, Equal <DRScheduleTranStatus.PostedStatus>, And <DRScheduleTran.scheduleID, Equal <Required <DRScheduleTran.scheduleID> >, And <DRScheduleTran.componentID, Equal <Required <DRScheduleTran.componentID> >, And <DRScheduleTran.detailLineNbr, Equal <Required <DRScheduleTran.detailLineNbr> >, And <DRScheduleTran.lineNbr, NotEqual <Required <DRScheduleTran.lineNbr> > > > > > > > .Select( this, originalDetail.ScheduleID, originalDetail.ComponentID, originalDetail.DetailLineNbr, originalDetail.CreditLineNbr) .RowCast <DRScheduleTran>(); } if (adjustmentDeferredAmount != 0m || accountForPostedTransactions && takeFromPosted != 0m) { string requiredTransactionStatus = relatedTransactionsDeferralCode.Method == DeferredMethodType.CashReceipt ? DRScheduleTranStatus.Projected : DRScheduleTranStatus.Open; IEnumerable <DRScheduleTran> originalOpenTransactions = PXSelect < DRScheduleTran, Where < DRScheduleTran.status, Equal <Required <DRScheduleTran.status> >, And <DRScheduleTran.scheduleID, Equal <Required <DRScheduleTran.scheduleID> >, And <DRScheduleTran.componentID, Equal <Required <DRScheduleTran.componentID> >, And <DRScheduleTran.detailLineNbr, Equal <Required <DRScheduleTran.detailLineNbr> > > > > > > .Select( this, requiredTransactionStatus, originalDetail.ScheduleID, originalDetail.ComponentID, originalDetail.DetailLineNbr) .RowCast <DRScheduleTran>(); IList <DRScheduleTran> relatedDeferralTransactions = GetTransactionsGenerator(relatedTransactionsDeferralCode).GenerateRelatedTransactions( relatedScheduleDetail, originalOpenTransactions, originalPostedTransactions, adjustmentDeferredAmount, takeFromPosted, tran.BranchID); foreach (DRScheduleTran deferralTransaction in relatedDeferralTransactions) { Transactions.Insert(deferralTransaction); relatedTransactions.Add(deferralTransaction); } } UpdateBalanceProjection(relatedTransactions, relatedScheduleDetail, defCode.AccountType); } }
private static void RecalculateScheduleProc(DraftScheduleMaint graph) { var schedule = graph.Schedule.Current; bool isUnable = graph.Schedule.Cache.GetStatus(graph.Schedule.Current) != PXEntryStatus.Notchanged && graph.Schedule.Cache.GetStatus(graph.Schedule.Current) != PXEntryStatus.Updated; if (isUnable || schedule.IsRecalculated == true || graph.Components.Any() == false) { return; } ARInvoice document = PXSelect <ARInvoice, Where <ARInvoice.docType, Equal <Required <ARRegister.docType> >, And <ARInvoice.refNbr, Equal <Required <ARRegister.refNbr> > > > > .Select(graph, schedule.DocType, schedule.RefNbr); PXSelectBase <DRSchedule> correspondingScheduleView = new PXSelect < DRSchedule, Where < DRSchedule.module, Equal <BatchModule.moduleAR>, And <DRSchedule.docType, Equal <Required <ARTran.tranType> >, And <DRSchedule.refNbr, Equal <Required <ARTran.refNbr> > > > > > (graph); DRSchedule correspondingSchedule = correspondingScheduleView.Select(document.DocType, document.RefNbr); var newDetails = new List <DRScheduleDetail>(); var netLinesAmount = ASC606Helper.CalculateNetAmount(graph, document); int? defScheduleID = null; DRSchedule scheduleResult = null; if (netLinesAmount.Cury != 0m) { DRSingleProcess process = PXGraph.CreateInstance <DRSingleProcess>(); process.CreateSingleSchedule(document, netLinesAmount, defScheduleID, true); scheduleResult = process.Schedule.Current; foreach (DRScheduleDetail detail in process.ScheduleDetail.Cache.Inserted) { newDetails.Add(detail); } } foreach (DRScheduleDetail detail in graph.Components.Select()) { graph.Components.Delete(detail); } schedule.DocDate = scheduleResult.DocDate; schedule.BAccountID = scheduleResult.BAccountID; schedule.BAccountLocID = scheduleResult.BAccountLocID; schedule.FinPeriodID = scheduleResult.FinPeriodID; schedule.TranDesc = scheduleResult.TranDesc; schedule.IsCustom = false; schedule.BAccountType = schedule.Module == BatchModule.AP ? BAccountType.VendorType : BAccountType.CustomerType; schedule.TermStartDate = scheduleResult.TermStartDate; schedule.TermEndDate = scheduleResult.TermEndDate; schedule.ProjectID = scheduleResult.ProjectID; schedule.TaskID = scheduleResult.TaskID; schedule.IsRecalculated = true; schedule = graph.Schedule.Update(schedule); foreach (DRScheduleDetail detail in newDetails) { graph.Components.Insert(detail); } }
private void SetAmounts(IList <DRScheduleTran> deferredTransactions, decimal deferredAmount, DRSchedule schedule) { switch (_code.Method) { case DeferredMethodType.CashReceipt: case DeferredMethodType.EvenPeriods: SetAmountsEvenPeriods(deferredTransactions, deferredAmount); break; case DeferredMethodType.ProrateDays: SetAmountsProrateDays(deferredTransactions, deferredAmount, schedule.DocDate.Value); break; case DeferredMethodType.ExactDays: SetAmountsExactDays(deferredTransactions, deferredAmount); break; case DeferredMethodType.FlexibleProrateDays: SetAmountsFlexibleProrateByDays(deferredTransactions, deferredAmount, schedule.TermStartDate.Value, schedule.TermEndDate.Value); break; case DeferredMethodType.FlexibleExactDays: SetAmountsFlexibleByDays(deferredTransactions, deferredAmount, schedule.TermStartDate.Value, schedule.TermEndDate.Value); break; } }
public virtual IList <DRScheduleTran> GenerateTransactions( DRSchedule deferralSchedule, DRScheduleDetail scheduleDetail, int?branchID) { if (deferralSchedule == null) { throw new ArgumentNullException(nameof(deferralSchedule)); } if (scheduleDetail == null) { throw new ArgumentNullException(nameof(scheduleDetail)); } ValidateTerms(deferralSchedule); decimal defAmount = scheduleDetail.TotalAmt.Value; List <DRScheduleTran> list = new List <DRScheduleTran>(); short lineCounter = 0; if (_code.ReconNowPct.Value > 0) { decimal recNowRaw = defAmount * _code.ReconNowPct.Value * 0.01m; decimal recNow = _roundingFunction(recNowRaw); defAmount -= recNow; lineCounter++; DRScheduleTran nowTran = new DRScheduleTran { BranchID = branchID, AccountID = scheduleDetail.AccountID, SubID = scheduleDetail.SubID, Amount = recNow, RecDate = deferralSchedule.DocDate, FinPeriodID = scheduleDetail.FinPeriodID, LineNbr = lineCounter, ScheduleID = scheduleDetail.ScheduleID, ComponentID = scheduleDetail.ComponentID, Status = _code.Method == DeferredMethodType.CashReceipt ? DRScheduleTranStatus.Projected : DRScheduleTranStatus.Open, }; list.Add(nowTran); } bool isFlexibleDeferralCode = DeferredMethodType.RequiresTerms(_code.Method); DateTime documentDate = deferralSchedule.DocDate.Value; string documentFinPeriod = _financialPeriodProvider.FindFinPeriodByDate(_graph, documentDate)?.FinPeriodID; int occurrences = isFlexibleDeferralCode ? CalcOccurrences(deferralSchedule.TermStartDate.Value, deferralSchedule.TermEndDate.Value) : _code.Occurrences.Value; List <DRScheduleTran> deferredList = new List <DRScheduleTran>(_code.Occurrences.Value); string deferredPeriod = null; for (int i = 0; i < occurrences; i++) { try { if (deferredPeriod == null) { deferredPeriod = isFlexibleDeferralCode ? _financialPeriodProvider.FindFinPeriodByDate(_graph, deferralSchedule.TermStartDate.Value)?.FinPeriodID : _financialPeriodProvider.PeriodPlusPeriod(_graph, scheduleDetail.FinPeriodID, _code.StartOffset.Value); } else { deferredPeriod = _financialPeriodProvider.PeriodPlusPeriod(_graph, deferredPeriod, _code.Frequency.Value); } } catch (PXFinPeriodException ex) { throw new PXException(ex, Messages.NoFinPeriod, _code.DeferredCodeID); } lineCounter++; DateTime recognitionDate = GetRecognitionDate( deferredPeriod, minimumDate: isFlexibleDeferralCode ? deferralSchedule.TermStartDate.Value : documentDate, maximumDate: isFlexibleDeferralCode ? deferralSchedule.TermEndDate : null); DRScheduleTran deferralTransaction = new DRScheduleTran { BranchID = branchID, AccountID = scheduleDetail.AccountID, SubID = scheduleDetail.SubID, RecDate = recognitionDate, FinPeriodID = _financialPeriodProvider.FindFinPeriodByDate(_graph, recognitionDate)?.FinPeriodID, LineNbr = lineCounter, ScheduleID = scheduleDetail.ScheduleID, ComponentID = scheduleDetail.ComponentID, Status = _code.Method == DeferredMethodType.CashReceipt ? DRScheduleTranStatus.Projected : DRScheduleTranStatus.Open }; deferredList.Add(deferralTransaction); } SetAmounts(deferredList, defAmount, deferralSchedule); if (DeferredMethodType.RequiresTerms(_code) && _code.RecognizeInPastPeriods != true) { // Adjust recognition dates and financial periods // that are in the past relative to the document date. // - foreach (DRScheduleTran transaction in deferredList .Where(transaction => transaction.RecDate < documentDate)) { transaction.RecDate = documentDate; transaction.FinPeriodID = documentFinPeriod; } } list.AddRange(deferredList); return(list); }