Hello
I am new here and currently looking for feedback on my approach:
Scenario: When a user pays the invoice.
Fig a: Invoice Screen:

Ask: On the Revenue Budget tab under the project, , I need to display the following through a user-defined field.

- Display “Total Units Paid” : reflecting the quantity for which invoice payment has been received from the customer.
- Display “Total Amount Paid” : representing the corresponding total value.
- Display “Difference in Units” ( Budgeted – Paid) : showing the variance between total billed units and total paid units.
I would appreciate if someone could provide feedback on my approach as I am bit lost.
DAC:using PX.Data;
using PX.Objects.AR;
namespace PX.Objects.PM
{
//Total Units Paid#region UsrUnitsPaid
[PXString(50)]
[PXUIField(DisplayName = "Units Paid")]
public string UsrUnitsPaid{ get; set; }
public abstract class usrUnitsPaid: PX.Data.BQL.BqlString.Field<usrUnitsPaid> { }
#endregion
//Total Amount Paid#region UsrAmtPaid
[PXString(50)]
[PXUIField(DisplayName = "Amount Paid")]
public string UsrAmtPaid{ get; set; }
public abstract class usrAmtPaid: PX.Data.BQL.BqlString.Field<usrAmtPaid> { }
#endregion
//Difference in Units#region UsrPendingUnits
[PXString(50)]
[PXUIField(DisplayName = "Out Standing Units")]
public string UsrPendingUnits{ get; set; }
public abstract class usrPendingUnits: PX.Data.BQL.BqlString.Field<usrPendingUnits> { }
#endregion
}
Observation: I see invoice method in exisiitng Invoice in base class code
public virtual IEnumerable invoices()
{
var manualInvoiceSelect = new PXSelectReadonly2<ARInvoice,
LeftJoin<PMBillingRecord, On<ARInvoice.docType, Equal<PMBillingRecord.aRDocType>, And<ARInvoice.refNbr, Equal<PMBillingRecord.aRRefNbr>>>,
LeftJoin<PMProforma, On<ARInvoice.docType, Equal<PMProforma.aRInvoiceDocType>, And<ARInvoice.refNbr, Equal<PMProforma.aRInvoiceRefNbr>>>>>,
Where<PMBillingRecord.recordID, IsNull, And<ARInvoice.projectID, Equal<Current<PMProject.contractID>>>>>(this);var manualResult = manualInvoiceSelect.Select();
if (manualResult.Count == 0)
{
var view = new PXView(this, false, Invoices.View.BqlSelect);
var startRow = PXView.StartRow;
int totalRows = 0;var list = view.Select(PXView.Currents, PXView.Parameters, PXView.Searches, PXView.SortColumns, PXView.Descendings, PXView.Filters,
ref startRow, PXView.MaximumRows, ref totalRows);PXView.StartRow = 0;
return list;
}
else
{
HashSet<string> added = new HashSet<string>();var autoInvoicesSelect = new PXSelectReadonly2<PMBillingRecord,
LeftJoin<PMProforma, On<PMProforma.refNbr, Equal<PMBillingRecord.proformaRefNbr>, And<PMProforma.corrected, Equal<False>>>,
LeftJoin<ARInvoice, On<ARInvoice.docType, Equal<PMBillingRecord.aRDocType>, And<ARInvoice.refNbr, Equal<PMBillingRecord.aRRefNbr>>>>>,
Where<PMBillingRecord.projectID, Equal<Current<PMProject.contractID>>>>(this);PXResultset<PMBillingRecord> rs = autoInvoicesSelect.Select();
List<PXResult<PMBillingRecord, PMProforma, ARInvoice>> list = new List<PXResult<PMBillingRecord, PMProforma, ARInvoice>>(rs.Count + manualResult.Count);
foreach (PXResult<PMBillingRecord, PMProforma, ARInvoice> record in rs)
{
ARInvoice invoice = record;
if (!string.IsNullOrEmpty(invoice.RefNbr))
{
added.Add(string.Format("{0}.{1}", invoice.DocType, invoice.RefNbr));
}list.Add(record);
}int cx = -1;
foreach (PXResult<ARInvoice, PMBillingRecord, PMProforma> record in manualResult)
{
var ar = (ARInvoice)record;
var br = (PMBillingRecord)record;
var proforma = (PMProforma)record;
var hasProforma = !string.IsNullOrEmpty(proforma?.RefNbr)
&& br.ARDocType == ar.DocType
&& br.ARRefNbr == ar.RefNbr
&& proforma?.Corrected != true;if (added.Contains(string.Format("{0}.{1}", ar.DocType, ar.RefNbr)))
continue;if (string.IsNullOrEmpty(br.ARDocType))
{
br.ARDocType = ar.DocType;
br.ARRefNbr = ar.RefNbr;
br.RecordID = cx--;
br.BillingTag = "P";
br.ProjectID = ar.ProjectID;
}if (hasProforma)
{
br.ProformaRefNbr = proforma.RefNbr;
}list.Add(new PXResult<PMBillingRecord, PMProforma, ARInvoice>(
br,
hasProforma ? proforma : new PMProforma(),
ar));
}var order = 0;
var isDirty = Invoices.Cache.IsDirty;
foreach (var item in list)
{
var record = (PMBillingRecord)item;
record.SortOrder = ++order;Invoices.Cache.SetStatus(record, PXEntryStatus.Held);
}
Invoices.Cache.IsDirty = isDirty;
return list;
}
}
Question :
I want to know if we can use, the above base method and find a way to query the Invoice.
Graph Extension:
namespace PX.Objects.PM
{
public class ProjectEntryExtension : PXGraphExtension<ProjectEntry>
{public delegate IEnumerable InvoicesDelegate();
[PXOverride]
public virtual IEnumerable invoices(InvoicesDelegate baseMethod)
{
var invoiceList = baseMethod();
foreach (PXResult<ARInvoice> record in invoiceList)
{
//assign the values to custom DAC}
}
}
Looking for feedback on the correct approach