public virtual void CreateSingleSchedule(AR.Standalone.ARCashSale originalDocument, Amount lineTotal, int?defScheduleID, bool isDraft) { DRScheduleParameters scheduleParameters = GetSingleScheduleParameters(originalDocument); CreateSingleSchedule <AR.Standalone.ARCashSale>(originalDocument, lineTotal, defScheduleID, isDraft, scheduleParameters); }
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); } }