示例#1
0
        protected virtual void DRScheduleDetail_RowInserted(PXCache sender, PXRowInsertedEventArgs e)
        {
            DRScheduleDetail row = e.Row as DRScheduleDetail;

            if (row != null && Schedule.Current != null)
            {
                row.Status     = DRScheduleStatus.Draft;
                row.IsCustom   = true;
                row.ScheduleID = Schedule.Current.ScheduleID;
                SyncProperties(Schedule.Current, row);


                if (row.ComponentID == null)
                {
                    row.ComponentID = DRScheduleDetail.EmptyComponentID;
                }
            }

            InventoryItem item = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <DRScheduleDetail.componentID> > > > .Select(this, row.ComponentID);

            if (item != null)
            {
                row.AccountID = row.Module == BatchModule.AP ? item.COGSAcctID : item.SalesAcctID;
                row.SubID     = row.Module == BatchModule.AP ? item.COGSSubID : item.SalesSubID;

                DRDeferredCode defCode = PXSelect <DRDeferredCode, Where <DRDeferredCode.deferredCodeID, Equal <Required <DRScheduleDetail.defCode> > > > .Select(this, item.DeferredCode);

                if (defCode != null)
                {
                    row.DefCode   = defCode.DeferredCodeID;
                    row.DefAcctID = defCode.AccountID;
                    row.DefSubID  = defCode.SubID;
                }
            }
        }
示例#2
0
        private void AddComponentScheduleDetail(
            INComponent inventoryItemComponent,
            DRDeferredCode componentDeferralCode,
            InventoryItem inventoryItem,
            decimal amount,
            DRProcess.DRScheduleParameters tranInfo,
            int?overridenSubID)
        {
            if (amount == 0m)
            {
                return;
            }

            DRScheduleDetail scheduleDetail = InsertScheduleDetail(
                inventoryItem.InventoryID,
                componentDeferralCode,
                amount,
                GetDeferralAccountSubaccount(componentDeferralCode, inventoryItem, tranInfo),
                GetSalesOrExpenseAccountSubaccount(inventoryItemComponent, inventoryItem),
                overridenSubID);

            if (!_isDraft)
            {
                IEnumerable <DRScheduleTran> deferralTransactions
                    = _drEntityStorage.CreateDeferralTransactions(_schedule, scheduleDetail, componentDeferralCode, _branchID);

                _drEntityStorage.NonDraftDeferralTransactionsPrepared(scheduleDetail, componentDeferralCode, deferralTransactions);
            }
        }
示例#3
0
        public virtual IEnumerable GenTran(PXAdapter adapter)
        {
            if (Components.Current != null)
            {
                DRDeferredCode defCode = DeferredCode.Select();
                if (defCode != null)
                {
                    PXResultset <DRScheduleTran> res = Transactions.Select();

                    if (res.Count > 0)
                    {
                        WebDialogResult result = Components.View.Ask(Components.Current, GL.Messages.Confirmation, Messages.RegenerateTran, MessageButtons.YesNo, MessageIcon.Question);
                        if (result == WebDialogResult.Yes)
                        {
                            CreateTransactions(defCode, Accessinfo.BranchID);
                        }
                    }
                    else
                    {
                        CreateTransactions(defCode, Accessinfo.BranchID);
                    }
                }
            }
            return(adapter.Get());
        }
示例#4
0
        /// <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);
                    }
                }
            }
        }
示例#5
0
        /// <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);
        }
        private void UpdateOriginalSingleSchedule(ARRegister originalDocument, decimal amount)
        {
            foreach (PXResult <ARTran, InventoryItem, INComponent, DRDeferredCode> item in ARTransactionWithItems.Select())
            {
                ARTran         artran        = item;
                InventoryItem  inventoryItem = item;
                INComponent    component     = item;
                DRDeferredCode deferredCode  = item;

                UpdateOriginalSchedule(artran, deferredCode, amount, originalDocument.DocDate, originalDocument.FinPeriodID, originalDocument.CustomerID, originalDocument.CustomerLocationID);
            }
        }
示例#7
0
        /// <summary>
        /// For a given schedule detail, reevaluates deferral transactions
        /// if they exist, otherwise, creates them anew.
        /// </summary>
        private void ReevaluateOrCreateTransactions(DRScheduleDetail scheduleDetail)
        {
            DRDeferredCode detailDeferralCode = _drEntityStorage.GetDeferralCode(scheduleDetail.DefCode);

            IList <DRScheduleTran> transactionList =
                _drEntityStorage.GetDeferralTransactions(scheduleDetail.ScheduleID, scheduleDetail.ComponentID);

            if (!transactionList.Any() && !_isDraft)
            {
                _drEntityStorage.CreateDeferralTransactions(_schedule, scheduleDetail, detailDeferralCode, _branchID);
            }
            else
            {
                decimal?totalTransactionAmount = transactionList.Sum(transaction => transaction.Amount);

                if (totalTransactionAmount != scheduleDetail.TotalAmt)
                {
                    if (transactionList.IsSingleElement())
                    {
                        UpdateTransactionAmount(
                            scheduleDetail,
                            detailDeferralCode,
                            transactionList.Single(),
                            scheduleDetail.TotalAmt);
                    }
                    else if (transactionList.HasAtLeastTwoItems())
                    {
                        decimal correctedTotal = 0;

                        transactionList.SkipLast(1).ForEach(transaction =>
                        {
                            decimal correctedAmountRaw = transaction.Amount.Value * scheduleDetail.TotalAmt.Value / totalTransactionAmount.Value;
                            decimal correctedAmount    = _roundingFunction(correctedAmountRaw);

                            correctedTotal += correctedAmount;

                            UpdateTransactionAmount(
                                scheduleDetail,
                                detailDeferralCode,
                                transaction,
                                correctedAmount);
                        });

                        UpdateTransactionAmount(
                            scheduleDetail,
                            detailDeferralCode,
                            transactionList.Last(),
                            scheduleDetail.TotalAmt - correctedTotal);
                    }
                }
            }
        }
示例#8
0
        private DRScheduleDetail InsertScheduleDetail(
            int?componentID,
            DRDeferredCode defCode,
            decimal amount,
            AccountSubaccountPair deferralAccountSubaccount,
            AccountSubaccountPair salesOrExpenseAccountSubaccount,
            int?overridenSubID = null)
        {
            FinPeriod detailFinPeriod = FinPeriodRepository
                                        .GetFinPeriodByMasterPeriodID(PXAccess.GetParentOrganizationID(_branchID),
                                                                      _schedule.FinPeriodID).GetValueOrRaiseError();

            DRScheduleDetail scheduleDetail = new DRScheduleDetail
            {
                ScheduleID    = _schedule.ScheduleID,
                BranchID      = _branchID,
                ComponentID   = componentID,
                CuryTotalAmt  = amount,
                CuryDefAmt    = amount,
                DefCode       = defCode.DeferredCodeID,
                Status        = _isDraft ? DRScheduleStatus.Draft : DRScheduleStatus.Open,
                IsCustom      = false,
                IsOpen        = true,
                Module        = _schedule.Module,
                DocType       = _schedule.DocType,
                RefNbr        = _schedule.RefNbr,
                LineNbr       = _schedule.LineNbr,
                FinPeriodID   = detailFinPeriod.FinPeriodID,
                TranPeriodID  = detailFinPeriod.MasterFinPeriodID,
                BAccountID    = _schedule.BAccountID,
                AccountID     = salesOrExpenseAccountSubaccount.AccountID,
                SubID         = overridenSubID ?? salesOrExpenseAccountSubaccount.SubID,
                DefAcctID     = deferralAccountSubaccount.AccountID,
                DefSubID      = deferralAccountSubaccount.SubID,
                CreditLineNbr = 0,
                DocDate       = _schedule.DocDate,
                BAccountType  =
                    _schedule.Module == BatchModule.AP
                                                ? BAccountType.VendorType
                                                : BAccountType.CustomerType,
            };

            scheduleDetail = _drEntityStorage.Insert(scheduleDetail);

            if (!_isDraft)
            {
                _drEntityStorage.CreateCreditLineTransaction(scheduleDetail, defCode, _branchID);
            }

            return(scheduleDetail);
        }
示例#9
0
 private void ValidateMDAConsistency(InventoryItem inventoryItem, DRDeferredCode deferralCode)
 {
     if (inventoryItem != null &&
         inventoryItem.IsSplitted == true &&
         deferralCode.MultiDeliverableArrangement == false)
     {
         throw new PXException(Messages.DeferralCodeNotMDA);
     }
     else if (
         inventoryItem == null &&
         deferralCode.MultiDeliverableArrangement == true)
     {
         throw new PXException(Messages.MDACodeButNoInventoryItem);
     }
 }
示例#10
0
        protected virtual void DRScheduleDetail_DefCode_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
        {
            DRScheduleDetail row = e.Row as DRScheduleDetail;

            if (row != null)
            {
                DRDeferredCode defCode = PXSelect <DRDeferredCode, Where <DRDeferredCode.deferredCodeID, Equal <Required <DRScheduleDetail.defCode> > > > .Select(this, row.DefCode);

                if (defCode != null)
                {
                    row.DefCode   = defCode.DeferredCodeID;
                    row.DefAcctID = defCode.AccountID;
                    row.DefSubID  = defCode.SubID;
                }
            }
        }
示例#11
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);
        }
示例#12
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);
            }
        }
示例#13
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);
            }
        }
示例#14
0
        /// <summary>
        /// For a given schedule detail, reevaluates deferral transactions if they exist.
        /// </summary>
        private void ReevaluateTransactionAmounts(
            DRScheduleDetail scheduleComponent,
            DRDeferredCode componentDeferralCode,
            IEnumerable <DRScheduleTran> componentTransactions)
        {
            decimal?totalTransactionAmount = componentTransactions.Sum(transaction => transaction.Amount);

            if (totalTransactionAmount == scheduleComponent.CuryTotalAmt)
            {
                return;
            }

            if (componentTransactions.IsSingleElement())
            {
                UpdateTransactionAmount(
                    scheduleComponent,
                    componentDeferralCode,
                    componentTransactions.Single(),
                    scheduleComponent.CuryTotalAmt);
            }
            else if (componentTransactions.HasAtLeastTwoItems())
            {
                decimal correctedTotal = 0;

                componentTransactions.SkipLast(1).ForEach(transaction =>
                {
                    decimal correctedAmountRaw = transaction.Amount.Value * scheduleComponent.CuryTotalAmt.Value / totalTransactionAmount.Value;
                    decimal correctedAmount    = _roundingFunction(correctedAmountRaw);

                    correctedTotal += correctedAmount;

                    UpdateTransactionAmount(
                        scheduleComponent,
                        componentDeferralCode,
                        transaction,
                        correctedAmount);
                });

                UpdateTransactionAmount(
                    scheduleComponent,
                    componentDeferralCode,
                    componentTransactions.Last(),
                    scheduleComponent.CuryTotalAmt - correctedTotal);
            }
        }
示例#15
0
        private DRScheduleDetail InsertScheduleDetail(
            int?componentID,
            DRDeferredCode defCode,
            decimal amount,
            AccountSubaccountPair deferralAccountSubaccount,
            AccountSubaccountPair salesOrExpenseAccountSubaccount)
        {
            DRScheduleDetail scheduleDetail = new DRScheduleDetail
            {
                ScheduleID    = _schedule.ScheduleID,
                ComponentID   = componentID,
                TotalAmt      = amount,
                DefAmt        = amount,
                DefCode       = defCode.DeferredCodeID,
                Status        = _isDraft ? DRScheduleStatus.Draft : DRScheduleStatus.Open,
                IsCustom      = false,
                IsOpen        = true,
                Module        = _schedule.Module,
                DocType       = _schedule.DocType,
                RefNbr        = _schedule.RefNbr,
                LineNbr       = _schedule.LineNbr,
                FinPeriodID   = _schedule.FinPeriodID,
                BAccountID    = _schedule.BAccountID,
                AccountID     = salesOrExpenseAccountSubaccount.AccountID,
                SubID         = salesOrExpenseAccountSubaccount.SubID,
                DefAcctID     = deferralAccountSubaccount.AccountID,
                DefSubID      = deferralAccountSubaccount.SubID,
                CreditLineNbr = 0,
                DocDate       = _schedule.DocDate,
                BAccountType  =
                    _schedule.Module == BatchModule.AP
                                                ? BAccountType.VendorType
                                                : BAccountType.CustomerType,
            };

            scheduleDetail = _drEntityStorage.Insert(scheduleDetail);

            if (!_isDraft)
            {
                _drEntityStorage.CreateCreditLineTransaction(scheduleDetail, defCode, _branchID);
            }

            return(scheduleDetail);
        }
示例#16
0
        private void CreateDetails(
            DRProcess.DRScheduleParameters scheduleParameters,
            DRDeferredCode deferralCode,
            InventoryItem inventoryItem,
            AccountSubaccountPair salesOrExpenseAccountSubaccount,
            decimal?transactionAmount,
            decimal?fairUnitPrice,
            decimal?compoundDiscountRate,
            decimal?quantityInBaseUnit)
        {
            if (deferralCode.MultiDeliverableArrangement == true && inventoryItem != null && inventoryItem.IsSplitted == true)
            {
                CreateDetailsForSplitted(
                    scheduleParameters,
                    inventoryItem,
                    salesOrExpenseAccountSubaccount.SubID,
                    transactionAmount,
                    fairUnitPrice,
                    compoundDiscountRate ?? 1.0m,
                    quantityInBaseUnit ?? 0.0m);
            }
            else
            {
                var deferralAccountSubaccount = GetDeferralAccountSubaccount(deferralCode, inventoryItem, scheduleParameters);

                int?componentID = inventoryItem == null ? DRScheduleDetail.EmptyComponentID : inventoryItem.InventoryID;

                DRScheduleDetail scheduleDetail = InsertScheduleDetail(
                    componentID,
                    deferralCode,
                    transactionAmount.Value,
                    deferralAccountSubaccount,
                    salesOrExpenseAccountSubaccount);

                if (!_isDraft)
                {
                    IEnumerable <DRScheduleTran> deferralTransactions =
                        _drEntityStorage.CreateDeferralTransactions(_schedule, scheduleDetail, deferralCode, _branchID);

                    _drEntityStorage.NonDraftDeferralTransactionsPrepared(scheduleDetail, deferralCode, deferralTransactions);
                }
            }
        }
示例#17
0
        /// <param name="roundingFunction">
        /// An optional parameter specifying a function that would be used to round
        /// the calculated transaction amounts. If <c>null</c>, the generator will use
        /// <see cref="PXDBCurrencyAttribute.BaseRound(PXGraph, decimal)"/> by default.
        /// </param>
        /// <param name="financialPeriodProvider">
        /// An optional parameter specifying an object that would be used to manipulate
        /// financial periods, e.g. extract a start date or an end date for a given period ID.
        /// If <c>null</c>, the generator will use <see cref="FinancialPeriodProvider.Default"/>.
        /// </param>
        public TransactionsGenerator(
            PXGraph graph,
            DRDeferredCode code,
            IFinancialPeriodProvider financialPeriodProvider = null,
            Func <decimal, decimal> roundingFunction         = null)
        {
            if (graph == null)
            {
                throw new ArgumentNullException(nameof(graph));
            }
            if (code == null)
            {
                throw new ArgumentNullException(nameof(code));
            }

            _graph                   = graph;
            _code                    = code;
            _roundingFunction        = roundingFunction ?? (rawAmount => PXDBCurrencyAttribute.BaseRound(_graph, rawAmount));
            _financialPeriodProvider = financialPeriodProvider ?? FinancialPeriodProvider.Default;
        }
示例#18
0
        private void CreateTransactions(DRDeferredCode defCode, int?branchID)
        {
            if (Components.Current != null && Components.Current.Status == DRScheduleStatus.Draft)
            {
                foreach (DRScheduleTran tran in Transactions.Select())
                {
                    Transactions.Delete(tran);
                }

                if (Schedule.Current != null && Components.Current != null && defCode != null)
                {
                    IList <DRScheduleTran> tranList = DRProcess.GenerateTransactions(this, Schedule.Current, Components.Current, defCode, branchID);

                    foreach (DRScheduleTran tran in tranList)
                    {
                        Transactions.Insert(tran);
                    }
                }
            }
        }
示例#19
0
        /// <param name="roundingFunction">
        /// An optional parameter specifying a function that would be used to round
        /// the calculated transaction amounts. If <c>null</c>, the generator will use
        /// <see cref="PXDBCurrencyAttribute.BaseRound(PXGraph, decimal)"/> by default.
        /// </param>
        /// <param name="financialPeriodProvider">
        /// An optional parameter specifying an object that would be used to manipulate
        /// financial periods, e.g. extract a start date or an end date for a given period ID.
        /// If <c>null</c>, the generator will use <see cref="FinancialPeriodProvider.Default"/>.
        /// </param>
        public TransactionsGenerator(
            PXGraph graph,
            DRDeferredCode code,
            IFinPeriodRepository finPeriodRepository = null,
            Func <decimal, decimal> roundingFunction = null)
        {
            if (graph == null)
            {
                throw new ArgumentNullException(nameof(graph));
            }
            if (code == null)
            {
                throw new ArgumentNullException(nameof(code));
            }

            _graph               = graph;
            _code                = code;
            _roundingFunction    = roundingFunction ?? (rawAmount => PXDBCurrencyAttribute.BaseRound(_graph, rawAmount));
            _finPeriodRepository = finPeriodRepository ?? _graph.GetService <IFinPeriodRepository>();
        }
示例#20
0
        private AccountSubaccountPair GetSalesAccountSubaccount(
            DRDeferredCode deferralCode,
            InventoryItem item,
            INComponent component,
            ARTran transaction)
        {
            int?accountID    = transaction.AccountID;
            int?subaccountID = transaction.SubID;

            if (deferralCode.MultiDeliverableArrangement == true)
            {
                accountID = component.SalesAcctID;
            }

            if (deferralCode.MultiDeliverableArrangement == true && item.UseParentSubID == true)
            {
                subaccountID = component.SalesSubID;
            }

            return(new AccountSubaccountPair(accountID, subaccountID));
        }
示例#21
0
        private void RunVerification()
        {
            if (Schedule.Current != null && Schedule.Current.RefNbr != null && Schedule.Current.OrigLineAmt.GetValueOrDefault() != 0)
            {
                decimal total = 0;
                foreach (DRScheduleDetail sd in Components.Select())
                {
                    total += sd.TotalAmt ?? 0;

                    DRDeferredCode dc = PXSelect <DRDeferredCode, Where <DRDeferredCode.deferredCodeID, Equal <Current <DRScheduleDetail.defCode> > > > .Select(this);

                    bool checkTotal = true;

                    if (dc != null && dc.Method == DeferredMethodType.CashReceipt)
                    {
                        checkTotal = false;
                    }

                    if (checkTotal)
                    {
                        decimal defTotal = SumOpenAndProjectedTransactions(sd);
                        if (defTotal != sd.DefAmt)
                        {
                            if (Components.Cache.RaiseExceptionHandling <DRScheduleDetail.defTotal>(sd, defTotal, new PXSetPropertyException(Messages.DeferredAmountSumError)))
                            {
                                throw new PXRowPersistingException(typeof(DRScheduleDetail.defTotal).Name, defTotal, Messages.DeferredAmountSumError);
                            }
                        }
                    }
                }

                if (total != Schedule.Current.OrigLineAmt)
                {
                    throw new PXException(Messages.SumOfComponentsError);
                }
            }
        }
示例#22
0
        private void AddComponentScheduleDetail(
            INComponent inventoryItemComponent,
            DRDeferredCode componentDeferralCode,
            InventoryItem inventoryItem,
            decimal amount,
            DRProcess.DRScheduleParameters tranInfo)
        {
            if (amount == 0m)
            {
                return;
            }

            DRScheduleDetail scheduleDetail = InsertScheduleDetail(
                inventoryItem.InventoryID,
                componentDeferralCode,
                amount,
                GetDeferralAccountSubaccount(componentDeferralCode, inventoryItem, tranInfo),
                GetSalesOrExpenseAccountSubaccount(inventoryItemComponent, inventoryItem));

            if (!_isDraft)
            {
                _drEntityStorage.CreateDeferralTransactions(_schedule, scheduleDetail, componentDeferralCode, _branchID);
            }
        }
        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;
        }
示例#24
0
        private AccountSubaccountPair GetDeferralAccountSubaccount(
            DRDeferredCode deferralCode,
            InventoryItem item,
            DRProcess.DRScheduleParameters scheduleParameters)
        {
            int?accountID = deferralCode.AccountID;

            string subaccountCD = null;
            int?   subaccountID = null;

            if (deferralCode.AccountSource == DeferralAccountSource.Item)
            {
                accountID = item != null ? item.DeferralAcctID : subaccountID;
                // this is fishy. subID is always null at this point.
            }

            if (deferralCode.CopySubFromSourceTran == true)
            {
                subaccountID = scheduleParameters.SubID;
            }
            else if (scheduleParameters.Module == BatchModule.AP)
            {
                int?itemSubID = item?.DeferralSubID;

                Location location = _businessAccountProvider
                                    .GetLocation(scheduleParameters.BAccountID, scheduleParameters.BAccountLocID);

                int?locationSubID = location?.VExpenseSubID;

                EPEmployee employee = _businessAccountProvider
                                      .GetEmployee(scheduleParameters.EmployeeID);

                int?employeeSubaccountID = employee?.ExpenseSubID;

                subaccountCD = _subaccountProvider.MakeSubaccount <DRScheduleDetail.subID>(
                    deferralCode.DeferralSubMaskAP,
                    new object[] { locationSubID, itemSubID, employeeSubaccountID, deferralCode.SubID },
                    new []
                {
                    typeof(Location.vExpenseSubID),
                    typeof(InventoryItem.deferralSubID),
                    typeof(EPEmployee.expenseSubID),
                    typeof(DRDeferredCode.subID)
                });
            }
            else if (scheduleParameters.Module == BatchModule.AR)
            {
                int?itemSubID = item?.DeferralSubID;

                Location location = _businessAccountProvider
                                    .GetLocation(scheduleParameters.BAccountID, scheduleParameters.BAccountLocID);

                int?locationSubaccountID = location?.CSalesSubID;

                EPEmployee employee = _businessAccountProvider
                                      .GetEmployee(scheduleParameters.EmployeeID);

                int?employeeSubaccountID = employee?.SalesSubID;

                SalesPerson salesPerson = _businessAccountProvider
                                          .GetSalesPerson(scheduleParameters.SalesPersonID);

                int?salesPersonSubaccountID = salesPerson?.SalesSubID;

                subaccountCD = _subaccountProvider.MakeSubaccount <DRScheduleDetail.subID>(
                    deferralCode.DeferralSubMaskAR,
                    new object[] { locationSubaccountID, itemSubID, employeeSubaccountID, deferralCode.SubID, salesPersonSubaccountID },
                    new []
                {
                    typeof(Location.cSalesSubID),
                    typeof(InventoryItem.deferralSubID),
                    typeof(EPEmployee.salesSubID),
                    typeof(DRDeferredCode.subID),
                    typeof(SalesPerson.salesSubID)
                });
            }

            if (subaccountCD != null)
            {
                subaccountID = _subaccountProvider.GetSubaccountID(subaccountCD);
            }

            return(new AccountSubaccountPair(accountID, subaccountID));
        }
示例#25
0
        private void CreateScheduleDetails(DRProcess.DRScheduleParameters scheduleParameters, Amount lineTotal)
        {
            decimal scheduleFairTotal = 0;

            var errors = new List <string>();

            foreach (PXResult <ARTran, InventoryItem, DRDeferredCode, INComponent,
                               DRSingleProcess.ComponentINItem, DRSingleProcess.ComponentDeferredCode> item in _singleScheduleViewProvider.GetParentDocumentDetails())
            {
                ARTran         artran        = item;
                InventoryItem  inventoryItem = item;
                DRDeferredCode deferredCode  = item;
                INComponent    component     = item;
                DRSingleProcess.ComponentINItem       componentINItem       = item;
                DRSingleProcess.ComponentDeferredCode componentDeferredCode = item;

                bool isMDA = deferredCode.MultiDeliverableArrangement == true;

                AccountSubaccountPair deferralAccountSubaccount = GetDeferralAccountSubaccount(
                    isMDA ? componentDeferredCode: deferredCode,
                    isMDA ? componentINItem : inventoryItem,
                    scheduleParameters,
                    artran.SubID);

                AccountSubaccountPair salesAccountSubaccount = GetSalesAccountSubaccount(deferredCode, inventoryItem, component, artran);

                bool isFlexibleMethod = deferredCode.Method == DeferredMethodType.FlexibleProrateDays ||
                                        deferredCode.Method == DeferredMethodType.FlexibleExactDays ||
                                        componentDeferredCode?.Method == DeferredMethodType.FlexibleProrateDays ||
                                        componentDeferredCode?.Method == DeferredMethodType.FlexibleExactDays;

                try
                {
                    DRScheduleDetail detail = CreateScheduleDetail(
                        artran,
                        component,
                        deferredCode,
                        deferralAccountSubaccount,
                        salesAccountSubaccount,
                        isFlexibleMethod);

                    detail = _drEntityStorage.Insert(detail);
                    SetFairValuePrice(detail);
                    detail = _drEntityStorage.Update(detail);

                    if (!_isDraft)
                    {
                        _drEntityStorage.CreateCreditLineTransaction(detail, deferredCode, _branchID);
                    }

                    scheduleFairTotal += detail.EffectiveFairValuePrice.Value * detail.Qty.Value;
                }
                catch (NoFairValuePriceFoundException e)
                {
                    errors.Add(e.Message);
                    continue;
                }
            }

            if (errors.Any())
            {
                throw new NoFairValuePricesFoundException(string.Join(Environment.NewLine, errors));
            }

            if (scheduleFairTotal == 0m)
            {
                throw new PXException(Messages.SumOfFairValuePricesEqualToZero);
            }

            IEnumerable <DRScheduleDetail> scheduleDetails = _drEntityStorage.GetScheduleDetails(_schedule.ScheduleID)
                                                             .RowCast <DRScheduleDetail>()
                                                             .ToList();

            if (scheduleDetails.IsSingleElement())
            {
                DRScheduleDetail scheduleDetail = scheduleDetails.Single();
                scheduleDetail.CuryTotalAmt = lineTotal.Cury;
                scheduleDetail.CuryDefAmt   = lineTotal.Cury;
                scheduleDetail.Percentage   = 1m;
                _drEntityStorage.Update(scheduleDetail);
            }
            else if (scheduleDetails.HasAtLeastTwoItems())
            {
                decimal          sumPercent = 0m;
                decimal          sumResult  = 0m;
                DRScheduleDetail maxAmtLine = null;

                scheduleDetails.ForEach(scheduleDetail =>
                {
                    scheduleDetail.Percentage = scheduleDetail.EffectiveFairValuePrice * scheduleDetail.Qty / scheduleFairTotal;
                    sumPercent += scheduleDetail.Percentage ?? 0m;

                    decimal?rawResult = lineTotal.Cury * scheduleDetail.Percentage;
                    decimal?result    = _roundingFunction(rawResult.Value);
                    sumResult        += result ?? 0m;

                    scheduleDetail.CuryTotalAmt = result;
                    scheduleDetail.CuryDefAmt   = result;

                    var detail = _drEntityStorage.Update(scheduleDetail);

                    if ((maxAmtLine?.CuryTotalAmt ?? 0m) < detail.CuryTotalAmt)
                    {
                        maxAmtLine = detail;
                    }
                });

                if (sumPercent != 1m || sumResult != lineTotal.Cury)
                {
                    decimal?amtDiff = lineTotal.Cury - sumResult;

                    maxAmtLine.CuryTotalAmt += amtDiff;
                    maxAmtLine.CuryDefAmt   += amtDiff;
                    maxAmtLine.Percentage   += 1m - sumPercent;

                    _drEntityStorage.Update(maxAmtLine);
                }
            }

            if (!_isDraft)
            {
                foreach (PXResult <DRScheduleDetail, DRDeferredCode> detail in _dataProvider.GetScheduleDetailsResultset(_schedule.ScheduleID))
                {
                    DRScheduleDetail scheduleDetail = detail;
                    DRDeferredCode   deferralCode   = detail;

                    IEnumerable <DRScheduleTran> deferralTransactions =
                        _drEntityStorage.CreateDeferralTransactions(_schedule, scheduleDetail, deferralCode, _branchID);

                    _drEntityStorage.NonDraftDeferralTransactionsPrepared(scheduleDetail, deferralCode, deferralTransactions);
                }
            }
        }
示例#26
0
        private DRScheduleDetail CreateScheduleDetail(
            ARTran artran,
            INComponent component,
            DRDeferredCode defCode,
            AccountSubaccountPair deferralAccountSubaccount,
            AccountSubaccountPair salesAccountSubaccount,
            bool isFlexibleMethod)
        {
            string  uom        = artran.UOM;
            decimal?qty        = artran.Qty;
            decimal coTermRate = 1m;

            if (component?.ComponentID != null)
            {
                uom = component.UOM;
                if (artran.UOM == component.UOM)
                {
                    qty = artran.Qty * component.Qty;
                }
                else
                {
                    var qtyBase = _salesPriceProvider.GetQuantityInBaseUOMs(artran);
                    qty = qtyBase * component.Qty;
                }
            }

            if (isFlexibleMethod == true)
            {
                coTermRate = (((artran.DRTermEndDate.Value - artran.DRTermStartDate.Value).Days + 1.0m) / 365.0m);
            }

            FinPeriod detailFinPeriod = FinPeriodRepository
                                        .GetFinPeriodByMasterPeriodID(PXAccess.GetParentOrganizationID(artran.BranchID), artran.TranPeriodID).GetValueOrRaiseError();

            DRScheduleDetail scheduleDetail = new DRScheduleDetail
            {
                ScheduleID        = _schedule.ScheduleID,
                BranchID          = artran.BranchID,
                ComponentID       = component?.ComponentID ?? artran.InventoryID,
                ParentInventoryID = component?.ComponentID != null ? artran.InventoryID : null,
                DefCode           = component?.DeferredCode ?? defCode.DeferredCodeID,
                Status            = _isDraft ? DRScheduleStatus.Draft : DRScheduleStatus.Open,
                IsCustom          = false,
                IsOpen            = true,
                Module            = _schedule.Module,
                DocType           = _schedule.DocType,
                RefNbr            = _schedule.RefNbr,
                LineNbr           = artran.LineNbr,
                FinPeriodID       = detailFinPeriod.FinPeriodID,
                TranPeriodID      = detailFinPeriod.MasterFinPeriodID,
                BAccountID        = _schedule.BAccountID,
                AccountID         = salesAccountSubaccount.AccountID,
                SubID             = salesAccountSubaccount.SubID,
                DefAcctID         = deferralAccountSubaccount.AccountID,
                DefSubID          = deferralAccountSubaccount.SubID,
                CreditLineNbr     = 0,
                DocDate           = _schedule.DocDate,
                UOM          = uom,
                Qty          = qty,
                BAccountType =
                    _schedule.Module == BatchModule.AP
                                                ? BAccountType.VendorType
                                                : BAccountType.CustomerType,
                TermStartDate = artran.DRTermStartDate,
                TermEndDate   = artran.DRTermEndDate,
                CoTermRate    = coTermRate,
            };

            return(scheduleDetail);
        }
示例#27
0
        /// <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 bool RequiresTerms(DRDeferredCode code)
 {
     return(code != null && RequiresTerms(code.Method));
 }
示例#29
0
        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);
            }
        }