protected virtual void PMProject_RowInserted(PXCache sender, PXRowInsertedEventArgs e) { PMProject row = e.Row as PMProject; if (row == null) { return; } ContractBillingSchedule schedule = new ContractBillingSchedule { ContractID = row.ContractID }; Billing.Insert(schedule); Billing.Cache.IsDirty = false; }
protected virtual ProjectsList CreateListItem(PXResult item) { PMProject project = PXResult.Unwrap <PMProject>(item); ContractBillingSchedule schedule = PXResult.Unwrap <ContractBillingSchedule>(item); Customer customer = PXResult.Unwrap <Customer>(item); ProjectsList result = new ProjectsList(); result.ProjectID = project.ContractID; result.ProjectCD = project.ContractCD; result.Description = project.Description; result.CustomerID = project.CustomerID; result.LastDate = schedule.LastDate; DateTime?fromDate = null; if (schedule.NextDate != null) { switch (schedule.Type) { case BillingType.Annual: fromDate = schedule.NextDate.Value.AddYears(-1); break; case BillingType.Monthly: fromDate = schedule.NextDate.Value.AddMonths(-1); break; case BillingType.Weekly: fromDate = schedule.NextDate.Value.AddDays(-7); break; case BillingType.Quarterly: fromDate = schedule.NextDate.Value.AddMonths(-3); break; } } result.FromDate = fromDate; result.NextDate = schedule.NextDate; return(result); }
protected ContractProcessing(int? contractID) { if (contractID > 0) { this.graph = PXGraph.CreateInstance<ARInvoiceEntry>(); graph.FieldVerifying.AddHandler<ARInvoice.projectID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; }); this.contract = PXSelect<Contract, Where<Contract.contractID, Equal<Required<Contract.contractID>>>>.Select(graph, contractID); this.insetup = PXSelect<INSetup>.Select(graph); this.template = PXSelect<Contract, Where<Contract.contractID, Equal<Required<Contract.contractID>>>>.Select(graph, contract.TemplateID); this.schedule = PXSelect<ContractBillingSchedule>.Search<ContractBillingSchedule.contractID>(graph, contract.ContractID); if (contract.CustomerID != null) { if (schedule != null && schedule.AccountID != null) { customer = PXSelect<Customer, Where<Customer.bAccountID, Equal<Required<ContractBillingSchedule.accountID>>>>.Select(graph, schedule.AccountID); if (schedule.LocationID != null) { location = PXSelect<Location, Where<Location.bAccountID, Equal<Required<ContractBillingSchedule.accountID>>, And<Location.locationID, Equal<Required<ContractBillingSchedule.locationID>>>>>.Select(graph, customer.BAccountID, schedule.LocationID); } else { location = PXSelect<Location, Where<Location.locationID, Equal<Required<Customer.defLocationID>>>>.Select(graph, customer.DefLocationID); } } else { customer = PXSelect<Customer, Where<Customer.bAccountID, Equal<Required<Customer.bAccountID>>>>.Select(graph, contract.CustomerID); if (contract.LocationID != null) { location = PXSelect<Location, Where<Location.bAccountID, Equal<Required<ContractBillingSchedule.accountID>>, And<Location.locationID, Equal<Required<ContractBillingSchedule.locationID>>>>>.Select(graph, customer.BAccountID, contract.LocationID); } else { location = PXSelect<Location, Where<Location.locationID, Equal<Required<Customer.defLocationID>>>>.Select(graph, customer.DefLocationID); } } } SetupGraph(); } }
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); }
public static DateTime?GetNextBillingDate(PXGraph graph, ContractBillingSchedule schedule, DateTime?date) { switch (schedule.Type) { case BillingType.Annual: return(date.Value.AddYears(1)); case BillingType.Monthly: return(date.Value.AddMonths(1)); case BillingType.Weekly: return(date.Value.AddDays(7)); case BillingType.Quarterly: return(date.Value.AddMonths(3)); case BillingType.OnDemand: return(null); default: throw new ArgumentException("Invalid Schedule type", "schedule"); } }
public virtual bool Bill(int?projectID, DateTime?invoiceDate) { PMProject project = PXSelect <PMProject, Where <PMProject.contractID, Equal <Required <PMProject.contractID> > > > .Select(this, projectID); ContractBillingSchedule schedule = PXSelect <ContractBillingSchedule> .Search <ContractBillingSchedule.contractID>(this, project.ContractID); DateTime billingDate; if (invoiceDate == null) { if (schedule.Type == BillingType.OnDemand) { billingDate = Accessinfo.BusinessDate ?? DateTime.Now; } else { billingDate = schedule.NextDate.Value; } } else { billingDate = invoiceDate.Value; } Customer customer = null; if (project.CustomerID != null) { customer = PXSelect <Customer, Where <Customer.bAccountID, Equal <Required <Customer.bAccountID> > > > .Select(this, project.CustomerID); } if (customer == null) { throw new PXException(Messages.NoCustomer); } List <BillingData> list = new List <BillingData>(); List <PMTran> reversalTrans = new List <PMTran>(); PXSelectBase <PMTask> selectTasks = new PXSelect <PMTask, Where <PMTask.projectID, Equal <Required <PMTask.projectID> >, And <PMTask.billingID, IsNotNull, And <PMTask.isActive, Equal <True> > > > >(this); foreach (PMTask task in selectTasks.Select(project.ContractID)) { if ((task.BillingOption == PMBillingOption.OnTaskCompletion && task.IsCompleted == true) || (task.BillingOption == PMBillingOption.OnProjectCompetion && project.IsCompleted == true) || task.BillingOption == PMBillingOption.OnBilling) { list.AddRange(BillTask(task, billingDate)); reversalTrans.AddRange(ReverseWipTask(task, billingDate)); } } //Regroup by Invoices: Dictionary <string, List <BillingData> > invoices = new Dictionary <string, List <BillingData> >(); string emptyInvoiceDescriptionKey = "!@#$%^&"; foreach (BillingData data in list) { if (string.IsNullOrEmpty(data.Rule.InvoiceDescription)) { if (invoices.ContainsKey(emptyInvoiceDescriptionKey)) { invoices[emptyInvoiceDescriptionKey].Add(data); } else { invoices.Add(emptyInvoiceDescriptionKey, new List <BillingData>(new BillingData[] { data })); } } else { if (invoices.ContainsKey(data.Rule.InvoiceDescription)) { invoices[data.Rule.InvoiceDescription].Add(data); } else { invoices.Add(data.Rule.InvoiceDescription, new List <BillingData>(new BillingData[] { data })); } } //Reverse On Billing: if (data.PMTran != null) { bool reverseOnBilling = false; if (data.PMTran.Reverse == PMReverse.OnBilling) { reverseOnBilling = true; } else if (data.PMTran.Reverse != PMReverse.Never && IsNonGL(data.PMTran)) { reverseOnBilling = true; } if (reverseOnBilling) { reversalTrans.AddRange(ReverseTran(data.PMTran)); } } } //Schedule update: schedule.NextDate = GetNextBillingDate(this, schedule, schedule.NextDate); schedule.LastDate = this.Accessinfo.BusinessDate; BillingSchedule.Update(schedule); //ContractDetail update: PXSelectBase <ContractDetailExt> cis = new PXSelect <ContractDetailExt, Where <ContractDetailExt.contractID, Equal <Required <ContractDetailExt.contractID> >, And <ContractDetailExt.resetUsage, Equal <ResetUsageOption.onBilling> > > >(this); foreach (ContractDetailExt ci in cis.Select(project.ContractID)) { ci.Used = 0; ContractDetail.Update(ci); } List <ARRegister> doclist = new List <ARRegister>(); PMRegister reversalDoc = null; if (invoices.Count > 0) { using (PXTransactionScope ts = new PXTransactionScope()) { ARInvoiceEntry invoiceEntry = PXGraph.CreateInstance <ARInvoiceEntry>(); invoiceEntry.FieldVerifying.AddHandler <ARInvoice.projectID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; }); invoiceEntry.FieldVerifying.AddHandler <ARTran.projectID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; }); invoiceEntry.FieldVerifying.AddHandler <ARTran.taskID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; }); foreach (KeyValuePair <string, List <BillingData> > kv in invoices) { invoiceEntry.Clear(PXClearOption.ClearAll); string description = kv.Key == emptyInvoiceDescriptionKey ? null : kv.Key; string docDesc = description ?? string.Format(PXMessages.LocalizeNoPrefix(CT.Messages.BillingFor), project.ContractCD, project.Description); ARInvoice invoice = (ARInvoice)invoiceEntry.Caches[typeof(ARInvoice)].CreateInstance(); invoice.DocType = GetDocType(kv.Value); int mult = 1; if (invoice.DocType == ARDocType.CreditMemo) { mult = -1; } invoice = (ARInvoice)invoiceEntry.Caches[typeof(ARInvoice)].Insert(invoice); invoiceEntry.Caches[typeof(ARInvoice)].SetValueExt <ARInvoice.customerID>(invoice, customer.AcctCD); invoiceEntry.Caches[typeof(ARInvoice)].SetValue <ARInvoice.customerLocationID>(invoice, project.LocationID); invoiceEntry.Caches[typeof(ARInvoice)].SetValueExt <ARInvoice.docDate>(invoice, billingDate); invoiceEntry.Caches[typeof(ARInvoice)].SetValue <ARInvoice.docDesc>(invoice, docDesc); invoiceEntry.Caches[typeof(ARInvoice)].SetValue <ARInvoice.projectID>(invoice, project.ContractID); CurrencyInfo curyinfo = (CurrencyInfo)invoiceEntry.Caches[typeof(CurrencyInfo)].Current; foreach (BillingData data in kv.Value) { data.Tran.ExtPrice = data.Tran.ExtPrice.GetValueOrDefault() * mult; data.Tran.Qty = data.Tran.Qty.GetValueOrDefault() * mult; data.Tran.TranAmt = data.Tran.TranAmt.GetValueOrDefault() * mult; decimal curyamount; PXDBCurrencyAttribute.CuryConvCury(invoiceEntry.Caches[typeof(CurrencyInfo)], curyinfo, data.Tran.UnitPrice.GetValueOrDefault(), out curyamount); data.Tran.CuryUnitPrice = curyamount; PXDBCurrencyAttribute.CuryConvCury(invoiceEntry.Caches[typeof(CurrencyInfo)], curyinfo, data.Tran.ExtPrice.GetValueOrDefault(), out curyamount); data.Tran.CuryExtPrice = curyamount; data.Tran.CuryTranAmt = data.Tran.CuryExtPrice; data.Tran.FreezeManualDisc = true; data.Tran.CuryInfoID = curyinfo.CuryInfoID; ARTran newTran = (ARTran)invoiceEntry.Caches[typeof(ARTran)].Insert(data.Tran); if (data.Tran.TranAmt > newTran.TranAmt) { newTran.PMDeltaOption = ARTran.pMDeltaOption.CompleteLine; //autocomplete when currency descrepency exists. } if (data.Tran.AccountID != null) { ARTran copy = (ARTran)invoiceEntry.Caches[typeof(ARTran)].CreateCopy(newTran); copy.AccountID = data.Tran.AccountID; copy = (ARTran)invoiceEntry.Caches[typeof(ARTran)].Update(copy); if (data.SubCD != null) { invoiceEntry.Caches[typeof(ARTran)].SetValueExt <ARTran.subID>(copy, data.SubCD); } } if (data.Note != null) { PXNoteAttribute.SetNote(invoiceEntry.Caches[typeof(ARTran)], newTran, data.Note); } if (data.Files != null && data.Files.Length > 0) { PXNoteAttribute.SetFileNotes(invoiceEntry.Caches[typeof(ARTran)], newTran, data.Files); } //item.RefLineNbr = newTran.LineNbr; } ARInvoice oldInvoice = (ARInvoice)invoiceEntry.Caches[typeof(ARInvoice)].CreateCopy(invoice); invoice.CuryOrigDocAmt = invoice.CuryDocBal; invoiceEntry.Caches[typeof(ARInvoice)].RaiseRowUpdated(invoice, oldInvoice); invoiceEntry.Caches[typeof(ARInvoice)].SetValue <ARInvoice.curyOrigDocAmt>(invoice, invoice.CuryDocBal); if (project.AutomaticReleaseAR == true) { invoiceEntry.Caches[typeof(ARInvoice)].SetValueExt <ARInvoice.hold>(invoice, false); } doclist.Add((ARInvoice)invoiceEntry.Caches[typeof(ARInvoice)].Current); invoiceEntry.Save.Press(); } Actions.PressSave(); if (reversalTrans.Count > 0) { RegisterEntry pmEntry = PXGraph.CreateInstance <RegisterEntry>(); pmEntry.FieldVerifying.AddHandler <PMTran.projectID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; }); //Project can be completed. pmEntry.FieldVerifying.AddHandler <PMTran.taskID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; }); //Task can be completed. pmEntry.FieldVerifying.AddHandler <PMTran.inventoryID>((PXCache sender, PXFieldVerifyingEventArgs e) => { e.Cancel = true; }); reversalDoc = (PMRegister)pmEntry.Document.Cache.Insert(); reversalDoc.OrigDocType = PMOrigDocType.AllocationReversal; reversalDoc.Description = "Allocation Reversal on Billing"; pmEntry.Document.Current = reversalDoc; foreach (PMTran tran in reversalTrans) { pmEntry.Transactions.Insert(tran); } pmEntry.Save.Press(); } ts.Complete(); } } else { this.Persist(typeof(ContractBillingSchedule), PXDBOperation.Update); this.Persist(typeof(Contract), PXDBOperation.Update); } if (project.AutomaticReleaseAR == true) { try { ARDocumentRelease.ReleaseDoc(doclist, false); } catch (Exception ex) { throw new PXException(Messages.AutoReleaseARFailed, ex); } if (reversalDoc != null) { try { RegisterRelease.Release(reversalDoc); } catch (Exception ex) { throw new PXException(Messages.AutoReleaseOfReversalFailed, ex); } } } return(doclist.Count > 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); }
protected virtual IEnumerable items() { BillingFilter filter = Filter.Current; if (filter == null) { yield break; } bool found = false; foreach (ProjectsList item in Items.Cache.Inserted) { found = true; yield return(item); } if (found) { yield break; } PXSelectBase <PMProject> select = new PXSelectJoin <PMProject, InnerJoin <ContractBillingSchedule, On <PMProject.contractID, Equal <ContractBillingSchedule.contractID> >, InnerJoin <Customer, On <PMProject.customerID, Equal <Customer.bAccountID> > > >, Where2 <Where <ContractBillingSchedule.nextDate, LessEqual <Current <BillingFilter.invoiceDate> >, Or <ContractBillingSchedule.type, Equal <BillingType.BillingOnDemand> > >, And <PMProject.baseType, Equal <PMProject.ProjectBaseType>, And <PMProject.nonProject, Equal <False>, And <PMProject.isTemplate, Equal <False> > > > > >(this); if (filter.StatementCycleId != null) { select.WhereAnd <Where <Customer.statementCycleId, Equal <Current <BillingFilter.statementCycleId> > > >(); } if (filter.CustomerClassID != null) { select.WhereAnd <Where <Customer.customerClassID, Equal <Current <BillingFilter.customerClassID> > > >(); } if (filter.CustomerID != null) { select.WhereAnd <Where <Customer.bAccountID, Equal <Current <BillingFilter.customerID> > > >(); } if (filter.TemplateID != null) { select.WhereAnd <Where <PMProject.templateID, Equal <Current <BillingFilter.templateID> > > >(); } foreach (PXResult <PMProject, ContractBillingSchedule, Customer> item in select.Select()) { PMProject project = (PMProject)item; ContractBillingSchedule schedule = (ContractBillingSchedule)item; Customer customer = (Customer)item; ProjectsList result = new ProjectsList(); result.ProjectID = project.ContractID; result.ProjectCD = project.ContractCD; result.Description = project.Description; result.CustomerID = project.CustomerID; result.CustomerName = customer.AcctName; result.LastDate = schedule.LastDate; DateTime?fromDate = null; if (schedule.NextDate != null) { switch (schedule.Type) { case BillingType.Annual: fromDate = schedule.NextDate.Value.AddYears(-1); break; case BillingType.Monthly: fromDate = schedule.NextDate.Value.AddMonths(-1); break; case BillingType.Weekly: fromDate = schedule.NextDate.Value.AddDays(-7); break; case BillingType.Quarterly: fromDate = schedule.NextDate.Value.AddMonths(-3); break; } } result.FromDate = fromDate; result.NextDate = schedule.NextDate; yield return(Items.Insert(result)); } Items.Cache.IsDirty = false; }
protected virtual IEnumerable items() { BillingFilter filter = Filter.Current; if (filter == null) { yield break; } bool found = false; foreach (ProjectsList item in Items.Cache.Inserted) { found = true; yield return(item); } if (found) { yield break; } PXSelectBase <PMProject> selectUnbilled = new PXSelectJoinGroupBy <PMProject, InnerJoin <PMUnbilledDailySummary, On <PMUnbilledDailySummary.projectID, Equal <PMProject.contractID> >, InnerJoin <ContractBillingSchedule, On <PMProject.contractID, Equal <ContractBillingSchedule.contractID> >, InnerJoin <Customer, On <PMProject.customerID, Equal <Customer.bAccountID> >, InnerJoin <PMTask, On <PMTask.projectID, Equal <PMUnbilledDailySummary.projectID>, And <PMTask.isActive, Equal <True>, And <PMTask.taskID, Equal <PMUnbilledDailySummary.taskID>, And <Where <PMTask.billingOption, Equal <PMBillingOption.onBilling>, Or2 <Where <PMTask.billingOption, Equal <PMBillingOption.onTaskCompletion>, And <PMTask.isCompleted, Equal <True> > >, Or <Where <PMTask.billingOption, Equal <PMBillingOption.onProjectCompetion>, And <PMProject.isCompleted, Equal <True> > > > > > > > > >, InnerJoin <PMBillingRule, On <PMBillingRule.billingID, Equal <PMTask.billingID>, And <PMBillingRule.accountGroupID, Equal <PMUnbilledDailySummary.accountGroupID> > > > > > > >, Where2 <Where <ContractBillingSchedule.nextDate, LessEqual <Current <BillingFilter.invoiceDate> >, Or <ContractBillingSchedule.type, Equal <BillingType.BillingOnDemand> > >, And2 <Where <PMBillingRule.includeNonBillable, Equal <False>, And <PMUnbilledDailySummary.billable, Greater <int0>, Or <Where <PMBillingRule.includeNonBillable, Equal <True>, And <Where <PMUnbilledDailySummary.nonBillable, Greater <int0>, Or <PMUnbilledDailySummary.billable, Greater <int0> > > > > > > >, And2 <Where <PMUnbilledDailySummary.date, LessEqual <Current <BillingFilter.invoiceDate> > >, And <Match <Current <AccessInfo.userName> > > > > >, Aggregate <GroupBy <PMProject.contractID> > >(this); if (Setup.Current.CutoffDate == PMCutOffDate.Excluded) { selectUnbilled = new PXSelectJoinGroupBy <PMProject, InnerJoin <PMUnbilledDailySummary, On <PMUnbilledDailySummary.projectID, Equal <PMProject.contractID> >, InnerJoin <ContractBillingSchedule, On <PMProject.contractID, Equal <ContractBillingSchedule.contractID> >, InnerJoin <Customer, On <PMProject.customerID, Equal <Customer.bAccountID> >, InnerJoin <PMTask, On <PMTask.projectID, Equal <PMUnbilledDailySummary.projectID>, And <PMTask.isActive, Equal <True>, And <PMTask.taskID, Equal <PMUnbilledDailySummary.taskID>, And <Where <PMTask.billingOption, Equal <PMBillingOption.onBilling>, Or2 <Where <PMTask.billingOption, Equal <PMBillingOption.onTaskCompletion>, And <PMTask.isCompleted, Equal <True> > >, Or <Where <PMTask.billingOption, Equal <PMBillingOption.onProjectCompetion>, And <PMProject.isCompleted, Equal <True> > > > > > > > > >, InnerJoin <PMBillingRule, On <PMBillingRule.billingID, Equal <PMTask.billingID>, And <PMBillingRule.accountGroupID, Equal <PMUnbilledDailySummary.accountGroupID> > > > > > > >, Where2 <Where <ContractBillingSchedule.nextDate, LessEqual <Current <BillingFilter.invoiceDate> >, Or <ContractBillingSchedule.type, Equal <BillingType.BillingOnDemand> > >, And2 <Where <PMBillingRule.includeNonBillable, Equal <False>, And <PMUnbilledDailySummary.billable, Greater <int0>, Or <Where <PMBillingRule.includeNonBillable, Equal <True>, And <Where <PMUnbilledDailySummary.nonBillable, Greater <int0>, Or <PMUnbilledDailySummary.billable, Greater <int0> > > > > > > >, And2 <Where <PMUnbilledDailySummary.date, Less <Current <BillingFilter.invoiceDate> > >, And <Match <Current <AccessInfo.userName> > > > > >, Aggregate <GroupBy <PMProject.contractID> > >(this); } PXSelectBase <PMProject> selectRecurring = new PXSelectJoinGroupBy <PMProject, InnerJoin <ContractBillingSchedule, On <PMProject.contractID, Equal <ContractBillingSchedule.contractID> >, InnerJoin <Customer, On <PMProject.customerID, Equal <Customer.bAccountID> >, InnerJoin <PMTask, On <PMTask.projectID, Equal <PMProject.contractID> >, InnerJoin <PMBillingRule, On <PMBillingRule.billingID, Equal <PMTask.billingID> >, InnerJoin <PMRecurringItem, On <PMTask.projectID, Equal <PMRecurringItem.projectID>, And <PMTask.taskID, Equal <PMRecurringItem.taskID>, And <PMTask.isCompleted, Equal <False> > > > > > > > >, Where2 <Where <ContractBillingSchedule.nextDate, LessEqual <Current <BillingFilter.invoiceDate> >, Or <ContractBillingSchedule.type, Equal <BillingType.BillingOnDemand> > >, And <Match <Current <AccessInfo.userName> > > >, Aggregate <GroupBy <PMProject.contractID> > >(this); PXSelectBase <PMProject> selectProgressive = new PXSelectJoinGroupBy <PMProject, InnerJoin <ContractBillingSchedule, On <PMProject.contractID, Equal <ContractBillingSchedule.contractID> >, InnerJoin <Customer, On <PMProject.customerID, Equal <Customer.bAccountID> >, InnerJoin <PMTask, On <PMTask.projectID, Equal <PMProject.contractID> >, InnerJoin <PMBillingRule, On <PMBillingRule.billingID, Equal <PMTask.billingID> >, InnerJoin <PMBudget, On <PMTask.projectID, Equal <PMBudget.projectID>, And <PMTask.taskID, Equal <PMBudget.projectTaskID>, And <PMBudget.type, Equal <GL.AccountType.income>, And <PMBudget.amountToInvoice, NotEqual <decimal0> > > > > > > > > >, Where <Match <Current <AccessInfo.userName> > >, Aggregate <GroupBy <PMProject.contractID> > >(this); if (filter.StatementCycleId != null) { selectUnbilled.WhereAnd <Where <Customer.statementCycleId, Equal <Current <BillingFilter.statementCycleId> > > >(); selectRecurring.WhereAnd <Where <Customer.statementCycleId, Equal <Current <BillingFilter.statementCycleId> > > >(); selectProgressive.WhereAnd <Where <Customer.statementCycleId, Equal <Current <BillingFilter.statementCycleId> > > >(); } if (filter.CustomerClassID != null) { selectUnbilled.WhereAnd <Where <Customer.customerClassID, Equal <Current <BillingFilter.customerClassID> > > >(); selectRecurring.WhereAnd <Where <Customer.customerClassID, Equal <Current <BillingFilter.customerClassID> > > >(); selectProgressive.WhereAnd <Where <Customer.customerClassID, Equal <Current <BillingFilter.customerClassID> > > >(); } if (filter.CustomerID != null) { selectUnbilled.WhereAnd <Where <Customer.bAccountID, Equal <Current <BillingFilter.customerID> > > >(); selectRecurring.WhereAnd <Where <Customer.bAccountID, Equal <Current <BillingFilter.customerID> > > >(); selectProgressive.WhereAnd <Where <Customer.bAccountID, Equal <Current <BillingFilter.customerID> > > >(); } if (filter.TemplateID != null) { selectUnbilled.WhereAnd <Where <PMProject.templateID, Equal <Current <BillingFilter.templateID> > > >(); selectRecurring.WhereAnd <Where <PMProject.templateID, Equal <Current <BillingFilter.templateID> > > >(); selectProgressive.WhereAnd <Where <PMProject.templateID, Equal <Current <BillingFilter.templateID> > > >(); } foreach (PXResult item in selectUnbilled.Select().Union(selectRecurring.Select()).Union(selectProgressive.Select())) { PMProject project = PXResult.Unwrap <PMProject>(item); ContractBillingSchedule schedule = PXResult.Unwrap <ContractBillingSchedule>(item); Customer customer = PXResult.Unwrap <Customer>(item); ProjectsList result = new ProjectsList(); result.ProjectID = project.ContractID; result.ProjectCD = project.ContractCD; result.Description = project.Description; result.CustomerID = project.CustomerID; result.CustomerName = customer.AcctName; result.LastDate = schedule.LastDate; DateTime?fromDate = null; if (schedule.NextDate != null) { switch (schedule.Type) { case BillingType.Annual: fromDate = schedule.NextDate.Value.AddYears(-1); break; case BillingType.Monthly: fromDate = schedule.NextDate.Value.AddMonths(-1); break; case BillingType.Weekly: fromDate = schedule.NextDate.Value.AddDays(-7); break; case BillingType.Quarterly: fromDate = schedule.NextDate.Value.AddMonths(-3); break; } } result.FromDate = fromDate; result.NextDate = schedule.NextDate; if (Items.Locate(result) == null) { yield return(Items.Insert(result)); } } Items.Cache.IsDirty = false; }