Joining 1:N related table in form without row duplication using Computed fields in views
Case
A customer wanted to display and filter Customer reference and Customer requisition fields from sales order on Project invoice journal screen. As there is no direct link to do this and the indirect link is a 1:N or even N:N in certain cases this gets problematic when displaying the journals. Resulting in duplicate journal entries in the journal overview. As the customer only have one sales order pr. project invoice and we are selecting the first only (Top 1) this will not be an issue.
As joining and display methods do not provide filter and sort options we need to generate the data on the server using computed fields.
Explanation
As display methods do not provide filter and sort options and joining 1:N table relations will duplicate the journals in the list, we need to generate the data on server using computed fields.
To do this we need a View with Proposal ID, join the view to the ProjInvoiceJour table on Proposal ID and add the view as a datasource to the form ProjProposalJournal.
1. Create the view
- Crate view (in example I called it ProjInvoiceJourSalesView_Postfix)
- Add table ProjInvoiceJour as datasource
- Drag ProposalId from datasource fields to View fields
- Add three string computed fields to the fields node of your view
- Save your view
Get Proposal ID from main datasource
public static server str getProposalId(){str projProposalIdLocal;projProposalIdLocal = SysComputedColumn::returnField( viewstr(ProjInvoiceJourSalesView_Postfix), identifierStr(ProjInvoiceJour), fieldstr(ProjInvoiceJour,ProposalID));return projProposalIdLocal;}
Get Sales ID
public static server Str getSalesId(){str ret;ret = strFmt(@"select top 1 ProjProposalItem.SalesIdfrom ProjProposalItemwhere ProjProposalItem.ProposalId = %1and ProjProposalItem.SalesId <> ''order by ProjProposalItem.SALESID asc", ProjInvoiceJourSalesView_Postfix::getProposalId());return ret;}
Get customer reference
public static server str getCustomerRef(){str ret;ret = strFmt(@"select Top 1 SalesTable.CUSTOMERREFfrom ProjProposalItemjoin SalesTableon SalesTable.SalesID = ProjProposalItem.SALESIDand ProjProposalItem.DATAAREAID = SALESTABLE.DATAAREAIDwhere ProjProposalItem.ProposalId = %1and ProjProposalItem.SalesId <> ''order by SalesTable.SALESID asc", ProjInvoiceJourSalesView_Postfix::getProposalId());return ret;}
Get Customer requisition
public static server str getPrchOrderFormNum(){str ret;ret = strFmt(@"select Top 1 SalesTable.PURCHORDERFORMNUMfrom ProjProposalItemjoin SalesTableon SalesTable.SalesID = ProjProposalItem.SALESIDand ProjProposalItem.DATAAREAID = SALESTABLE.DATAAREAIDwhere ProjProposalItem.ProposalId = %1and ProjProposalItem.SalesId <> ''order by SalesTable.SALESID asc", ProjInvoiceJourSalesView_PostFix::getProposalId());return ret;}
- Note that there is no data area Id range and that the Proposal ID is not enclosed in single quotes, this I found that did not work when implemented. The computed fields are strange like this. Did compile and synchronize but did not give any data.
- The syntax in the strings are MSSQL and not X++.
- Extra important, if you get lots of synchronization issues when compiling, your MSSQL scripts in your computed methods are probably not compiling. You can try simple queries to root out your culprit eg. ret = "select 123" will return the value 123 in every instance.
4. Reference methods in computed fields in view
- Select your Extended data type, in this example Sales ID
- For each computed field in your view select corresponding method in the parameter View Method, here getSalesID is selected
5. Link view to table
- Create or find the extension for your ProjInvoiceJour table
- Add relation to your view on the field Proposal ID
6. Add the view and fields to the form
- Create or locate extension of Form ProjInvoiceJournalV2
- Add your view as a datasource outer joining the ProjInvoiceJour datasource
- Drag your computed fields from the view
Comments
Post a Comment