protected virtual void PMBillingRule_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
        {
            PMBillingRule row = e.Row as PMBillingRule;

            if (row != null)
            {
                PXUIFieldAttribute.SetVisible <PMBillingRule.subMask>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.subMaskBudget>(sender, e.Row, row.Type == PMBillingType.Budget);
                PXUIFieldAttribute.SetVisible <PMBillingRule.branchSourceBudget>(sender, e.Row, ShowBranchOptions() && row.Type == PMBillingType.Budget);
                PXUIFieldAttribute.SetVisible <PMBillingRule.accountID>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.accountGroupID>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.amountFormula>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.qtyFormula>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.rateTypeID>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.noRateOption>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.includeNonBillable>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.includeZeroQty>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.includeZeroQty>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.groupByDate>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.groupByEmployee>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.groupByItem>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.groupByVendor>(sender, e.Row, row.Type == PMBillingType.Transaction);
                PXUIFieldAttribute.SetVisible <PMBillingRule.branchSource>(sender, e.Row, ShowBranchOptions() && row.Type == PMBillingType.Transaction);
            }
        }
        protected virtual void PMBillingRule_RowPersisting(PXCache sender, PXRowPersistingEventArgs e)
        {
            PMBillingRule row = e.Row as PMBillingRule;

            if (row == null)
            {
                return;
            }

            if (row.Type == PMBillingType.Transaction && row.AccountGroupID == null)
            {
                sender.RaiseExceptionHandling <PMBillingRule.accountGroupID>(row, null, new PXSetPropertyException(ErrorMessages.FieldIsEmpty, typeof(PMBillingRule.accountGroupID).Name));
            }

            if (row.SubMaskBudget != null && row.SubMaskBudget.Contains('B') && row.SubID == null)
            {
                sender.RaiseExceptionHandling <PMBillingRule.subID>(row, null, new PXSetPropertyException(ErrorMessages.FieldIsEmpty, typeof(PMBillingRule.subID).Name));
            }

            if (row.SubMask != null && row.SubMask.Contains('B') && row.SubID == null)
            {
                sender.RaiseExceptionHandling <PMBillingRule.subID>(row, null, new PXSetPropertyException(ErrorMessages.FieldIsEmpty, typeof(PMBillingRule.subID).Name));
            }

            if (row.SubMask == null && PXAccess.FeatureInstalled <FeaturesSet.subAccount>())
            {
                sender.RaiseExceptionHandling <PMBillingRule.subMask>(row, null, new PXSetPropertyException(ErrorMessages.FieldIsEmpty, typeof(PMBillingRule.subMask).Name));
            }

            if (row.SubMaskBudget == null && PXAccess.FeatureInstalled <FeaturesSet.subAccount>())
            {
                sender.RaiseExceptionHandling <PMBillingRule.subMaskBudget>(row, null, new PXSetPropertyException(ErrorMessages.FieldIsEmpty, typeof(PMBillingRule.subMaskBudget).Name));
            }
        }
Пример #3
0
 public BillingData(ARTran tran, PMBillingRule rule, PMTran pmTran, string subCD, string note, Guid[] files)
 {
     this.Tran   = tran;
     this.Rule   = rule;
     this.PMTran = pmTran;
     this.SubCD  = subCD;
     this.Note   = note;
     this.Files  = files;
 }
        protected virtual void PMBillingRule_CapsAccountGroupID_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
        {
            PMBillingRule row = e.Row as PMBillingRule;

            if (row != null && row.CapsAccountGroupID == null && (row.LimitAmt == true || row.LimitQty == true))
            {
                PMAccountGroup ag = PXSelect <PMAccountGroup> .Search <PMAccountGroup.groupID>(this, row.AccountGroupID);

                e.NewValue = ag.GroupCD;
            }
        }
        protected virtual void PMBillingRule_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
        {
            PMBillingRule row = e.Row as PMBillingRule;

            if (row != null)
            {
                PXUIFieldAttribute.SetEnabled <PMBillingRule.capsAccountGroupID>(sender, e.Row,
                                                                                 (row.LimitAmt == true || row.LimitQty == true));
                PXUIFieldAttribute.SetEnabled <PMBillingRule.accountID>(sender, e.Row, row.AccountSource != PMAccountSource.None);
                PXUIFieldAttribute.SetEnabled <PMBillingRule.subID>(sender, e.Row, row.AccountSource != PMAccountSource.None);
                PXUIFieldAttribute.SetEnabled <PMBillingRule.subMask>(sender, e.Row, row.AccountSource != PMAccountSource.None);
            }
        }
        protected virtual void PMBillingRule_RowPersisting(PXCache sender, PXRowPersistingEventArgs e)
        {
            PMBillingRule row = e.Row as PMBillingRule;

            if (row != null)
            {
                if (row.CapsAccountGroupID == null && (row.LimitAmt == true || row.LimitQty == true))
                {
                    sender.RaiseExceptionHandling <PMBillingRule.capsAccountGroupID>(row, null,
                                                                                     new PXSetPropertyException(
                                                                                         ErrorMessages.FieldIsEmpty,
                                                                                         typeof(PMBillingRule.capsAccountGroupID).Name));
                }
            }
        }
        protected virtual void PMBillingRule_AccountSource_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
        {
            PMBillingRule row = e.Row as PMBillingRule;

            if (row == null)
            {
                return;
            }

            if (row.AccountSource == PMAccountSource.None)
            {
                row.AccountID = null;
                row.SubID     = null;
                row.SubMask   = null;
            }
        }
Пример #8
0
        protected virtual List <PMTran> ReverseWipTask(PMTask task, PMBillingRule rule, DateTime billingDate)
        {
            List <PMTran> list = new List <PMTran>();

            //usage:
            PXSelectBase <PMTran> select = new PXSelect <PMTran,
                                                         Where <PMTran.projectID, Equal <Required <PMTran.projectID> >,
                                                                And <PMTran.taskID, Equal <Required <PMTran.taskID> >,
                                                                     And <PMTran.accountGroupID, Equal <Required <PMTran.accountGroupID> >,
                                                                          And <PMTran.date, Less <Required <PMTran.date> >,
                                                                               And <PMTran.billed, Equal <False>,
                                                                                    And <PMTran.released, Equal <True>,
                                                                                         And <PMTran.reversed, Equal <False> > > > > > > > >(this);

            DateTime cuttofDate = billingDate;            //all transactions  excluding the current day.
            ContractBillingSchedule schedule = PXSelect <ContractBillingSchedule> .Search <ContractBillingSchedule.contractID>(this, task.ProjectID);

            if (schedule != null && schedule.Type == BillingType.OnDemand)
            {
                cuttofDate = billingDate.AddDays(1);                //all transactions including the current day.
            }
            else
            {
                if (IncludeTodaysTransactions)
                {
                    cuttofDate = billingDate.AddDays(1);
                }
            }

            foreach (PMTran tran in select.Select(task.ProjectID, task.TaskID, rule.WipAccountGroupID, cuttofDate))
            {
                list.AddRange(ReverseTran(tran));

                tran.Billed     = true;
                tran.BilledDate = billingDate;

                Transactions.Update(tran);
            }

            return(list);
        }
        protected virtual void PMBillingRule_Type_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
        {
            PMBillingRule row = e.Row as PMBillingRule;

            if (row == null)
            {
                return;
            }

            if (row.Type == PMBillingType.Budget)
            {
                row.AccountGroupID = null;
                row.AccountSource  = PMAccountSource.AccountGroup;
            }
            else
            {
                row.AccountSource = PMAccountSource.None;
            }

            row.AccountID = null;
            row.SubID     = null;
        }
Пример #10
0
        protected virtual List <BillingData> BillTask(PMTask task, PMBillingRule rule, DateTime billingDate)
        {
            PMProject project = PXSelect <PMProject, Where <PMProject.contractID, Equal <Required <PMProject.contractID> > > > .Select(this, task.ProjectID);

            Customer customer = PXSelect <Customer, Where <Customer.bAccountID, Equal <Required <Customer.bAccountID> > > > .Select(this, project.CustomerID);

            List <BillingData>               list         = new List <BillingData>();
            Dictionary <int, decimal>        availableQty = new Dictionary <int, decimal>();
            Dictionary <int, ContractDetail> billingItems = new Dictionary <int, ContractDetail>();

            //recurent Billing:
            PXSelectBase <ContractDetail> selectBilling = new PXSelect <ContractDetail,
                                                                        Where <ContractDetail.contractID, Equal <Required <ContractDetail.contractID> >,
                                                                               And <ContractDetail.taskID, Equal <Required <ContractDetail.taskID> > > > >(this);

            foreach (ContractDetail billing in selectBilling.Select(task.ProjectID, task.TaskID))
            {
                billingItems.Add(billing.InventoryID.Value, billing);

                if (billing.Included > 0)
                {
                    if (billing.ResetUsage == ResetUsageOption.OnBilling)
                    {
                        availableQty.Add(billing.InventoryID.Value, billing.Included.Value);
                    }
                    else
                    {
                        decimal qtyLeft = billing.Included.Value - billing.LastBilledQty ?? 0;

                        if (qtyLeft > 0)
                        {
                            availableQty.Add(billing.InventoryID.Value, qtyLeft);
                        }
                    }
                }

                bool bill = false;
                if (billing.ResetUsage == ResetUsageOption.OnBilling)
                {
                    bill = true;
                }
                else
                {
                    if (billing.LastBilledDate == null)
                    {
                        bill = true;
                    }
                }

                if (bill)
                {
                    ARTran arTran = new ARTran();
                    arTran.InventoryID    = billing.InventoryID;
                    arTran.TranDesc       = billing.Description;
                    arTran.Qty            = billing.Included;
                    arTran.UOM            = billing.UOM;
                    arTran.ExtPrice       = billing.ItemFee;
                    arTran.TranAmt        = arTran.ExtPrice;
                    arTran.ProjectID      = task.ProjectID;
                    arTran.TaskID         = task.TaskID;
                    arTran.Commissionable = false;                     //todo

                    string subCD = null;
                    #region Set Account and Subaccount
                    if (billing.AccountSource != PMAccountSource.None)
                    {
                        if (rule.AccountSource == PMAccountSource.RecurringBillingItem)
                        {
                            if (billing.AccountID != null)
                            {
                                arTran.AccountID = billing.AccountID;
                            }
                            else
                            {
                                InventoryItem item = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(this, billing.InventoryID);

                                throw new PXException(Messages.BillingRuleAccountIsNotConfiguredForBillingRecurent, item.InventoryCD);
                            }
                        }
                        else if (billing.AccountSource == PMAccountSource.Project)
                        {
                            if (project.DefaultAccountID != null)
                            {
                                arTran.AccountID = project.DefaultAccountID;
                            }
                            else
                            {
                                InventoryItem item = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(this, billing.InventoryID);

                                throw new PXException(Messages.ProjectAccountIsNotConfiguredForBillingRecurent, item.InventoryCD, project.ContractCD);
                            }
                        }
                        else if (billing.AccountSource == PMAccountSource.Task)
                        {
                            if (task.DefaultAccountID != null)
                            {
                                arTran.AccountID = task.DefaultAccountID;
                            }
                            else
                            {
                                InventoryItem item = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(this, billing.InventoryID);

                                throw new PXException(Messages.TaskAccountIsNotConfiguredForBillingRecurent, item.InventoryCD, project.ContractCD, task.TaskCD);
                            }
                        }
                        else if (billing.AccountSource == PMAccountSource.InventoryItem)
                        {
                            InventoryItem item = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(this, billing.InventoryID);

                            if (item != null)
                            {
                                if (item.SalesAcctID != null)
                                {
                                    arTran.AccountID = item.SalesAcctID;
                                }
                                else
                                {
                                    throw new PXException(Messages.InventoryAccountIsNotConfiguredForBillingRecurent, item.InventoryCD);
                                }
                            }
                        }
                        else if (billing.AccountSource == PMAccountSource.Customer && customer != null)
                        {
                            CR.Location customerLoc = PXSelect <CR.Location, Where <CR.Location.bAccountID, Equal <Required <CR.Location.bAccountID> >, And <CR.Location.locationID, Equal <Required <CR.Location.locationID> > > > > .Select(this, customer.BAccountID, customer.DefLocationID);

                            if (customerLoc != null)
                            {
                                if (customerLoc.CSalesAcctID != null)
                                {
                                    arTran.AccountID = customerLoc.CSalesAcctID;
                                }
                                else
                                {
                                    InventoryItem item = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(this, billing.InventoryID);

                                    throw new PXException(Messages.CustomerAccountIsNotConfiguredForBillingRecurent, item.InventoryCD, customer.AcctCD);
                                }
                            }
                        }

                        if (arTran.AccountID == null && !string.IsNullOrEmpty(billing.SubMask))
                        {
                            InventoryItem item = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(this, billing.InventoryID);

                            throw new PXException(Messages.SubAccountCannotBeComposed, item.InventoryCD);
                        }
                        else if (arTran.AccountID != null && !string.IsNullOrEmpty(billing.SubMask))
                        {
                            subCD = PMRecurentBillSubAccountMaskAttribute.MakeSub <PMBillingRule.subMask>(this, billing.SubMask,
                                                                                                          new object[] { billing.SubID, project.DefaultSubID, task.DefaultSubID },
                                                                                                          new Type[] { typeof(PMBillingRule.subID), typeof(PMProject.defaultSubID), typeof(PMTask.defaultSubID) });
                        }
                    }

                    #endregion

                    list.Add(new BillingData(arTran, rule, null, subCD, null, null));

                    billing.LastBilledDate = billingDate;
                    ContractDetail.Update(billing);
                }
            }



            int            mult = 1;
            PMAccountGroup ag   = PXSelect <PMAccountGroup, Where <PMAccountGroup.groupID, Equal <Required <PMAccountGroup.groupID> > > > .Select(this, rule.AccountGroupID);

            if (ag == null)
            {
                throw new PXException(Messages.AccountGroupInBillingRuleNotFound, rule.BillingID, rule.AccountGroupID);
            }
            if (ag.Type == GL.AccountType.Liability || ag.Type == GL.AccountType.Income)
            {
                mult = -1;
            }

            DateTime cuttofDate = billingDate;            //all transactions  excluding the current day.
            ContractBillingSchedule schedule = PXSelect <ContractBillingSchedule> .Search <ContractBillingSchedule.contractID>(this, task.ProjectID);

            if (schedule != null && schedule.Type == BillingType.OnDemand)
            {
                cuttofDate = billingDate.AddDays(1);                //all transactions including the current day.
            }
            else
            {
                if (IncludeTodaysTransactions)
                {
                    cuttofDate = billingDate.AddDays(1);
                }
            }

            List <PMTran> billingBase = SelectBillingBase(task.ProjectID, task.TaskID, rule.AccountGroupID, cuttofDate,
                                                          rule.IncludeNonBillable == true);

            foreach (PMTran tran in billingBase)
            {
                ARTran arTran = new ARTran();
                arTran.BranchID = tran.BranchID;
                if (tran.InventoryID != PMInventorySelectorAttribute.EmptyInventoryID)
                {
                    arTran.InventoryID = tran.InventoryID;
                }
                arTran.TranDesc = tran.Description;
                arTran.UOM      = tran.UOM;
                arTran.Qty      = tran.BillableQty * mult;
                arTran.ExtPrice = tran.Amount * mult;
                if (arTran.Qty != 0)
                {
                    arTran.UnitPrice = arTran.ExtPrice / arTran.Qty;
                }
                else
                {
                    arTran.UnitPrice = 0;
                }
                arTran.TranAmt        = arTran.ExtPrice;
                arTran.ProjectID      = task.ProjectID;
                arTran.TaskID         = task.TaskID;
                arTran.PMTranID       = tran.TranID;
                arTran.Commissionable = false;                 //todo
                arTran.Date           = tran.Date;

                string subCD = null;
                #region Set Account and Subaccount

                int?employeeSubID = null;

                if (tran.ResourceID != null)
                {
                    EP.EPEmployee emp = PXSelect <EP.EPEmployee, Where <EP.EPEmployee.bAccountID, Equal <Required <EP.EPEmployee.bAccountID> > > > .Select(this, tran.ResourceID);

                    if (emp != null)
                    {
                        employeeSubID = emp.SalesSubID;
                    }
                }

                if (rule.AccountSource != PMAccountSource.None)
                {
                    if (rule.AccountSource == PMAccountSource.BillingRule)
                    {
                        if (rule.AccountID != null)
                        {
                            arTran.AccountID = rule.AccountID;
                        }
                        else
                        {
                            throw new PXException(Messages.BillingRuleAccountIsNotConfiguredForBilling, rule.BillingID);
                        }
                    }
                    else if (rule.AccountSource == PMAccountSource.Project)
                    {
                        if (project.DefaultAccountID != null)
                        {
                            arTran.AccountID = project.DefaultAccountID;
                        }
                        else
                        {
                            throw new PXException(Messages.ProjectAccountIsNotConfiguredForBilling, rule.BillingID, project.ContractCD);
                        }
                    }
                    else if (rule.AccountSource == PMAccountSource.Task)
                    {
                        if (task.DefaultAccountID != null)
                        {
                            arTran.AccountID = task.DefaultAccountID;
                        }
                        else
                        {
                            throw new PXException(Messages.TaskAccountIsNotConfiguredForBilling, rule.BillingID, project.ContractCD, task.TaskCD);
                        }
                    }
                    else if (rule.AccountSource == PMAccountSource.InventoryItem)
                    {
                        InventoryItem item = PXSelect <InventoryItem, Where <InventoryItem.inventoryID, Equal <Required <InventoryItem.inventoryID> > > > .Select(this, tran.InventoryID);

                        if (item != null)
                        {
                            if (item.SalesAcctID != null)
                            {
                                arTran.AccountID = item.SalesAcctID;
                            }
                            else
                            {
                                throw new PXException(Messages.InventoryAccountIsNotConfiguredForBilling, rule.BillingID, item.InventoryCD);
                            }
                        }
                    }
                    else if (rule.AccountSource == PMAccountSource.Customer && customer != null)
                    {
                        CR.Location customerLoc = PXSelect <CR.Location, Where <CR.Location.bAccountID, Equal <Required <CR.Location.bAccountID> >, And <CR.Location.locationID, Equal <Required <CR.Location.locationID> > > > > .Select(this, customer.BAccountID, customer.DefLocationID);

                        if (customerLoc != null)
                        {
                            if (customerLoc.CSalesAcctID != null)
                            {
                                arTran.AccountID = customerLoc.CSalesAcctID;
                            }
                            else
                            {
                                throw new PXException(Messages.CustomerAccountIsNotConfiguredForBilling, rule.BillingID, customer.AcctCD);
                            }
                        }
                    }
                    else if (rule.AccountSource == PMAccountSource.Resource)
                    {
                        EP.EPEmployee emp = PXSelect <EP.EPEmployee, Where <EP.EPEmployee.bAccountID, Equal <Required <EP.EPEmployee.bAccountID> > > > .Select(this, tran.ResourceID);

                        if (emp != null)
                        {
                            if (emp.SalesAcctID != null)
                            {
                                arTran.AccountID = emp.SalesAcctID;
                            }
                            else
                            {
                                throw new PXException(Messages.EmployeeAccountIsNotConfiguredForBilling, rule.BillingID, emp.AcctCD);
                            }
                        }
                    }

                    if (arTran.AccountID == null && !string.IsNullOrEmpty(rule.SubMask))
                    {
                        throw new PXException(Messages.SubAccountCannotBeComposed, rule.BillingID);
                    }
                    else if (arTran.AccountID != null && !string.IsNullOrEmpty(rule.SubMask))
                    {
                        subCD = PMBillSubAccountMaskAttribute.MakeSub <PMBillingRule.subMask>(this, rule.SubMask,
                                                                                              new object[] { tran.SubID, rule.SubID, project.DefaultSubID, task.DefaultSubID, employeeSubID },
                                                                                              new Type[] { typeof(PMTran.subID), typeof(PMBillingRule.subID), typeof(PMProject.defaultSubID), typeof(PMTask.defaultSubID), typeof(EP.EPEmployee.salesSubID) });
                    }
                }

                #endregion

                string note  = PXNoteAttribute.GetNote(Transactions.Cache, tran);
                Guid[] files = PXNoteAttribute.GetFileNotes(Transactions.Cache, tran);
                list.Add(new BillingData(arTran, rule, tran, subCD, note, files));

                if (billingItems.ContainsKey(tran.InventoryID.Value))
                {
                    if (availableQty.ContainsKey(tran.InventoryID.Value))
                    {
                        decimal available = availableQty[tran.InventoryID.Value];

                        if (tran.BillableQty <= available)
                        {
                            //Transaction is already payed for as a post payment included. Thus it should be free.
                            arTran.TranDesc = PXMessages.LocalizeNoPrefix(CT.Messages.PrefixIncludedUsage) + " " + tran.Description;
                            availableQty[tran.InventoryID.Value] -= arTran.Qty.Value;                            //decrease available qty
                            arTran.UnitPrice = 0;
                            arTran.ExtPrice  = 0;
                            arTran.TranAmt   = 0;
                        }
                        else
                        {
                            arTran.TranDesc = PXMessages.LocalizeNoPrefix(CT.Messages.PrefixOverused) + " " + tran.Description;
                            arTran.Qty      = arTran.Qty - available;
                            availableQty[tran.InventoryID.Value] = 0;                            //all available qty was used.
                        }
                    }
                }

                tran.Billed     = true;
                tran.BilledDate = billingDate;

                Transactions.Update(tran);
            }

            return(list);
        }
 public override string GetInvoiceKey(string proformaTag, PMBillingRule rule)
 {
     return(base.GetInvoiceKey("P", null));
 }