InventoryFilter.java
/*
* Copyright 2020 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gringlobal.service.filter;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.genesys.blocks.model.filters.TemporalFilter;
import org.genesys.blocks.model.filters.NumberFilter;
import org.genesys.blocks.model.filters.StringFilter;
import org.genesys.blocks.util.CurrentApplicationContext;
import org.gringlobal.api.exception.InvalidApiUsageException;
import org.gringlobal.model.Inventory;
import org.gringlobal.model.QCropTraitObservation;
import org.gringlobal.model.QInventory;
import com.querydsl.core.types.Predicate;
import org.gringlobal.model.QInventoryAction;
/**
* Filters for {@link Inventory}
*/
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
@Accessors(fluent = true)
public class InventoryFilter extends CooperatorOwnedModelFilter<InventoryFilter, Inventory> implements IFullTextFilter {
private static final long serialVersionUID = -6168038817307724417L;
/** Any text. */
public String _text;
/** Include system inventories */
public Boolean includeSystem = false;
/** The accession. */
public AccessionFilter accession;
/** The inventory preferred name */
public StringFilter preferredName;
/** Site */
public SiteFilter site;
/** The availability end date. */
public TemporalFilter<Date> availabilityEndDate;
/** The availability start date. */
public TemporalFilter<Date> availabilityStartDate;
/** The availability status code. */
public Set<String> availabilityStatusCode;
/** The availability status note. */
public StringFilter availabilityStatusNote;
/** The backup inventory. */
public Long backupInventory;
/** The distribution critical quantity. */
public NumberFilter<Double> distributionCriticalQuantity;
/** The distribution default form code. */
public Set<String> distributionDefaultFormCode;
/** The distribution unit code. */
public Set<String> distributionUnitCode;
/** The form type code. */
public Set<String> formTypeCode;
/** The distribution default quantity. */
public NumberFilter<Double> distributionDefaultQuantity;
/** The hundred seed weight. */
public NumberFilter<Double> hundredSeedWeight;
/** The inventory number. */
public Set<String> inventoryNumber;
/** The inventory number part1. */
public StringFilter inventoryNumberPart1;
/** The inventory number part2. */
public NumberFilter<Long> inventoryNumberPart2;
/** The inventory number part3. */
public StringFilter inventoryNumberPart3;
/** Is auto deducted */
public Boolean autoDeducted;
/** Is available */
public Boolean available;
/** Is distributable */
public Boolean distributable;
/** The latitude. */
public NumberFilter<Double> latitude;
/** The longitude. */
public NumberFilter<Double> longitude;
/** The note. */
public StringFilter note;
/** The parent inventory. */
public Long parentInventory;
/** The pathogen status code. */
public Set<String> pathogenStatusCode;
/** The plant sex code. */
public Set<String> plantSexCode;
/** The pollination method code. */
public Set<String> pollinationMethodCode;
/** The pollination vector code. */
public Set<String> pollinationVectorCode;
/** The preservation method. */
public MethodFilter preservationMethod;
/** The regeneration method. */
public MethodFilter regenerationMethod;
/** The inventory maintenance policy. */
public InventoryMaintenancePolicyFilter inventoryMaintenancePolicy;
/** The propagation date. */
public TemporalFilter<Date> propagationDate;
/** The propagation date code. */
public Set<String> propagationDateCode;
/** The quantity on hand. */
public NumberFilter<Double> quantityOnHand;
/** The quantity on hand unit code. */
public Set<String> quantityOnHandUnitCode;
/** The regeneration critical quantity. */
public NumberFilter<Double> regenerationCriticalQuantity;
/** The rootstock. */
public StringFilter rootstock;
/** The barcode. */
public Set<String> barcode;
/** The storage location part1. */
public StringFilter storageLocationPart1;
/** The storage location part2. */
public StringFilter storageLocationPart2;
/** The storage location part3. */
public StringFilter storageLocationPart3;
/** The storage location part4. */
public StringFilter storageLocationPart4;
/** The web availability note. */
public StringFilter webAvailabilityNote;
/** The accession inventory group id. */
public Set<Long> accessionInvGroup;
/** The inventory action filter */
public InventoryActionFilter actions;
/** The inventory action filter */
public AccessionInvNameFilter names;
/** The inventory extra filter */
public InventoryExtraFilter extra;
/** The crop traits value */
public List<CropTraitObservationFilter.CropTraitValueFilter> cropTraits;
/** The production location geography */
public GeographyFilter productionLocationGeography;
/** Inventory names */
public StringFilter plantName;
/** The attachment */
public AccessionInvAttachFilter accessionInvAttach;
/**
* Builds the query.
*
* @return the predicate
*/
@Override
public List<Predicate> collectPredicates() {
return collectPredicates(QInventory.inventory);
}
/**
* Builds the query.
*
* @param inventory the inventory
* @return the predicate
*/
public List<Predicate> collectPredicates(QInventory inventory) {
configExtraNullAndNotNull();
final List<Predicate> predicates = super.collectPredicates(inventory, inventory._super);
if (includeSystem != null && ! includeSystem) {
predicates.add(inventory.formTypeCode.ne(Inventory.SYSTEM_INVENTORY_FTC));
}
if (accession != null) {
predicates.addAll(accession.collectPredicates(inventory.accession()));
}
if (site != null) {
predicates.addAll(site.collectPredicates(inventory.site()));
}
if (availabilityEndDate != null) {
predicates.add(availabilityEndDate.buildQuery(inventory.availabilityEndDate));
}
if (availabilityStartDate != null) {
predicates.add(availabilityStartDate.buildQuery(inventory.availabilityStartDate));
}
if (CollectionUtils.isNotEmpty(availabilityStatusCode)) {
predicates.add(inventory.availabilityStatusCode.in(availabilityStatusCode));
}
if (availabilityStatusNote != null) {
predicates.add(availabilityStatusNote.buildQuery(inventory.availabilityStatusNote));
}
if (preferredName != null) {
predicates.add(preferredName.buildQuery(inventory.preferredName));
}
if (backupInventory != null) {
predicates.add(inventory.backupInventory().id.eq(backupInventory));
}
if (distributionCriticalQuantity != null) {
predicates.add(distributionCriticalQuantity.buildQuery(inventory.distributionCriticalQuantity));
}
if (CollectionUtils.isNotEmpty(distributionDefaultFormCode)) {
predicates.add(inventory.distributionDefaultFormCode.in(distributionDefaultFormCode));
}
if (CollectionUtils.isNotEmpty(distributionUnitCode)) {
predicates.add(inventory.distributionUnitCode.in(distributionUnitCode));
}
if (CollectionUtils.isNotEmpty(formTypeCode)) {
predicates.add(inventory.formTypeCode.in(formTypeCode));
}
if (distributionDefaultQuantity != null) {
predicates.add(distributionDefaultQuantity.buildQuery(inventory.distributionDefaultQuantity));
}
if (hundredSeedWeight != null) {
predicates.add(hundredSeedWeight.buildQuery(inventory.hundredSeedWeight));
}
if (CollectionUtils.isNotEmpty(inventoryNumber)) {
predicates.add(inventory.inventoryNumber.in(inventoryNumber));
}
if (inventoryNumberPart1 != null) {
predicates.add(inventoryNumberPart1.buildQuery(inventory.inventoryNumberPart1));
}
if (inventoryNumberPart2 != null) {
predicates.add(inventoryNumberPart2.buildQuery(inventory.inventoryNumberPart2));
}
if (inventoryNumberPart3 != null) {
predicates.add(inventoryNumberPart3.buildQuery(inventory.inventoryNumberPart3));
}
if (autoDeducted != null) {
predicates.add(inventory.isAutoDeducted.eq(convertToString(autoDeducted)));
}
if (available != null) {
predicates.add(inventory.isAvailable.eq(convertToString(available)));
}
if (distributable != null) {
predicates.add(inventory.isDistributable.eq(convertToString(distributable)));
}
if (latitude != null) {
predicates.add(latitude.buildQuery(inventory.latitude));
}
if (longitude != null) {
predicates.add(longitude.buildQuery(inventory.longitude));
}
if (note != null) {
predicates.add(note.buildQuery(inventory.note));
}
if (parentInventory != null) {
predicates.add(inventory.parentInventory().id.eq(parentInventory));
}
if (CollectionUtils.isNotEmpty(pathogenStatusCode)) {
predicates.add(inventory.pathogenStatusCode.in(pathogenStatusCode));
}
if (CollectionUtils.isNotEmpty(plantSexCode)) {
predicates.add(inventory.plantSexCode.in(plantSexCode));
}
if (regenerationMethod != null) {
predicates.addAll(regenerationMethod.collectPredicates(inventory.regenerationMethod()));
}
if (preservationMethod != null) {
predicates.addAll(preservationMethod.collectPredicates(inventory.preservationMethod()));
}
if (inventoryMaintenancePolicy != null) {
predicates.addAll(inventoryMaintenancePolicy.collectPredicates(inventory.inventoryMaintenancePolicy()));
}
if (CollectionUtils.isNotEmpty(pollinationMethodCode)) {
predicates.add(inventory.pollinationMethodCode.in(pollinationMethodCode));
}
if (CollectionUtils.isNotEmpty(pollinationVectorCode)) {
predicates.add(inventory.pollinationVectorCode.in(pollinationVectorCode));
}
if (propagationDate != null) {
predicates.add(propagationDate.buildQuery(inventory.propagationDate));
}
if (CollectionUtils.isNotEmpty(propagationDateCode)) {
predicates.add(inventory.propagationDateCode.in(propagationDateCode));
}
if (quantityOnHand != null) {
predicates.add(quantityOnHand.buildQuery(inventory.quantityOnHand));
}
if (CollectionUtils.isNotEmpty(quantityOnHandUnitCode)) {
predicates.add(inventory.quantityOnHandUnitCode.in(quantityOnHandUnitCode));
}
if (regenerationCriticalQuantity != null) {
predicates.add(regenerationCriticalQuantity.buildQuery(inventory.regenerationCriticalQuantity));
}
if (rootstock != null) {
predicates.add(rootstock.buildQuery(inventory.rootstock));
}
if (CollectionUtils.isNotEmpty(barcode)) {
predicates.add(inventory.barcode.in(barcode));
}
if (storageLocationPart1 != null) {
predicates.add(storageLocationPart1.buildQuery(inventory.storageLocationPart1));
}
if (storageLocationPart2 != null) {
predicates.add(storageLocationPart2.buildQuery(inventory.storageLocationPart2));
}
if (storageLocationPart3 != null) {
predicates.add(storageLocationPart3.buildQuery(inventory.storageLocationPart3));
}
if (storageLocationPart4 != null) {
predicates.add(storageLocationPart4.buildQuery(inventory.storageLocationPart4));
}
if (webAvailabilityNote != null) {
predicates.add(webAvailabilityNote.buildQuery(inventory.webAvailabilityNote));
}
if (CollectionUtils.isNotEmpty(accessionInvGroup)) {
predicates.add(inventory.accessionInvGroupMaps.any().accessionInvGroup().id.in(accessionInvGroup));
}
if (actions != null) {
var qInventoryAction = new QInventoryAction(inventory.actions.getMetadata().getName());
predicates.add(nestedFilter(inventory.actions, qInventoryAction, qInventoryAction.inventory().eq(inventory), actions.collectPredicates(qInventoryAction)));
}
if (names != null) {
predicates.addAll(names.collectPredicates(inventory.names.any()));
}
if (extra != null) {
predicates.addAll(extra.collectPredicates(inventory.extra()));
}
if (cropTraits != null) {
if (StringUtils.isNotBlank(_text)) throw new InvalidApiUsageException("_text search is not available when filtering cropTrats");
predicates.add(inventory.id.in(processCropTraitObservations(cropTraits)));
}
if (productionLocationGeography != null) {
predicates.addAll(productionLocationGeography.collectPredicates(inventory.productionLocationGeography()));
}
if (plantName != null) {
predicates.add(plantName.buildQuery(inventory.names.any().plantName));
}
if (accessionInvAttach != null) {
predicates.addAll(accessionInvAttach.collectPredicates(inventory.attachments.any()));
}
return predicates;
}
private JPAQuery<Long> processCropTraitObservations(List<CropTraitObservationFilter.CropTraitValueFilter> cropTraits) {
var jpaQueryFactory = CurrentApplicationContext.getContext().getBean(JPAQueryFactory.class);
JPAQuery<Long> query = null;
int queryNum = 0;
for (var cropTraitFilter : cropTraits) {
var qPath = new QCropTraitObservation("cropTraitObs" + queryNum++);
var predicate = cropTraitFilter.buildPredicate(qPath);
var traitQuery = jpaQueryFactory.selectDistinct(qPath.inventory().id).from(qPath).where(predicate);
if (query != null) {
// Intersection of the two sets of inventory.ids
traitQuery.where(qPath.inventory().id.in(query));
}
query = traitQuery;
}
return query;
}
/**
* Gets the text.
*
* @return the text
*/
@Override
public String get_text() {
return _text;
}
/**
* Id.
*
* @return the sets the
*/
public synchronized Set<Long> id() {
if (id == null) {
id = new HashSet<>();
}
return id;
}
protected void configExtraNullAndNotNull() {
var extraPropName = QInventory.inventory.extra().getMetadata().getName().concat(".");
if (CollectionUtils.isNotEmpty(NULL)) {
var extraProps = NULL.stream().filter(nullProp -> nullProp.startsWith(extraPropName)).collect(Collectors.toList());
if (!extraProps.isEmpty()) {
if (extra == null) {
extra = new InventoryExtraFilter();
}
if (extra.NULL == null) {
extra.NULL(new HashSet<>());
}
extra.NULL.addAll(extraProps.stream().map(extraProp -> extraProp.replaceFirst(extraPropName, "")).collect(Collectors.toSet()));
extraProps.forEach(NULL::remove);
}
}
if (CollectionUtils.isNotEmpty(NOTNULL)) {
var extraProps = NOTNULL.stream().filter(nullProp -> nullProp.startsWith(extraPropName)).collect(Collectors.toList());
if (!extraProps.isEmpty()) {
if (extra == null) {
extra = new InventoryExtraFilter();
}
if (extra.NOTNULL == null) {
extra.NOTNULL(new HashSet<>());
}
extra.NOTNULL.addAll(extraProps.stream().map(extraProp -> extraProp.replaceFirst(extraPropName, "")).collect(Collectors.toSet()));
extraProps.forEach(NOTNULL::remove);
}
}
}
}