protected override PMCommitment FromRecord(PXCache sender, object row)
        {
            SOMiscLine2 line  = (SOMiscLine2)row;
            SOOrder     order = (SOOrder)PXParentAttribute.SelectParent(sender.Graph.Caches[detailEntity], row, typeof(SOOrder));

            int sign = line.Operation == SOOperation.Issue ? 1 : -1;

            PMCommitment commitment = new PMCommitment();

            commitment.Type               = PMCommitmentType.Internal;
            commitment.CommitmentID       = line.CommitmentID ?? Guid.NewGuid();
            commitment.AccountGroupID     = GetAccountGroup(sender, row);
            commitment.ProjectID          = line.ProjectID;
            commitment.ProjectTaskID      = line.TaskID;
            commitment.UOM                = line.UOM;
            commitment.Qty                = sign * line.OrderQty;
            commitment.Amount             = sign * line.LineAmt;
            commitment.OpenQty            = sign * line.UnbilledQty;
            commitment.OpenAmount         = sign * line.UnbilledAmt;
            commitment.ReceivedQty        = 0;
            commitment.InvoicedQty        = 0;
            commitment.InvoicedAmount     = 0;
            commitment.InvoicedIsReadonly = true;
            commitment.RefNoteID          = order.NoteID;
            commitment.InventoryID        = line.InventoryID ?? PMInventorySelectorAttribute.EmptyInventoryID;
            commitment.CostCodeID         = line.CostCodeID ?? CostCodeAttribute.GetDefaultCostCode();

            return(commitment);
        }
        public virtual PMBudget SelectProjectBalanceByCostCodes(IProjectFilter filter)
        {
            PXSelectBase <PMBudget> selectBudget = new PXSelect <PMBudget,
                                                                 Where <PMBudget.accountGroupID, Equal <Required <PMBudget.accountGroupID> >,
                                                                        And <PMBudget.projectID, Equal <Required <PMBudget.projectID> >,
                                                                             And <PMBudget.projectTaskID, Equal <Required <PMBudget.projectTaskID> >,
                                                                                  And <Where <PMBudget.costCodeID, Equal <Required <PMBudget.costCodeID> >, Or <PMBudget.costCodeID, Equal <Required <PMBudget.costCodeID> > > > > > > > >(graph);

            PMBudget withCostCode    = null;
            PMBudget withoutCostCode = null;

            foreach (PMBudget item in selectBudget.Select(filter.AccountGroupID, filter.ProjectID, filter.TaskID, filter.CostCodeID, CostCodeAttribute.GetDefaultCostCode()))            //0..2 records
            {
                if (item.CostCodeID == CostCodeAttribute.GetDefaultCostCode())
                {
                    withoutCostCode = item;
                }
                else
                {
                    withCostCode = item;
                }
            }

            return(withCostCode ?? withoutCostCode);
        }
        protected override PMCommitment FromRecord(PXCache sender, object row)
        {
            POLineUOpen poline = (POLineUOpen)row;
            POOrder     order  = (POOrder)PXParentAttribute.SelectParent(sender.Graph.Caches[detailEntity], row, typeof(POOrder));

            PMCommitment commitment = new PMCommitment();

            commitment.Type               = PMCommitmentType.Internal;
            commitment.CommitmentID       = poline.CommitmentID ?? Guid.NewGuid();
            commitment.AccountGroupID     = GetAccountGroup(sender, row);
            commitment.ProjectID          = poline.ProjectID;
            commitment.ProjectTaskID      = poline.TaskID;
            commitment.UOM                = poline.UOM;
            commitment.Qty                = poline.OrderQty;
            commitment.Amount             = poline.ExtCost;
            commitment.OpenQty            = poline.OpenQty;
            commitment.OpenAmount         = poline.OpenAmt;
            commitment.ReceivedQty        = poline.ReceivedQty;
            commitment.InvoicedQty        = 0;
            commitment.InvoicedAmount     = 0;
            commitment.InvoicedIsReadonly = true;
            commitment.RefNoteID          = order.NoteID;
            commitment.InventoryID        = poline.InventoryID ?? PMInventorySelectorAttribute.EmptyInventoryID;
            commitment.CostCodeID         = poline.CostCodeID ?? CostCodeAttribute.GetDefaultCostCode();

            return(commitment);
        }
        protected virtual void _(Events.FieldDefaulting <PMBudget, PMBudget.description> e)
        {
            if (e.Row == null)
            {
                return;
            }

            if (CostCodeAttribute.UseCostCode())
            {
                if (e.Row.CostCodeID != null && e.Row.CostCodeID != CostCodeAttribute.GetDefaultCostCode())
                {
                    PMCostCode costCode = PXSelectorAttribute.Select <PMBudget.costCodeID>(e.Cache, e.Row) as PMCostCode;
                    if (costCode != null)
                    {
                        e.NewValue = costCode.Description;
                    }
                }
            }
            else
            {
                if (e.Row.InventoryID != null && e.Row.InventoryID != PMInventorySelectorAttribute.EmptyInventoryID)
                {
                    InventoryItem item = PXSelectorAttribute.Select <PMBudget.inventoryID>(e.Cache, e.Row) as InventoryItem;
                    if (item != null)
                    {
                        e.NewValue = item.Descr;
                    }
                }
            }
        }
 protected virtual void _(Events.FieldDefaulting <PMCommitment, PMCommitment.costCodeID> e)
 {
     if (!CostCodeAttribute.UseCostCode())
     {
         e.NewValue = CostCodeAttribute.GetDefaultCostCode();
     }
 }
Exemple #6
0
 public virtual BudgetKeyTuple GetBudgetKey()
 {
     return(new BudgetKeyTuple(ProjectID.GetValueOrDefault(),
                               TaskID.GetValueOrDefault(),
                               AccountGroupID.GetValueOrDefault(),
                               InventoryID.GetValueOrDefault(PMInventorySelectorAttribute.EmptyInventoryID),
                               CostCodeID.GetValueOrDefault(CostCodeAttribute.GetDefaultCostCode())));
 }
        protected virtual void _(Events.FieldDefaulting <ARTran, ARTran.costCodeID> e)
        {
            PMProject project;

            if (CostCodeAttribute.UseCostCode() && ProjectDefaultAttribute.IsProject(Base, e.Row.ProjectID, out project))
            {
                if (project.BudgetLevel == BudgetLevels.Task)
                {
                    e.NewValue = CostCodeAttribute.GetDefaultCostCode();
                }
            }
        }
        protected virtual void _(Events.FieldDefaulting <PMBudget, PMBudget.costCodeID> e)
        {
            if (e.Row == null)
            {
                return;
            }

            PMProject project = PXSelect <PMProject, Where <PMProject.contractID, Equal <Required <PMProject.contractID> > > > .Select(this, e.Row.ProjectID);

            if (project != null)
            {
                if (project.BudgetLevel != BudgetLevels.CostCode)
                {
                    e.NewValue = CostCodeAttribute.GetDefaultCostCode();
                }
            }
        }
        public void FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
        {
            int?costCodeID = (int?)sender.GetValue(e.Row, costCodeField.Name);

            if (costCodeID != null && costCodeID != CostCodeAttribute.GetDefaultCostCode())
            {
                PMCostCode costCode = PXSelect <PMCostCode, Where <PMCostCode.costCodeID, Equal <Required <PMCostCode.costCodeID> > > > .Select(sender.Graph, costCodeID);

                if (costCode != null)
                {
                    var select = new PXSelect <PMWorkCode, Where <PMWorkCode.costCodeFrom, LessEqual <Required <PMWorkCode.costCodeFrom> >,
                                                                  And <PMWorkCode.costCodeTo, GreaterEqual <Required <PMWorkCode.costCodeTo> > > > >(sender.Graph);
                    PMWorkCode code = select.Select(costCode.CostCodeCD, costCode.CostCodeCD);
                    if (code != null)
                    {
                        e.NewValue = code.WorkCodeID;
                    }
                }
            }
        }
Exemple #10
0
        protected override PMCommitment FromRecord(PXCache sender, object row)
        {
            POLine  poline = (POLine)row;
            POOrder order  = (POOrder)PXParentAttribute.SelectParent(sender.Graph.Caches[detailEntity], row, typeof(POOrder));

            PMCommitment commitment = new PMCommitment();

            commitment.Type           = PMCommitmentType.Internal;
            commitment.CommitmentID   = poline.CommitmentID ?? Guid.NewGuid();
            commitment.AccountGroupID = GetAccountGroup(sender, row);
            commitment.ProjectID      = poline.ProjectID;
            commitment.ProjectTaskID  = poline.TaskID;
            commitment.UOM            = poline.UOM;
            if (poline.OrigExtCost == null)
            {
                commitment.OrigQty    = poline.OrderQty;
                commitment.OrigAmount = poline.ExtCost + poline.RetainageAmt.GetValueOrDefault();
            }
            else
            {
                commitment.OrigQty    = poline.OrigOrderQty;
                commitment.OrigAmount = poline.OrigExtCost;
            }
            commitment.Qty                = poline.OrderQty;
            commitment.Amount             = poline.ExtCost + poline.RetainageAmt.GetValueOrDefault();
            commitment.OpenQty            = CalculateOpenQty(poline.OpenQty, poline.UnbilledQty);
            commitment.OpenAmount         = CalculateOpenAmount(commitment.OpenQty, poline.OrderQty, poline.ExtCost, poline.UnbilledAmt);
            commitment.ReceivedQty        = CalculateReceivedQty(poline.CompletedQty, poline.BilledQty);
            commitment.InvoicedQty        = 0;
            commitment.InvoicedAmount     = 0;
            commitment.InvoicedIsReadonly = true;
            commitment.RefNoteID          = order.NoteID;
            commitment.InventoryID        = poline.InventoryID ?? PMInventorySelectorAttribute.EmptyInventoryID;
            commitment.CostCodeID         = poline.CostCodeID ?? CostCodeAttribute.GetDefaultCostCode();

            return(commitment);
        }
        public virtual void ProcessPOCommitments(PMProject project)
        {
            foreach (PXResult <POLine, POOrder> res in polines.Select(project.ContractID))
            {
                POLine  poline = (POLine)res;
                POOrder order  = (POOrder)res;
                PXParentAttribute.SetParent(polines.Cache, poline, typeof(POOrder), order);

                PMCommitmentAttribute.Sync(polines.Cache, poline);
            }

            foreach (APTran tran in aptran.Select(project.ContractID))
            {
                POLine poline = new POLine();
                poline.OrderType = tran.POOrderType;
                poline.OrderNbr  = tran.PONbr;
                poline.LineNbr   = tran.POLineNbr;

                poline = polines.Locate(poline);

                if (poline != null && poline.CommitmentID != null)
                {
                    decimal sign = (tran.DrCr == DrCr.Debit) ? Decimal.One : Decimal.MinusOne;

                    PMCommitment container = new PMCommitment();
                    container.CommitmentID   = poline.CommitmentID;
                    container.UOM            = tran.UOM;
                    container.InventoryID    = tran.InventoryID;
                    container.CostCodeID     = tran.CostCodeID.GetValueOrDefault(CostCodeAttribute.GetDefaultCostCode());
                    container.InvoicedAmount = sign * tran.LineAmt.GetValueOrDefault();
                    container.InvoicedQty    = sign * tran.Qty.GetValueOrDefault();

                    PMCommitmentAttribute.AddToInvoiced(polines.Cache, container);
                }
            }
        }
        public virtual void ProcessSOCommitments(PMProject project)
        {
            foreach (PXResult <SOLine, SOOrder> res in solines.Select(project.ContractID))
            {
                SOLine  soline = (SOLine)res;
                SOOrder order  = (SOOrder)res;
                PXParentAttribute.SetParent(solines.Cache, soline, typeof(SOOrder), order);

                PMCommitmentAttribute.Sync(solines.Cache, soline);
            }

            foreach (ARTran tran in artran.Select(project.ContractID))
            {
                SOLine soline = new SOLine();
                soline.OrderType = tran.SOOrderType;
                soline.OrderNbr  = tran.SOOrderNbr;
                soline.LineNbr   = tran.SOOrderLineNbr;

                soline = solines.Locate(soline);

                if (soline != null && soline.CommitmentID != null)
                {
                    decimal sign = (tran.DrCr == DrCr.Credit) ? Decimal.One : Decimal.MinusOne;

                    PMCommitment container = new PMCommitment();
                    container.CommitmentID   = soline.CommitmentID;
                    container.UOM            = tran.UOM;
                    container.InventoryID    = tran.InventoryID;
                    container.CostCodeID     = tran.CostCodeID.GetValueOrDefault(CostCodeAttribute.GetDefaultCostCode());
                    container.InvoicedAmount = sign * tran.TranAmt.GetValueOrDefault();
                    container.InvoicedQty    = sign * tran.Qty.GetValueOrDefault();

                    PMCommitmentAttribute.AddToInvoiced(solines.Cache, container);
                }
            }
        }
Exemple #13
0
        public virtual Result Calculate(PMProject project, PMTran pmt, PMAccountGroup ag, string accountType, int amountSign, int qtySign)
        {
            PMBudgetLite target = null;
            bool         isExisting;

            target = service.SelectProjectBalance(pmt, ag, project, out isExisting);

            var rollupQty = CalculateRollupQty(pmt, target);

            List <PMHistory>  list     = new List <PMHistory>();
            PMTaskTotal       ta       = null;
            PMBudget          ps       = null;
            PMForecastHistory forecast = null;

            if (pmt.TaskID != null && (rollupQty != 0 || pmt.Amount != 0))             //TaskID will be null for Contract
            {
                ps                = new PMBudget();
                ps.ProjectID      = target.ProjectID;
                ps.ProjectTaskID  = target.TaskID;
                ps.AccountGroupID = target.AccountGroupID;
                ps.Type           = target.Type;
                ps.InventoryID    = target.InventoryID;
                ps.CostCodeID     = target.CostCodeID;
                ps.UOM            = target.UOM;
                ps.IsProduction   = target.IsProduction;
                ps.Description    = target.Description;
                if (ps.CuryInfoID == null)
                {
                    ps.CuryInfoID = project.CuryInfoID;
                }
                decimal amt     = amountSign * pmt.Amount.GetValueOrDefault();
                decimal curyAmt = amountSign * pmt.ProjectCuryAmount.GetValueOrDefault();

                ps.ActualQty        = rollupQty * qtySign;
                ps.ActualAmount     = amt;
                ps.CuryActualAmount = curyAmt;

                #region PMTask Totals Update

                ta           = new PMTaskTotal();
                ta.ProjectID = ps.ProjectID;
                ta.TaskID    = ps.TaskID;

                string accType = ag.IsExpense == true ? AccountType.Expense : ag.Type;
                switch (accType)
                {
                case AccountType.Asset:
                    ta.CuryAsset = curyAmt;
                    ta.Asset     = amt;
                    break;

                case AccountType.Liability:
                    ta.CuryLiability = curyAmt;
                    ta.Liability     = amt;
                    break;

                case AccountType.Income:
                    ta.CuryIncome = curyAmt;
                    ta.Income     = amt;
                    break;

                case AccountType.Expense:
                    ta.CuryExpense = curyAmt;
                    ta.Expense     = amt;
                    break;
                }

                #endregion

                #region History
                PMHistory hist = new PMHistory();
                hist.ProjectID      = ps.ProjectID;
                hist.ProjectTaskID  = ps.TaskID;
                hist.AccountGroupID = ps.AccountGroupID;
                hist.InventoryID    = pmt.InventoryID ?? ps.InventoryID;
                hist.CostCodeID     = pmt.CostCodeID ?? ps.CostCodeID;
                hist.PeriodID       = pmt.FinPeriodID;
                hist.BranchID       = pmt.BranchID;
                decimal baseQty = 0;
                list.Add(hist);
                if (pmt.InventoryID != null && pmt.InventoryID != PMInventorySelectorAttribute.EmptyInventoryID && pmt.Qty != 0)
                {
                    if (PXAccess.FeatureInstalled <FeaturesSet.multipleUnitMeasure>())
                    {
                        baseQty = qtySign * IN.INUnitAttribute.ConvertToBase(graph.Caches[typeof(PMHistory)], pmt.InventoryID, pmt.UOM, pmt.Qty.Value, PX.Objects.IN.INPrecision.QUANTITY);
                    }
                    else
                    {
                        IN.InventoryItem initem = PXSelectorAttribute.Select <PMTran.inventoryID>(graph.Caches[typeof(PMTran)], pmt) as IN.InventoryItem;
                        if (initem != null && !string.IsNullOrEmpty(pmt.UOM))
                        {
                            baseQty = qtySign * IN.INUnitAttribute.ConvertGlobalUnits(graph, pmt.UOM, initem.BaseUnit, pmt.Qty ?? 0, IN.INPrecision.QUANTITY);
                        }
                    }
                }
                hist.FinPTDCuryAmount = curyAmt;
                hist.FinPTDAmount     = amt;
                hist.FinYTDCuryAmount = curyAmt;
                hist.FinYTDAmount     = amt;
                hist.FinPTDQty        = baseQty;
                hist.FinYTDQty        = baseQty;
                if (pmt.FinPeriodID == pmt.TranPeriodID)
                {
                    hist.TranPTDCuryAmount = curyAmt;
                    hist.TranPTDAmount     = amt;
                    hist.TranYTDCuryAmount = curyAmt;
                    hist.TranYTDAmount     = amt;
                    hist.TranPTDQty        = baseQty;
                    hist.TranYTDQty        = baseQty;
                }
                else
                {
                    PMHistory tranHist = new PMHistory();
                    tranHist.ProjectID      = ps.ProjectID;
                    tranHist.ProjectTaskID  = ps.TaskID;
                    tranHist.AccountGroupID = ps.AccountGroupID;
                    tranHist.InventoryID    = pmt.InventoryID ?? PM.PMInventorySelectorAttribute.EmptyInventoryID;
                    tranHist.CostCodeID     = pmt.CostCodeID ?? CostCodeAttribute.GetDefaultCostCode();
                    tranHist.PeriodID       = pmt.TranPeriodID;
                    tranHist.BranchID       = pmt.BranchID;
                    list.Add(tranHist);
                    tranHist.TranPTDCuryAmount = curyAmt;
                    tranHist.TranPTDAmount     = amt;
                    tranHist.TranYTDCuryAmount = curyAmt;
                    tranHist.TranYTDAmount     = amt;
                    tranHist.TranPTDQty        = baseQty;
                    tranHist.TranYTDQty        = baseQty;
                }
                #endregion

                forecast                  = new PMForecastHistory();
                forecast.ProjectID        = ps.ProjectID;
                forecast.ProjectTaskID    = ps.ProjectTaskID;
                forecast.AccountGroupID   = ps.AccountGroupID;
                forecast.InventoryID      = ps.InventoryID;
                forecast.CostCodeID       = ps.CostCodeID;
                forecast.PeriodID         = pmt.TranPeriodID;
                forecast.ActualQty        = ps.ActualQty;
                forecast.CuryActualAmount = ps.CuryActualAmount;
                forecast.ActualAmount     = ps.ActualAmount;
            }
            return(new Result(list, ps, ta, forecast));
        }
        public virtual PMBudgetLite SelectProjectBalance(PMAccountGroup ag, PMProject project, int?taskID, int?inventoryID, int?costCodeID, out bool isExisting)
        {
            BudgetKeyTuple key = new BudgetKeyTuple(project.ContractID.Value, taskID.Value, ag.GroupID.Value, inventoryID.GetValueOrDefault(PMInventorySelectorAttribute.EmptyInventoryID), costCodeID.GetValueOrDefault(CostCodeAttribute.GetDefaultCostCode()));

            string budgetLevel = BudgetLevels.Task;
            string updateMode  = CostBudgetUpdateModes.Summary;

            if (ag.Type == GL.AccountType.Income)
            {
                budgetLevel = project.BudgetLevel;
                updateMode  = settings.RevenueBudgetUpdateMode;
            }
            else if (ag.IsExpense == true)
            {
                budgetLevel = project.CostBudgetLevel;
                updateMode  = settings.CostBudgetUpdateMode;
            }

            PMBudgetLite target = SelectExistingBalance(key, budgetLevel, updateMode);

            if (target != null)
            {
                isExisting = true;
            }
            else
            {
                isExisting = false;
                target     = BuildTarget(key, ag, budgetLevel, updateMode);
            }

            return(target);
        }
        protected virtual PMBudgetLite BuildTarget(BudgetKeyTuple key, PMAccountGroup accountGroup, string budgetLevel, string budgetUpdateMode)
        {
            if (accountGroup == null)
            {
                throw new ArgumentNullException(nameof(accountGroup));
            }
            if (accountGroup.GroupID != key.AccountGroupID)
            {
                throw new ArgumentException("AccountGroup doesnot match key.AccountGroupID");
            }

            PMBudgetLite target = new PMBudgetLite();

            target.ProjectID      = key.ProjectID;
            target.ProjectTaskID  = key.ProjectTaskID;
            target.AccountGroupID = key.AccountGroupID;
            target.InventoryID    = PMInventorySelectorAttribute.EmptyInventoryID;
            target.CostCodeID     = CostCodeAttribute.GetDefaultCostCode();
            target.IsProduction   = false;
            target.Type           = accountGroup.IsExpense == true ? GL.AccountType.Expense : accountGroup.Type;

            if (budgetLevel == BudgetLevels.Task)
            {
                //default
            }
            else if (budgetLevel == BudgetLevels.Item)
            {
                target.InventoryID = budgetUpdateMode == CostBudgetUpdateModes.Summary ? PMInventorySelectorAttribute.EmptyInventoryID : key.InventoryID;
                if (target.InventoryID != PMInventorySelectorAttribute.EmptyInventoryID)
                {
                    InventoryItem item = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(graph, target.InventoryID);

                    if (item != null)
                    {
                        target.Description = item.Descr;
                        target.UOM         = item.BaseUnit;
                    }
                }
            }
            else if (budgetLevel == BudgetLevels.CostCode)
            {
                target.CostCodeID = budgetUpdateMode == CostBudgetUpdateModes.Summary ? CostCodeAttribute.GetDefaultCostCode() : key.CostCodeID;
                PMCostCode costCode = PXSelect <PMCostCode, Where <PMCostCode.costCodeID, Equal <Required <PMCostCode.costCodeID> > > > .Select(graph, target.CostCodeID);

                if (costCode != null)
                {
                    target.Description = costCode.Description;
                }
            }
            else if (budgetLevel == BudgetLevels.Detail)
            {
                target.InventoryID = budgetUpdateMode == CostBudgetUpdateModes.Summary ? PMInventorySelectorAttribute.EmptyInventoryID : key.InventoryID;
                target.CostCodeID  = budgetUpdateMode == CostBudgetUpdateModes.Summary ? CostCodeAttribute.GetDefaultCostCode() : key.CostCodeID;
                PMCostCode costCode = PXSelect <PMCostCode, Where <PMCostCode.costCodeID, Equal <Required <PMCostCode.costCodeID> > > > .Select(graph, target.CostCodeID);

                if (costCode != null)
                {
                    target.Description = costCode.Description;
                }
            }
            else
            {
                throw new ArgumentException(string.Format("Unknown budget level = {0}", budgetLevel), nameof(budgetLevel));
            }

            return(target);
        }
        public virtual List <Balance> Run(int?projectID)
        {
            Dictionary <string, Balance> balances = new Dictionary <string, Balance>();

            List <PMTran> expenseTrans   = CreateExpenseTransactions(projectID);
            List <long>   expenseTranIds = new List <long>();

            Debug.Print("Created Expense Transactions:");
            Debug.Indent();
            foreach (PMTran tran in expenseTrans)
            {
                expenseTranIds.Add(tran.TranID.Value);
                Debug.Print("TranID:{0} AccountGroup:{1}, InventoryID={2}, Qty={3}, Amt={4}, Allocated={5}, Released={6}, Billed={7}, Date={8}", tran.TranID, AccountGroupFromID(tran.AccountGroupID), InventoryFromID(tran.InventoryID), tran.Qty, tran.Amount, tran.Allocated, tran.Released, tran.Billed, tran.Date);
            }
            Debug.Unindent();

            if (expenseTrans.Count == 0)
            {
                PXTrace.WriteError(Messages.FailedToEmulateExpenses);
                return(new List <Balance>());
            }

            PMAllocatorEmulator ae = PXGraph.CreateInstance <PMAllocatorEmulator>();

            ae.SourceTransactions = expenseTrans;
            foreach (PMTran tran in expenseTrans)
            {
                ae.Transactions.Insert(tran);
            }

            PXSelectBase <PMTask> selectTasks = new PXSelect <PMTask, Where <PMTask.projectID, Equal <Required <PMTask.projectID> >, And <PMTask.allocationID, IsNotNull> > >(this);

            List <PMTask> tasks = new List <PMTask>();

            foreach (PMTask pmTask in selectTasks.Select(projectID))
            {
                tasks.Add(pmTask);
            }

            ae.Execute(tasks);
            Debug.Print("After Allocation:");
            Debug.Indent();

            foreach (PMTran tran in ae.Transactions.Cache.Inserted)
            {
                tran.Released = true;
                Transactions.Cache.Update(tran);

                if (expenseTranIds.Contains(tran.TranID.Value))
                {
                    continue;
                }

                Debug.Print("TranID:{0} AccountGroup:{1}, InventoryID={2}, Qty={3}, Amt={4}, Allocated={5}, Released={6}, Billed={7}, Date={8}", tran.TranID, AccountGroupFromID(tran.AccountGroupID), InventoryFromID(tran.InventoryID), tran.Qty, tran.Amount, tran.Allocated, tran.Released, tran.Billed, tran.Date);
            }
            Debug.Unindent();

            DateTime billingDate = DateTime.Now.AddDays(1);

            //Get ARTrans for Bill:
            Debug.Print("Bill using the following Billing date={0}", billingDate);

            PMBillEngineEmulator engine = PXGraph.CreateInstance <PMBillEngineEmulator>();

            engine.FieldVerifying.AddHandler <PMTran.projectID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; });        //Project can be completed.
            engine.FieldVerifying.AddHandler <PMTran.taskID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; });           //Task can be completed.
            engine.FieldVerifying.AddHandler <PMTran.inventoryID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; });

            Debug.Print("Transactions passed to BillTask:");
            Debug.Indent();
            foreach (PMTran tran in Transactions.Cache.Cached)
            {
                //if (expenseTranIds.Contains(tran.TranID.Value))
                //	continue;
                engine.Transactions.Insert(tran);
                Debug.Print("TranID:{0} AccountGroup:{1}, InventoryID={2}, Qty={3}, Amt={4}, Allocated={5}, Released={6}, Billed={7}, Date={8}", tran.TranID, AccountGroupFromID(tran.AccountGroupID), InventoryFromID(tran.InventoryID), tran.Qty, tran.Amount, tran.Allocated, tran.Released, tran.Billed, tran.Date);
            }
            Debug.Unindent();
            engine.Bill(projectID, billingDate, null);


            Debug.Print("AR Trans:");
            Debug.Indent();

            foreach (ARTran tran in engine.InvoiceEntry.Transactions.Select())
            {
                if (tran.TaskID == null)
                {
                    continue;
                }

                Debug.Print("InventoryID={0}, Qty={1}, Amt={2}", InventoryFromID(tran.InventoryID), tran.Qty, tran.TranAmt);

                Account acct = PXSelect <Account, Where <Account.accountID, Equal <Required <Account.accountID> > > > .Select(engine.InvoiceEntry, tran.AccountID);

                if (acct.AccountGroupID == null)
                {
                    throw new PXException(Messages.FailedEmulateBilling);
                }

                string key = string.Format("{0}.{1}.{2}", tran.TaskID.Value, acct.AccountGroupID, tran.InventoryID ?? PMInventorySelectorAttribute.EmptyInventoryID);

                if (balances.ContainsKey(key))
                {
                    balances[key].Amount   += tran.TranAmt ?? 0;
                    balances[key].Quantity += tran.Qty ?? 0;
                }
                else
                {
                    Balance b = new Balance();
                    b.TaskID         = tran.TaskID.Value;
                    b.AccountGroupID = acct.AccountGroupID.Value;
                    b.InventoryID    = tran.InventoryID ?? PMInventorySelectorAttribute.EmptyInventoryID;
                    b.CostCodeID     = tran.CostCodeID ?? CostCodeAttribute.GetDefaultCostCode();
                    b.Amount         = tran.TranAmt ?? 0;
                    b.Quantity       = tran.Qty ?? 0;

                    balances.Add(key, b);
                }
            }

            return(new List <Balance>(balances.Values));
        }
        public virtual Result Calculate(PMTran pmt, PMAccountGroup ag, Account acc, int mult)
        {
            PMBudget status = SelectProjectBalance(pmt);

            int?      inventoryID = status != null ? status.InventoryID : PMInventorySelectorAttribute.EmptyInventoryID;
            int?      costCodeID  = status != null ? status.CostCodeID : CostCodeAttribute.GetDefaultCostCode();
            RollupQty rollup      = null;

            if (settings.CostBudgetUpdateMode == CostBudgetUpdateModes.Detailed && ag.IsExpense == true && pmt.InventoryID != settings.EmptyInventoryID)
            {
                if (status == null || status.InventoryID == settings.EmptyInventoryID)
                {
                    rollup      = new RollupQty(pmt.UOM, pmt.Qty);
                    inventoryID = pmt.InventoryID;
                    if (pmt.CostCodeID != null)
                    {
                        costCodeID = pmt.CostCodeID;
                    }
                }
            }

            if (rollup == null)
            {
                rollup = CalculateRollupQty(pmt, status);
            }

            List <PMHistory> list = new List <PMHistory>();

            PMTaskTotal ta = null;
            PMBudget    ps = null;

            if (pmt.TaskID != null && (rollup.Qty != 0 || pmt.Amount != 0))             //TaskID will be null for Contract
            {
                ps                = new PMBudget();
                ps.ProjectID      = pmt.ProjectID;
                ps.ProjectTaskID  = pmt.TaskID;
                ps.AccountGroupID = ag.GroupID;
                if (ag.Type == PMAccountType.OffBalance)
                {
                    ps.Type = ag.IsExpense == true ? GL.AccountType.Expense : ag.Type;
                }
                else
                {
                    ps.Type = ag.Type;
                }
                ps.InventoryID = inventoryID;
                ps.CostCodeID  = costCodeID;
                ps.UOM         = rollup.UOM;
                if (status != null)
                {
                    ps.IsProduction = status.IsProduction;
                }

                decimal amt = mult * pmt.Amount.GetValueOrDefault();

                if (!string.IsNullOrEmpty(ps.UOM))
                {
                    ps.ActualQty = rollup.Qty;                     // commented out otherwise invoice produces -ve Qty. * mult;
                }
                ps.ActualAmount = amt;

                #region PMTask Totals Update

                ta           = new PMTaskTotal();
                ta.ProjectID = pmt.ProjectID;
                ta.TaskID    = pmt.TaskID;

                string accType = null;
                int    multFix = 1;             //flip back the sign if it was changed because of ag.Type<>acc.type
                if (pmt.TranType == BatchModule.PM && acc != null && !string.IsNullOrEmpty(acc.Type))
                {
                    //Only transactions that originated in PM were inverted and require to be fixed.
                    accType = ag.Type;

                    if (acc.Type != ag.Type)
                    {
                        multFix = -1;
                    }
                }
                else
                {
                    accType = ag.Type;
                }

                switch (accType)
                {
                case AccountType.Asset:
                    ta.Asset = amt * multFix;
                    break;

                case AccountType.Liability:
                    ta.Liability = amt * multFix;
                    break;

                case AccountType.Income:
                    ta.Income = amt * multFix;
                    break;

                case AccountType.Expense:
                    ta.Expense = amt * multFix;
                    break;
                }

                #endregion

                #region History
                PMHistory hist = new PMHistory();
                hist.ProjectID      = pmt.ProjectID;
                hist.ProjectTaskID  = pmt.TaskID;
                hist.AccountGroupID = ag.GroupID;
                hist.InventoryID    = pmt.InventoryID ?? PMInventorySelectorAttribute.EmptyInventoryID;
                hist.CostCodeID     = pmt.CostCodeID ?? CostCodeAttribute.GetDefaultCostCode();
                hist.PeriodID       = pmt.FinPeriodID;
                decimal baseQty = 0;
                list.Add(hist);
                if (pmt.InventoryID != null && pmt.InventoryID != PMInventorySelectorAttribute.EmptyInventoryID && pmt.Qty != 0 && !string.IsNullOrEmpty(rollup.UOM))
                {
                    if (PXAccess.FeatureInstalled <FeaturesSet.multipleUnitMeasure>())
                    {
                        baseQty = mult * IN.INUnitAttribute.ConvertToBase(graph.Caches[typeof(PMHistory)], pmt.InventoryID, pmt.UOM, pmt.Qty.Value, PX.Objects.IN.INPrecision.QUANTITY);
                    }
                    else
                    {
                        IN.InventoryItem initem = PXSelectorAttribute.Select <PMTran.inventoryID>(graph.Caches[typeof(PMTran)], pmt) as IN.InventoryItem;
                        if (initem != null)
                        {
                            baseQty = mult * IN.INUnitAttribute.ConvertGlobalUnits(graph, pmt.UOM, initem.BaseUnit, pmt.Qty ?? 0, IN.INPrecision.QUANTITY);
                        }
                    }
                }
                hist.FinPTDAmount = amt;
                hist.FinYTDAmount = amt;
                hist.FinPTDQty    = baseQty;
                hist.FinYTDQty    = baseQty;
                if (pmt.FinPeriodID == pmt.TranPeriodID)
                {
                    hist.TranPTDAmount = amt;
                    hist.TranYTDAmount = amt;
                    hist.TranPTDQty    = baseQty;
                    hist.TranYTDQty    = baseQty;
                }
                else
                {
                    PMHistory tranHist = new PMHistory();
                    tranHist.ProjectID      = pmt.ProjectID;
                    tranHist.ProjectTaskID  = pmt.TaskID;
                    tranHist.AccountGroupID = ag.GroupID;
                    tranHist.InventoryID    = pmt.InventoryID ?? PM.PMInventorySelectorAttribute.EmptyInventoryID;
                    tranHist.CostCodeID     = pmt.CostCodeID ?? CostCodeAttribute.GetDefaultCostCode();
                    tranHist.PeriodID       = pmt.TranPeriodID;
                    list.Add(tranHist);
                    tranHist.TranPTDAmount = amt;
                    tranHist.TranYTDAmount = amt;
                    tranHist.TranPTDQty    = baseQty;
                    tranHist.TranYTDQty    = baseQty;
                }
                #endregion
            }
            return(new Result(list, ps, ta));
        }
        public virtual void RecalculateDraftInvoicesAmount(PMProject project, ProjectBalance pb)
        {
            var selectProforma = new PXSelectJoinGroupBy <PMProformaLine,
                                                          InnerJoin <Account, On <PMProformaLine.accountID, Equal <Account.accountID> > >,
                                                          Where <PMProformaLine.projectID, Equal <Required <PMProformaLine.projectID> >,
                                                                 And <PMProformaLine.released, Equal <False> > >,
                                                          Aggregate <GroupBy <PMProformaLine.projectID,
                                                                              GroupBy <PMProformaLine.taskID,
                                                                                       GroupBy <PMProformaLine.accountID,
                                                                                                GroupBy <PMProformaLine.inventoryID,
                                                                                                         GroupBy <PMProformaLine.costCodeID,
                                                                                                                  Sum <PMProformaLine.lineTotal> > > > > > > >(this);

            var selectInvoice = new PXSelectJoinGroupBy <ARTran,
                                                         InnerJoin <Account, On <ARTran.accountID, Equal <Account.accountID> > >,
                                                         Where <ARTran.projectID, Equal <Required <ARTran.projectID> >,
                                                                And <ARTran.released, Equal <False> > >,
                                                         Aggregate <GroupBy <ARTran.tranType,
                                                                             GroupBy <ARTran.projectID,
                                                                                      GroupBy <ARTran.taskID,
                                                                                               GroupBy <ARTran.accountID,
                                                                                                        GroupBy <ARTran.inventoryID,
                                                                                                                 GroupBy <ARTran.costCodeID,
                                                                                                                          Sum <ARTran.tranAmt> > > > > > > > >(this);


            var selectRevenueBudget = new PXSelect <PMRevenueBudget,
                                                    Where <PMRevenueBudget.projectID, Equal <Required <PMRevenueBudget.projectID> >,
                                                           And <PMRevenueBudget.type, Equal <GL.AccountType.income> > > >(this);
            var revenueBudget = selectRevenueBudget.Select(project.ContractID);

            foreach (PXResult <PMProformaLine, Account> res in selectProforma.Select(project.ContractID))
            {
                PMProformaLine line    = (PMProformaLine)res;
                Account        account = (Account)res;

                int?inventoryID = PMInventorySelectorAttribute.EmptyInventoryID;

                foreach (PMRevenueBudget rev in revenueBudget)
                {
                    foreach (PMRevenueBudget budget in revenueBudget)
                    {
                        if (budget.TaskID == line.TaskID && line.InventoryID == budget.InventoryID)
                        {
                            inventoryID = line.InventoryID;
                        }
                    }
                }

                PMBudgetAccum invoiced = new PMBudgetAccum();
                invoiced.Type           = GL.AccountType.Income;
                invoiced.ProjectID      = line.ProjectID;
                invoiced.ProjectTaskID  = line.TaskID;
                invoiced.AccountGroupID = account.AccountGroupID;
                invoiced.InventoryID    = inventoryID;
                invoiced.CostCodeID     = line.CostCodeID.GetValueOrDefault(CostCodeAttribute.GetDefaultCostCode());

                invoiced = Budget.Insert(invoiced);
                invoiced.InvoicedAmount += line.LineTotal.GetValueOrDefault();

                if (line.IsPrepayment == true)
                {
                    invoiced.PrepaymentInvoiced += line.LineTotal.GetValueOrDefault();
                }
            }

            foreach (PXResult <ARTran, Account> res in selectInvoice.Select(project.ContractID))
            {
                ARTran  line    = (ARTran)res;
                Account account = (Account)res;

                int?inventoryID = PMInventorySelectorAttribute.EmptyInventoryID;

                foreach (PMRevenueBudget rev in revenueBudget)
                {
                    foreach (PMRevenueBudget budget in revenueBudget)
                    {
                        if (budget.TaskID == line.TaskID && line.InventoryID == budget.InventoryID)
                        {
                            inventoryID = line.InventoryID;
                        }
                    }
                }

                PMBudgetAccum invoiced = new PMBudgetAccum();
                invoiced.Type           = GL.AccountType.Income;
                invoiced.ProjectID      = line.ProjectID;
                invoiced.ProjectTaskID  = line.TaskID;
                invoiced.AccountGroupID = account.AccountGroupID;
                invoiced.InventoryID    = inventoryID;
                invoiced.CostCodeID     = line.CostCodeID.GetValueOrDefault(CostCodeAttribute.GetDefaultCostCode());

                invoiced = Budget.Insert(invoiced);
                invoiced.InvoicedAmount += line.TranAmt.GetValueOrDefault() * ARDocType.SignAmount(line.TranType);
            }
        }