Пример #1
0
        /// <summary>
        /// If applicable, creates a single related transaction for all original posted transactions
        /// whose recognition date is earlier than (or equal to) the current document date.
        /// Does not set any amounts.
        /// </summary>
        /// <param name="transactionList">
        /// Transaction list where the new transaction will be put (if created).
        /// </param>
        /// <param name="lineCounter">
        /// Transaction line counter. Will be incremented if any transactions are created by this procedure.
        /// </param>
        private void AddRelatedTransactionForPostedBeforeDocumentDate(
            IList <DRScheduleTran> transactionList,
            DRScheduleDetail relatedScheduleDetail,
            IEnumerable <DRScheduleTran> originalPostedTransactions,
            int?branchID,
            ref short lineCounter)
        {
            IEnumerable <DRScheduleTran> originalTransactionsPostedBeforeDocumentDate =
                originalPostedTransactions.Where(transaction => transaction.RecDate <= relatedScheduleDetail.DocDate);

            if (originalTransactionsPostedBeforeDocumentDate.Any())
            {
                ++lineCounter;

                DRScheduleTran relatedTransaction = new DRScheduleTran
                {
                    BranchID    = branchID,
                    AccountID   = relatedScheduleDetail.AccountID,
                    SubID       = relatedScheduleDetail.SubID,
                    RecDate     = relatedScheduleDetail.DocDate,
                    FinPeriodID = relatedScheduleDetail.FinPeriodID,
                    LineNbr     = lineCounter,
                    ScheduleID  = relatedScheduleDetail.ScheduleID,
                    ComponentID = relatedScheduleDetail.ComponentID,
                    Status      = DRScheduleTranStatus.Open
                };

                transactionList.Add(relatedTransaction);
            }
        }
Пример #2
0
        protected virtual void DRScheduleTran_RowDeleted(PXCache sender, PXRowDeletedEventArgs e)
        {
            DRScheduleTran row = e.Row as DRScheduleTran;

            if (row != null && Components.Current != null && Components.Current.Status == DRScheduleStatus.Open)
            {
                Subtract(row);
            }
        }
Пример #3
0
        protected virtual void DRScheduleTran_RecDate_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
        {
            DRScheduleTran row = e.Row as DRScheduleTran;

            if (row != null)
            {
                row.FinPeriodID = FinPeriodIDAttribute.PeriodFromDate(this, row.RecDate);
            }
        }
Пример #4
0
        /// <summary>
        /// Tries to perform a redirect to the original AR or AP document referenced by
        /// the <see cref="DRSchedule"/> that owns the given <see cref="DRScheduleTran"/>.
        /// </summary>
        /// <param name="sourceGraph">
        /// A graph through which the redirect will be processed.
        /// </param>
        /// <param name="scheduleTransaction">
        /// The <see cref="DRScheduleDetail"/> object from which the corresponding schedule
        /// will be selected.
        /// </param>
        public static void NavigateToOriginalDocument(
            PXGraph sourceGraph,
            DRScheduleTran scheduleTransaction)
        {
            DRSchedule correspondingSchedule = PXSelect <
                DRSchedule,
                Where <DRSchedule.scheduleID, Equal <Required <DRScheduleTran.scheduleID> > > >
                                               .Select(sourceGraph, scheduleTransaction.ScheduleID);

            NavigateToOriginalDocument(sourceGraph, correspondingSchedule);
        }
Пример #5
0
        protected virtual void DRScheduleTran_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
        {
            DRScheduleTran row = e.Row as DRScheduleTran;

            if (row != null)
            {
                PXUIFieldAttribute.SetEnabled <DRScheduleTran.recDate>(sender, row, row.Status == DRScheduleTranStatus.Open || row.Status == DRScheduleTranStatus.Projected);
                PXUIFieldAttribute.SetEnabled <DRScheduleTran.amount>(sender, row, row.Status == DRScheduleTranStatus.Open || row.Status == DRScheduleTranStatus.Projected);
                PXUIFieldAttribute.SetEnabled <DRScheduleTran.accountID>(sender, row, row.Status == DRScheduleTranStatus.Open || row.Status == DRScheduleTranStatus.Projected);
                PXUIFieldAttribute.SetEnabled <DRScheduleTran.subID>(sender, row, row.Status == DRScheduleTranStatus.Open || row.Status == DRScheduleTranStatus.Projected);
            }
        }
Пример #6
0
        protected virtual void DRScheduleTran_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
        {
            DRScheduleTran row = e.Row as DRScheduleTran;

            if (!sender.ObjectsEqual <DRScheduleTran.finPeriodID, DRScheduleTran.accountID, DRScheduleTran.subID, DRScheduleTran.amount>(e.Row, e.OldRow))
            {
                if (Components.Current != null && Components.Current.Status == DRScheduleStatus.Open)
                {
                    DRScheduleTran oldRow = (DRScheduleTran)e.OldRow;
                    Subtract(oldRow);
                    Add(row);
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Updates the transaction amount and performs the callback to
        /// <see cref="IDREntityStorage"/>, notifying about the update.
        /// </summary>
        private void UpdateTransactionAmount(
            DRScheduleDetail scheduleDetail,
            DRDeferredCode detailDeferralCode,
            DRScheduleTran transaction,
            decimal?newAmount)
        {
            DRScheduleTran oldTransaction = _drEntityStorage.CreateCopy(transaction);

            transaction.Amount = newAmount;

            _drEntityStorage.ScheduleTransactionModified(
                scheduleDetail,
                detailDeferralCode,
                oldTransaction,
                transaction);
        }
Пример #8
0
        private void Add(DRScheduleTran tran)
        {
            Debug.Print("Add FinPeriod={0} Status={1} Amount={2}", tran.FinPeriodID, tran.Status, tran.Amount);
            DRDeferredCode code = DeferredCode.Select();

            if (code.AccountType == DeferredAccountType.Expense)
            {
                AddExpenseToProjection(tran);
                AddExpenseToBalance(tran);
            }
            else
            {
                AddRevenueToProjection(tran);
                AddRevenueToBalance(tran);
            }
        }
Пример #9
0
        private void Subtract(DRScheduleTran tran)
        {
            Debug.Print("Subtract FinPeriod={0} Status={1} Amount={2}", tran.FinPeriodID, tran.Status, tran.Amount);
            DRDeferredCode code = DeferredCode.Select();

            if (code.AccountType == DeferredAccountType.Expense)
            {
                SubtractExpenseFromProjection(tran);
                SubtractExpenseFromBalance(tran);
            }
            else
            {
                SubtractRevenueFromProjection(tran);
                SubtractRevenueFromBalance(tran);
            }
        }
Пример #10
0
        private void AddExpenseToProjection(DRScheduleTran tran)
        {
            if (tran.FinPeriodID == null)
            {
                return;
            }
            DRExpenseProjectionAccum hist = new DRExpenseProjectionAccum();

            hist.FinPeriodID = tran.FinPeriodID;
            hist.AcctID      = Components.Current.AccountID;
            hist.SubID       = Components.Current.SubID;
            hist.ComponentID = Components.Current.ComponentID ?? 0;
            hist.ProjectID   = Components.Current.ProjectID ?? 0;
            hist.VendorID    = Components.Current.BAccountID ?? 0;

            hist = ExpenseProjection.Insert(hist);
            hist.PTDProjected += tran.Amount;
        }
Пример #11
0
        private void SubtractRevenueFromProjection(DRScheduleTran tran)
        {
            if (tran.FinPeriodID == null)
            {
                return;
            }
            DRRevenueProjectionAccum hist = new DRRevenueProjectionAccum();

            hist.FinPeriodID = tran.FinPeriodID;
            hist.AcctID      = Components.Current.AccountID;
            hist.SubID       = Components.Current.SubID;
            hist.ComponentID = Components.Current.ComponentID ?? 0;
            hist.ProjectID   = Components.Current.ProjectID ?? 0;
            hist.CustomerID  = Components.Current.BAccountID ?? 0;

            hist = RevenueProjection.Insert(hist);
            hist.PTDProjected -= tran.Amount;
        }
        /// <summary>
        /// Adds a related transaction for every original transaction
        /// in <paramref name="originalTransactions"/> using information
        /// from the provided related <see cref="DRScheduleDetail"/>.
        /// Does not set any transaction amounts.
        /// </summary>
        /// <param name="transactionList">
        /// Transaction list where the new transaction will be put (if created).
        /// </param>
        /// <param name="lineCounter">
        /// Transaction line counter. Will be incremented if any transactions are created by this procedure.
        /// </param>
        private void AddRelatedTransactions(
            IList <DRScheduleTran> transactionList,
            DRScheduleDetail relatedScheduleDetail,
            IEnumerable <DRScheduleTran> originalTransactions,
            int?branchID,
            ref short lineCounter)
        {
            int?organizationID = PXAccess.GetParentOrganizationID(branchID);

            foreach (DRScheduleTran originalTransaction in originalTransactions)
            {
                ++lineCounter;

                DRScheduleTran relatedTransaction = new DRScheduleTran
                {
                    BranchID      = branchID,
                    AccountID     = relatedScheduleDetail.AccountID,
                    SubID         = relatedScheduleDetail.SubID,
                    LineNbr       = lineCounter,
                    DetailLineNbr = relatedScheduleDetail.DetailLineNbr,
                    ScheduleID    = relatedScheduleDetail.ScheduleID,
                    ComponentID   = relatedScheduleDetail.ComponentID,
                    Status        = DRScheduleTranStatus.Open
                };

                var maxDate = originalTransaction.RecDate.Value < relatedScheduleDetail.DocDate.Value
                                        ? relatedScheduleDetail.DocDate
                                        : originalTransaction.RecDate;

                relatedTransaction.RecDate = maxDate;

                var maxPeriod = string.CompareOrdinal(originalTransaction.FinPeriodID, relatedScheduleDetail.FinPeriodID) < 0
                                        ? relatedScheduleDetail.FinPeriodID
                                        : originalTransaction.FinPeriodID;

                FinPeriod maxFinPeriod = _finPeriodRepository.GetByID(maxPeriod, organizationID);

                relatedTransaction.FinPeriodID  = maxFinPeriod.FinPeriodID;
                relatedTransaction.TranPeriodID = maxFinPeriod.MasterFinPeriodID;

                transactionList.Add(relatedTransaction);
            }
        }
Пример #13
0
        private void AddExpenseToBalance(DRScheduleTran tran)
        {
            if (tran.FinPeriodID == null)
            {
                return;
            }
            DRExpenseBalance hist = new DRExpenseBalance();

            hist.FinPeriodID = tran.FinPeriodID;
            hist.AcctID      = Components.Current.DefAcctID;
            hist.SubID       = Components.Current.DefSubID;
            hist.ComponentID = Components.Current.ComponentID ?? 0;
            hist.ProjectID   = Components.Current.ProjectID ?? 0;
            hist.VendorID    = Components.Current.BAccountID ?? 0;

            hist = ExpenseBalance.Insert(hist);
            hist.PTDProjected += tran.Amount;
            hist.EndProjected -= tran.Amount;
        }
Пример #14
0
        private void SubtractRevenueFromBalance(DRScheduleTran tran)
        {
            if (tran.FinPeriodID == null)
            {
                return;
            }
            DRRevenueBalance hist = new DRRevenueBalance();

            hist.FinPeriodID = tran.FinPeriodID;
            hist.AcctID      = Components.Current.DefAcctID;
            hist.SubID       = Components.Current.DefSubID;
            hist.ComponentID = Components.Current.ComponentID ?? 0;
            hist.ProjectID   = Components.Current.ProjectID ?? 0;
            hist.CustomerID  = Components.Current.BAccountID ?? 0;

            hist = RevenueBalance.Insert(hist);
            hist.PTDProjected -= tran.Amount;
            hist.EndProjected += tran.Amount;
        }
Пример #15
0
        /// <summary>
        /// Adds a related transaction for every original transaction
        /// in <paramref name="originalTransactions"/> using information
        /// from the provided related <see cref="DRScheduleDetail"/>.
        /// Does not set any transaction amounts.
        /// </summary>
        /// <param name="transactionList">
        /// Transaction list where the new transaction will be put (if created).
        /// </param>
        /// <param name="lineCounter">
        /// Transaction line counter. Will be incremented if any transactions are created by this procedure.
        /// </param>
        private void AddRelatedTransactions(
            IList <DRScheduleTran> transactionList,
            DRScheduleDetail relatedScheduleDetail,
            IEnumerable <DRScheduleTran> originalTransactions,
            int?branchID,
            ref short lineCounter)
        {
            foreach (DRScheduleTran originalTransaction in originalTransactions)
            {
                ++lineCounter;

                DRScheduleTran relatedTransaction = new DRScheduleTran
                {
                    BranchID    = branchID,
                    AccountID   = relatedScheduleDetail.AccountID,
                    SubID       = relatedScheduleDetail.SubID,
                    LineNbr     = lineCounter,
                    ScheduleID  = relatedScheduleDetail.ScheduleID,
                    ComponentID = relatedScheduleDetail.ComponentID,
                    Status      = DRScheduleTranStatus.Open
                };

                var maxDate = originalTransaction.RecDate.Value < relatedScheduleDetail.DocDate.Value
                                        ? relatedScheduleDetail.DocDate
                                        : originalTransaction.RecDate;

                relatedTransaction.RecDate = maxDate;

                var maxPeriod = string.CompareOrdinal(originalTransaction.FinPeriodID, relatedScheduleDetail.FinPeriodID) < 0
                                        ? relatedScheduleDetail.FinPeriodID
                                        : originalTransaction.FinPeriodID;

                relatedTransaction.FinPeriodID = maxPeriod;

                transactionList.Add(relatedTransaction);
            }
        }
        public static void RunRecognition(List <ScheduledTran> trans, DateTime?filterDate)
        {
            ScheduleMaint scheduleMaint = PXGraph.CreateInstance <ScheduleMaint>();

            scheduleMaint.Clear();

            bool failed = false;

            List <ScheduledTran> items = GetValidatedItems(trans, scheduleMaint);

            failed = items.Count() < trans.Count();

            // Save virtual records:
            // -
            foreach (ScheduledTran tr in items)
            {
                PXProcessing <ScheduledTran> .SetCurrentItem(tr);

                if (tr.IsVirtual == true)
                {
                    try
                    {
                        scheduleMaint.Document.Current = PXSelect <DRScheduleDetail,
                                                                   Where <DRScheduleDetail.scheduleID, Equal <Required <DRScheduleDetail.scheduleID> >,
                                                                          And <DRScheduleDetail.componentID, Equal <Required <DRScheduleDetail.componentID> > > > >
                                                         .Select(scheduleMaint, tr.ScheduleID, tr.ComponentID ?? DRScheduleDetail.EmptyComponentID);

                        DRScheduleTran tran = new DRScheduleTran();
                        tran.BranchID    = tr.BranchID;
                        tran.AccountID   = tr.AccountID;
                        tran.SubID       = tr.SubID;
                        tran.AdjgDocType = tr.AdjgDocType;
                        tran.AdjgRefNbr  = tr.AdjgRefNbr;
                        tran.AdjNbr      = tr.AdjNbr;
                        tran.Amount      = tr.Amount;
                        tran.ComponentID = tr.ComponentID ?? DRScheduleDetail.EmptyComponentID;
                        tran.FinPeriodID = tr.FinPeriodID;
                        tran.ScheduleID  = tr.ScheduleID;
                        tran.RecDate     = tr.RecDate;
                        tran.Status      = DRScheduleTranStatus.Open;

                        tran       = scheduleMaint.OpenTransactions.Insert(tran);
                        tr.LineNbr = tran.LineNbr;

                        scheduleMaint.RebuildProjections();

                        scheduleMaint.Save.Press();
                        byte[] ts = scheduleMaint.TimeStamp;
                        scheduleMaint.Clear();
                        scheduleMaint.TimeStamp = ts;
                        PXProcessing <ScheduledTran> .SetProcessed();
                    }

                    catch (Exception ex)
                    {
                        failed = true;
                        PXProcessing <ScheduledTran> .SetError(ex.Message);
                    }
                }
                else
                {
                    PXProcessing <ScheduledTran> .SetProcessed();
                }
            }

            PXProcessing <ScheduledTran> .SetCurrentItem(null);

            List <DRBatch> list = SplitByFinPeriod(items);

            DRProcess process = CreateInstance <DRProcess>();

            process.Clear();
            process.TimeStamp = scheduleMaint.TimeStamp;
            List <Batch> batchlist = process.RunRecognition(list, filterDate);

            PostGraph pg = PXGraph.CreateInstance <PostGraph>();
            //Post Batches if AutoPost

            bool postFailed = false;

            if (pg.AutoPost)
            {
                foreach (Batch batch in batchlist)
                {
                    try
                    {
                        pg.Clear();
                        pg.TimeStamp = batch.tstamp;
                        pg.PostBatchProc(batch);
                    }
                    catch (Exception)
                    {
                        postFailed = true;
                    }
                }
                if (postFailed)
                {
                    throw new PXException(Messages.AutoPostFailed);
                }
            }

            if (failed)
            {
                throw new PXException(GL.Messages.DocumentsNotReleased);
            }
        }
        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;
        }
Пример #18
0
        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);
        }
Пример #19
0
        /// <summary>
        /// Generates the related transactions given the list of original
        /// </summary>
        /// <param name="relatedScheduleDetail">
        /// The schedule detail
        /// to which the related transactions will pertain.
        /// </param>
        /// <param name="originalOpenTransactions">
        /// Original transactions in the Open (or Projected) status.
        /// </param>
        /// <param name="originalPostedTransactions">
        /// Original transactions in the Posted status.
        /// </param>
        /// <param name="amountToDistributeForUnposted">
        /// Amount to distribute among the related transactions that are
        /// created for original Open transactions.
        /// </param>
        /// <param name="amountToDistributeForPosted">
        /// Amount to distribute among the related transactions that are
        /// created for original Posted transactions.
        /// </param>
        /// <param name="branchID">
        /// Branch ID for the related transactions.
        /// </param>
        /// <returns></returns>
        public virtual IList <DRScheduleTran> GenerateRelatedTransactions(
            DRScheduleDetail relatedScheduleDetail,
            IEnumerable <DRScheduleTran> originalOpenTransactions,
            IEnumerable <DRScheduleTran> originalPostedTransactions,
            decimal amountToDistributeForUnposted,
            decimal amountToDistributeForPosted,
            int?branchID)
        {
            ValidateOpenTransactions(originalOpenTransactions);
            ValidatePostedTransactions(originalPostedTransactions);

            List <DRScheduleTran> transactionList = new List <DRScheduleTran>();

            short lineCounter = 0;
            int   transactionsAddedDuringPreviousStep;

            // Handle posted transactions
            // -
            if (originalPostedTransactions != null && originalPostedTransactions.Any())
            {
                decimal originalPostedTransactionsTotal =
                    originalPostedTransactions.Sum(transaction => transaction.Amount ?? 0);

                AddRelatedTransactionForPostedBeforeDocumentDate(
                    transactionList,
                    relatedScheduleDetail,
                    originalPostedTransactions,
                    branchID,
                    ref lineCounter);

                transactionsAddedDuringPreviousStep = lineCounter;

                decimal originalPostedBeforeDocumentDateSum = originalPostedTransactions
                                                              .Where(transaction => transaction.RecDate <= relatedScheduleDetail.DocDate)
                                                              .Sum(transaction => transaction.Amount ?? 0);

                decimal multiplier = amountToDistributeForPosted / originalPostedTransactionsTotal;

                // Amount to be distributed across other transactions that
                // are related to the original posted transactions.
                // -
                decimal residualPostedAmount = amountToDistributeForPosted;

                if (transactionList.Any())
                {
                    transactionList[0].Amount = multiplier * originalPostedBeforeDocumentDateSum;
                    residualPostedAmount     -= transactionList[0].Amount ?? 0;
                }

                IEnumerable <DRScheduleTran> originalPostedAfterDocumentDate =
                    originalPostedTransactions.Where(transaction => transaction.RecDate > relatedScheduleDetail.DocDate);

                AddRelatedTransactions(
                    transactionList,
                    relatedScheduleDetail,
                    originalPostedAfterDocumentDate,
                    branchID,
                    ref lineCounter);

                // Set amounts for related transactions
                // -
                decimal relatedTransactionTotal = 0;

                if (originalPostedAfterDocumentDate.Any())
                {
                    originalPostedAfterDocumentDate.SkipLast(1).ForEach((originalTransaction, i) =>
                    {
                        decimal rawTransactionAmount = multiplier * originalTransaction.Amount ?? 0;
                        transactionList[transactionsAddedDuringPreviousStep + i].Amount = _roundingFunction(rawTransactionAmount);

                        relatedTransactionTotal += transactionList[transactionsAddedDuringPreviousStep + i].Amount ?? 0;
                    });

                    transactionList[transactionList.Count - 1].Amount = residualPostedAmount - relatedTransactionTotal;
                }
            }

            transactionsAddedDuringPreviousStep = lineCounter;

            // Handle open transactions
            // -
            if (originalOpenTransactions != null && originalOpenTransactions.Any())
            {
                decimal originalOpenTransactionsTotal =
                    originalOpenTransactions.Sum(transaction => transaction.Amount ?? 0);

                AddRelatedTransactions(
                    transactionList,
                    relatedScheduleDetail,
                    originalOpenTransactions,
                    branchID,
                    ref lineCounter);

                // Set amounts for related transactions
                // -
                decimal multiplier = amountToDistributeForUnposted / originalOpenTransactionsTotal;
                decimal relatedTransactionTotal = 0;

                originalOpenTransactions.SkipLast(1).ForEach((originalTransaction, i) =>
                {
                    decimal rawTransactionAmount = multiplier * originalTransaction.Amount.Value;
                    transactionList[transactionsAddedDuringPreviousStep + i].Amount = _roundingFunction(rawTransactionAmount);

                    relatedTransactionTotal += transactionList[transactionsAddedDuringPreviousStep + i].Amount ?? 0;
                });

                transactionList[transactionList.Count - 1].Amount = amountToDistributeForUnposted - relatedTransactionTotal;
            }
            else if (amountToDistributeForUnposted > 0)
            {
                ++lineCounter;

                DRScheduleTran deferralTransaction = new DRScheduleTran
                {
                    Amount      = amountToDistributeForUnposted,
                    BranchID    = branchID,
                    AccountID   = relatedScheduleDetail.AccountID,
                    SubID       = relatedScheduleDetail.SubID,
                    RecDate     = relatedScheduleDetail.DocDate,
                    FinPeriodID = relatedScheduleDetail.FinPeriodID,
                    LineNbr     = lineCounter,
                    ScheduleID  = relatedScheduleDetail.ScheduleID,
                    ComponentID = relatedScheduleDetail.ComponentID,
                    Status      = DRScheduleTranStatus.Open
                };

                transactionList.Add(deferralTransaction);
            }

            return(transactionList);
        }
        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);
        }