OrderBy in PXProjection Select does not work - acumatica

Have any of you experienced this issue in Acumatica?
Adding OrderBy to Select2 in PXProjection attribute has no effect.
I checked the SQL query in Request Profiler and the data is sorted by key fields of the DAC.

Try adding your OrderBy to the PXSelect which is using the DAC made with the PXProjection. Note that by default, the records are ordered by the DAC keys.

In almost every case Acumatica will sort by the key fields first, so if your expectation was to have the data sorted exactly as in your OrderBy<> criteria then this won't work. What you can do instead of override the order directly in the view delegate, like this:
PXView select = new PXView(Base, true, this.myView.View.BqlSelect);
select.OrderByNew<OrderBy<Desc<MyDac.myField1, Desc<MyDac.myField2>>>>();
//<rest logic to select from the view>
This will always replace the order with your custom sort order. If you only want to do it only when the user hasn't altered the sort order in a grid, you can add a condition like that:
if (PXView.SortColumns.Length == this.myView.Cache.Keys.Length)
{
// apply custom default sort order
select.OrderByNew<OrderBy<Desc<MyDac.myField1, Desc<MyDac.myField2>>>>();
}

Related

How to sort the OrderItems in the cart by its category on Broadleaf Commerce?

Broadleaf Commerce site
I need to sort the OrderItems in the cart by its product category. Currently, I am using the comparator to sort the OrderItems.
What is the best or right way to customize the default sort for Cart OrderItems?
I assume that you are currently doing something like this:
List<OrderItem> items = cart.getOrderItems();
Collections.sort(items, comparator);
and I also assume that by "default sort" you mean that you want to change the behavior when you call cart.getOrderItems().
Unfortunately, there is no way to change the behavior of the query that occurs when you call getOrderItems() as this is a JPA-generated query on the OrderItem collection within OrderImpl:
#OneToMany(mappedBy = "order", targetEntity = OrderItemImpl.class, cascade = {CascadeType.ALL})
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region="blOrderElements")
#AdminPresentationCollection(friendlyName="OrderImpl_Order_Items",
tab = TabName.General)
protected List<OrderItem> orderItems = new ArrayList<>();
Because of this you really only have 3 options:
Override the OrderImpl class and change the implementation of the getOrderItems() method. Unless you really needed to extend this (like to add another column to BLC_ORDER) then this isn't a great solution since it will add another table to the database that isn't actually used. See the Broadleaf extending entities tutorial. You can also technically avoid the multi-table inheritance by switching to single-table inheritance which is detailed at the bottom of that doc
Add your own query somewhere in a service method that manually queries for OrderItem for the order with a JPA query
Do what you are currently doing and sort the order items manually after retrieval with your comparator. You might consider adding a Thymeleaf utility method to have it available to you in your templates

Restrict User input for PXSelector and use it only as a lookup

I have a case in my customisation project, were I have a PXSelector that I want it to solely act as a lookup, and would not like the users to input any data via the selector and create new records.
I could not find a way to limit this from the attribute itself, therefore I tried to limit it from the events that the control fires. The idea was that in the FieldUpdating Event I would verify whether the value inserted by the user can be found in the selector's key column, if not I would revert it back to the old value. The problem was that cancelling the event had no effect on the selector and since I did not know what the previous value was, I could not revert it back manually.
It sounds like you are trying to use a filter. You need a PXFilter view which then could be used to display data in a grid for example.
You can search the source for "PXFilter to find good examples. One I found is APVendorBalanceEnq which uses public PXFilter<APHistoryFilter> Filter
PXFilter views are not committed to the database. Typically you would create a new DAC for the filter based on your needs but you can use existing DACs that are bound to tables without the fear of the data making it to the database. With the filter you simply use the field values rather than load records into the view.

GroupBy aggregate with record count in projection DAC

I'm currently working on a processing screen that should be showing a listing of custom orders from my DAC summarized by orderid.
The table itself stores a full listing of the order line items.
For example:
OrderNbr, OrderDate, LineNbr, Desc, InvtId, Qty, ExtPrice, isValidated
The grid of the processing screen should show the following information
OrderNbr, OrderDate, Desc, Count(LineNbr), Sum(ExtPrice)
I've created a projection DAC to group the lines by OrderNbr/OrderDate
[PXProjection(typeof(Select4<CWOrderTable,
Where<CWOrderTable.isValidated,Equal<boolTrue>>,
Aggregate<
GroupBy<CWOrderTable.orderNbr,
GroupBy<CWOrderTable.isValidated,
Sum<CWOrderTable.ExtPrice>>>>>
public partial class CWOrderSummary : IBqlTable
What I'm not able to get is a count of the line items that composes this order. I attempted to add a Count<> aggregate to the above however that doesn't return an actual count, simply the MAX() of the field. I couldn't find a great example of using Count() in a projection DAC.
I also found the article on the asiablog regarding the ScalarCount function and attempted that.
article here: http://asiablog.acumatica.com/2016/05/scalarcount-bql-operator.html
There are no errors using this however the subquery never is executed/passed to SQL and the value is always null.
Anyone have any recommendations or examples on how to get the count of records this way?
This is using Acumatica 6.10.0010. I'm partially wondering if it's a build issue and we need to force the customer to upgrade.
Thanks

How to select only needed fields of objects?

I am using the Pimcore API to fetch objects.
$myObjects = new Object\MyObject\Listing();
$myObjects->load();
$myObjects->getObjects();
Works as expected. Now I want to select only a specific field of my objects, e.g. the name field.
How can I tell Pimcore to select only fields that I want? Is it even possibile through the API or do I need to use custom SQL? If so, how can I do that?
Best regards
The pimcore listing is always returning the complete set of objects matching your listing condition...
If you want a fast and easy way to only select one field of your object, I recommend to use the pimcore db class:
$db = \Pimcore\Db::get();
$fieldsArray = $db->fetchCol("SELECT `YOUR_FIELD` FROM `object_query_CLASS-ID`");
This will return you an array width all 'YOUR_FIELD' values from the object query table of your class.
To get the class ID for your query dynamically your should use:
$classId = \Pimcore\Model\Object\MyObject::classId();
Edit:
To get more than one field column, you need to use 'fetchAll' instead of 'fetchCol':
$fieldsArray = $db->fetchAll("SELECT `YOUR_FIELD`, `YOUR_FIELD_2` FROM `object_query_CLASS-ID`");

Default Sort of tr:table?

Is there a way to sort the initial data displayed on UI using tr:table? I know there are sort properties which can be defined on tr:column and which are used to sort the data present in the table.
But the requirement here is to have the data sorted by default when the page is opened. Is there a way to do that except sorting the table data from back end?
You can't sort a table by default, but you have to do it programmatically. With a little bit of work you can write a reusable PhaseListener which you can control from your JSF page.
Make sure it only handles a single phase (for example PhaseId.RESTORE_VIEW) and use it to set the sort order using setSortCriteria:
List<SortCriterion> sortCriteria = new ArrayList<SortCriterion>(1);
String property = "myProperty";
boolean ascending = true;
sortCriteria.add(new SortCriterion(property, ascending));
myCoreTable.setSortCriteria(sortCriteria);
Now you only have to add two <f:attribute/>s on your table to pass both the property name and the ascending boolean so you can create a reusable listener for all your tables.
In your <tr:document> you can have a <f:attribute/> with a list of table ID's to process.
as far as I know: No!
You can read from here for more information:
"TRINIDAD-1491"

Resources