FlexibleSearch using enum in WHERE clause - sap-commerce-cloud

I am working with Hybris and trying to query all the products that have an approval status of APPROVED within Java code. It should look like below, but I cannot get it to work in either HAC, or in Java code.
What is the correct way to do it?
SELECT {p:pk} FROM {Product as p join EnumerationValue as enum on enum.pk = p.approvalStatus } WHERE {enum:code[en]} = 'APPROVED'
Thank you everyone, here is the final answer that works, see comments in other replies for some more questions I have and hopefully some wonderfully wise replies:
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("SELECT {p:").append(ProductModel.PK).append("} ");
stringBuilder.append("FROM {").append(ProductModel._TYPECODE).append(" as p join ")
.append(ArticleApprovalStatus._TYPECODE).append(" as enum on {enum.pk} = {p.").append(ProductModel.APPROVALSTATUS).append("} join ")
.append(CatalogVersionModel._TYPECODE).append(" as cv on {cv.pk} = {p.").append(ProductModel.CATALOGVERSION).append("} } ");
stringBuilder.append("WHERE ( {enum:code} = ?approvalStatus1 or {enum:code} = ?approvalStatus2} and {cv:")
.append(CatalogVersionModel.VERSION)
.append("} = ?version");
final String unapprovedString = ArticleApprovalStatus.UNAPPROVED.toString().toLowerCase();
params.put("approvalStatus1", unapprovedString);
params.put("approvalStatus2", ArticleApprovalStatus.UNAPPROVED.toString().toLowerCase());

You need to use the type of the enum. Also, the enum code is case-sensitive; it depends on what is defined in the items.xml.
SELECT * FROM {Product
JOIN ArticleApprovalStatus ON {Product.approvalStatus} = {ArticleApprovalStatus.pk}}
WHERE {ArticleApprovalStatus.code} = 'approved'

Try to wrap the attributes with {} like this:
SELECT {p:pk} FROM {Product as p join EnumerationValue as enum on {enum.pk} = {p.approvalStatus} } WHERE {enum:code[en]} = 'APPROVED'

Related

How to get first String based on whitespace out of a full String using java8?

Let's Example I have String s = "Rahul Kumar" I need to have Rahul as a output using java8
Actual Requirement, I do have a list of Trip Object, I want to set driverName property as only first name to each Trip Object and return that list?
System.out.println( someStringValue.subSequence(0, someStringValue.indexOf(' ')));
I'm getting trouble to incorporate this code into the listOfTrip. If I'm doing like this,
List<CharSequence> list = listOfTrips.stream().map(e -> e.getDriverName().subSequence(0, someStringValue.indexOf(' '))).collect(Collectors.toList()); System.out.println(list);
Here, With this, The return type is wrong and it is not fetching only first name out of full name.
Below will give you the proper result:
List<CharSequence> list2 = listOfTrips.stream()
.map(m->m.getDriverName().substring(0,m.getDriverName().indexOf(' ')))
.collect(Collectors.toList());
Please try this also once:
String s = "Rahul Kumar";
Optional<String> beforeWhiteSpace = Pattern.compile(" ").splitAsStream(s).collect(Collectors.toList()).stream().findFirst();

Hybris Impex import based on PKs obtained from FlexQuery

What I want to achieve:
I want to set the value of two attributes, a1 and a2, to null for any product where a third attribute, a3, has a specific enum value.
What I have so far:
I have a flexquery which fetches a list of PKs for products which fulfill the requirement for a3. I now need to set the attributes of the products with those specific keys. The query is as follows:
SELECT {p.pk} FROM {Product AS p JOIN ProductOrigin AS o ON {o.pk} = {p.origin}} WHERE {o.code} = 'MARKETPLACE'
What I need help with:
I do not know how to combine the results of the flexquery with a typical impex operation. What I ideally want is to be able to simply pass the list of PKs to an INSERT_UPDATE as in:
INSERT_UPDATE Product; pk ; a1 ; a2 ;
queryResult; null; null;
I do not know if this is possible however. Even better would be if there is an even easier way to do this that I have not thought of.
Hi Erik you can achieve this even without using the Impex header and use groovy, steps are below.
Create groovy
#%impex.enableCodeExecution(true);
"#%groovy%
def queryCreditCardsToRemove = ''' SELECT {p.pk} FROM {Product AS p JOIN ProductOrigin AS o ON {o.pk} = {p.origin}} WHERE {o.code} = 'MARKETPLACE''''
def products = (Collection<ProductModel>)flexibleSearchService.search(queryCreditCardsToRemove).result
products.stream()
.each{
modelService
}
modelService.removeAll(cardsToRemove)
";
Save the file as impex
3.# Disable legacy scripting (makes groovy work at impex)
impex.legacy.scripting=false---> either you can change dynamically via hac-->configuration or add in local.properties
here is one beanshell script, execute it from hac -> console -> scripting languages!
In the below script, you need to put query that will give you result which is expected to you and on that result script will do further operations of saving null values to attributes!
import de.hybris.platform.servicelayer.search.FlexibleSearchService
import de.hybris.platform.servicelayer.search.SearchResult;
import de.hybris.platform.core.model.product.ProductModel
import de.hybris.platform.variants.model.VariantProductModel;
final Map<String, Object> params = new HashMap<String, Object>();
String query = "-------------- query to check condition of third (a3) attribute
with specific enum value ----------------------"
params = -----------if any need to be passed in query ------------------;
FlexibleSearchService fss = spring.getBean("flexibleSearchService")
final SearchResult<ProductModel> searchResult = fss.search(query, params);
for (final ProductModel product : searchResult.getResult()) {
// set attributes a1 and a2 to null
// save product model using modelService
}

What is wrong in this LINQ Query, getting compile error

I have a list AllIDs:
List<IAddress> AllIDs = new List<IAddress>();
I want to do substring operation on a member field AddressId based on a character "_".
I am using below LINQ query but getting compilation error:
AllIDs= AllIDs.Where(s => s.AddressId.Length >= s.AddressId.IndexOf("_"))
.Select(s => s.AddressId.Substring(s.AddressId.IndexOf("_")))
.ToList();
Error:
Cannot implicitly convert type 'System.Collections.Generic.List<string>' to 'System.Collections.Generic.List<MyCompany.Common.Users.IAddress>'
AllIDs is a list of IAddress but you are selecting a string. The compiler is complaining it cannot convert a List<string> to a List<IAddress>. Did you mean the following instead?
var substrings = AllIDs.Where(...).Select(...).ToList();
If you want to put them back into Address objects (assuming you have an Address class in addition to your IAddress interface), you can do something like this (assuming the constructor for Address is in place):
AllIDs = AllIDs.Where(...).Select(new Address(s.AddressID.Substring(s.AddressID.IndexOf("_")))).ToList();
You should also look at using query syntax for LINQ instead of method syntax, it can clean up and improve the readability of a lot of queries like this. Your original (unmodified) query is roughly equivalent to this:
var substrings = from a in AllIDs
let id = a.AddressId
let idx = id.IndexOf("_")
where id.Length >= idx
select id.Substring(idx);
Though this is really just a style thing, and this compiles to the same thing as the original. One slight difference is that you only have to call String.IndexOf() one per entry, instead of twice per entry. let is your friend.
Maybe this?
var boundable =
from s id in AllIDs
where s.AddressId.Length >= s.AddressId.IndexOf("_")
select new { AddressId = s.AddressId.Substring(s.AddressId.IndexOf("_")) };
boundable = boundable.ToList();

Subsonic 3 - Sequence contains no matching element

I need help creating a LINQ SQL with subsonic. First the basics, this works fine:
var query = (from o in bd.concelhos
orderby o.descricao
select o);
var results = query.ToList<concelhos>();
However, I want to filter out some columns and I have created the following code:
var query = (from o in bd.concelhos
orderby o.descricao
select new FilteredConcelhos { id = o.idDistrito + "/" + o.idConcelho, descricao = o.descricao });
var results = query.ToList<FilteredConcelhos>();
which errors out in the ToList method with the description "Sequence contains no matching element"
Any help would be great with this...
update:
Turns out I was missing get set attributes in the newly declared class...
Like so
public class FilteredConcelhos
{
public string id { get; set; }
public string descricao { get; set; }
}
This clears the exception, but the resulting List is still all wrong (FilteredConcelhos.id contains nothing and FilteredConcelhos.descricao contains numbers)
Can you try to first execute the ToList and the select afterwards - then the select is performed via linq 2 objects!
Have you tried to work with an anonymous type?
var query = (from o in bd.concelhos
orderby o.descricao
select new { id = o.idDistrito + "/" + o.idConcelho,
descricao = o.descricao });
var results = query.ToList();
Unfortunately, this happened to me a lot. I'm not sure about the details of how Linq 2 Object works, but if you'll call ToList on the original object, like this:
from o in bd.concelhos.ToList()
...
It should do the trick.

Left Join in Subsonic3

I'm new in subsonic3, and I'm getting some errors when I try to use LeftJoin
var q =
from c in categories
join p in products on c equals p.Category into ps
from p in ps.DefaultIfEmpty()
select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName };
The error is
"System.Collections.Generic.Enumerable '...' cannot be used for parameter of type System.Linq.IQueryable
Does anyone had this error before? Did you fix it?
Thanks
I don't know which one is the IQueryable property but you probably know, just add the .AsEnumerable() method.
categories.AsEnumerable() or products.AsEnumerable()
I cant remember if you had to add the toList() method also but you can try it out.
categories.AsEnumerable().toList() or products.AsEnumerable().toList()

Resources