Example #1
0
        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));
            }

            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,
                    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 = _finPeriodRepository.FindFinPeriodByDate(documentDate, organizationID)?.FinPeriodID;

            int occurrences = isFlexibleDeferralCode ?
                              CalcOccurrences(deferralSchedule.TermStartDate.Value, deferralSchedule.TermEndDate.Value, organizationID) :
                              _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 ?
                                         _finPeriodRepository.FindFinPeriodByDate(deferralSchedule.TermStartDate.Value, organizationID)?.FinPeriodID :
                                         _finPeriodRepository.GetOffsetPeriodId(scheduleDetail.FinPeriodID, _code.StartOffset.Value, organizationID);
                    }
                    else
                    {
                        deferredPeriod = _finPeriodRepository.GetOffsetPeriodId(deferredPeriod, _code.Frequency.Value, organizationID);
                    }
                }
                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,
                    organizationID: organizationID);

                DRScheduleTran deferralTransaction = new DRScheduleTran
                {
                    BranchID    = scheduleDetail.BranchID,
                    AccountID   = scheduleDetail.AccountID,
                    SubID       = scheduleDetail.SubID,
                    RecDate     = recognitionDate,
                    FinPeriodID = _finPeriodRepository.FindFinPeriodByDate(recognitionDate, organizationID)?.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, 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;
                }
            }

            list.AddRange(deferredList);

            return(list);
        }