public Page<TurnEntity> find(
@NotNull String station,
@NotNull LocalDate startDate,
@NotNull LocalDate endDate,
@NotNull Optional<Set<String>> fleets,
@NotNull Optional<Optional<Long>> invoicerRateId,
@NotNull Optional<Class<? extends com.aa.cleanwithus.job.Job>> jobType,
@NotNull Optional<Acceptance> acceptance,
@NotNull Optional<Optional<Provider>> provider,
@NotNull Optional<Node> jobFilter_,
@NotNull Optional<Node> filter,
@NotNull List<OrderByExpr<String>> orderBys,
@NotNull PageSpec pageSpec
){
Map<String, Object> params = new HashMap<>();
params.put("station", station);
params.put("startDate", startDate);
params.put("endDate", endDate);
jobType.ifPresent(j -> params.put("jobType", j));
invoicerRateId.ifPresent(r ->
r.ifPresent(r_ ->
params.put("invoicerRateId", r_)));
Optional<Node> jobFilter = acceptance.isPresent() ?
acceptance.map(a -> combine(eq("acceptance", a), jobFilter_)) :
jobFilter_;
provider.ifPresent(p ->
p.ifPresent(p_ ->
p_.getId().ifPresent(i ->
params.put("providerId", i))));
PredicateProducer<TurnEntity> where =
(crit,root) -> {
CriteriaBuilder b = em.getCriteriaBuilder();
SetJoin<TurnEntity, JobEntity> jobsJoin = root.joinSet("jobs");
Root<ProviderStation> psRoot = crit.from(ProviderStation.class);
Root<ProviderStationJobType> psjtRoot = crit.from(ProviderStationJobType.class);
Subquery<ProviderStationJobType> psjtSubquery = crit.subquery(ProviderStationJobType.class);
Root<ProviderStation> psRootWithSubquery = psjtSubquery.correlate(psRoot);
crit.multiselect(jobsJoin, psRootWithSubquery);
Collection<Predicate> wheres = new ArrayList<>();
Predicate stnPred = b.equal(root.get("station"),
b.parameter(String.class, "station"));
wheres.add(stnPred);
Predicate rjDatePred = b.between(jobsJoin.get("date"),
b.parameter(LocalDate.class, "startDate"),
b.parameter(LocalDate.class, "endDate"));
wheres.add(rjDatePred);
jobType.ifPresent(j ->
wheres.add(b.equal(
jobsJoin.get("type"),
b.parameter(Class.class, "jobType"))));
Expression<String> irId = jobsJoin.get("invoicerRateId");
invoicerRateId.ifPresent(r ->
wheres.add(
r.map(r_ ->
b.equal(irId, b.parameter(Long.class, "invoicerRateId")))
.orElseGet(() -> b.isNull(irId))));
Expression<Long> rjProvider = jobsJoin.get(JobEntity_.provider).get(Provider_.id);
provider.ifPresent(p ->
wheres.add(
p.map(p_ ->
b.or(
b.equal(rjProvider, b.parameter(Long.class, "providerId")),
b.isNull(rjProvider)))
.orElseGet(() -> b.isNull(rjProvider))));
Expression<Long> psProvider = psRoot.get(ProviderStation_.provider).get(Provider_.id);
Predicate psPred = b.and(
b.equal(root.get(TurnEntity_.station), psRoot.get(ProviderStation_.station)),
b.or(
b.equal(rjProvider, psProvider),
b.and(
b.isNull(rjProvider),
provider.map(p ->
p.map(p_ ->
b.equal(psProvider, b.parameter(Long.class, "providerId"))
).orElseGet(() -> b.isNull(psProvider))
).orElseGet(() -> b.isNull(psProvider)),
jobsJoin.get(JobEntity_.type).in(
psjtSubquery.select(psjtRoot.get("type"))
.where(b.or(
b.and(
b.equal(root.get(TurnEntity_.carrierCategory), CompanyCategory.MAINLINE),
psjtRoot.get("category").in(
ProviderStationJobTypeCategory.MAINLINE,
ProviderStationJobTypeCategory.ALL)),
b.and(
b.equal(root.get(TurnEntity_.carrierCategory), CompanyCategory.REGIONAL),
psjtRoot.get("category").in(
ProviderStationJobTypeCategory.REGIONAL,
ProviderStationJobTypeCategory.ALL))))))));
wheres.add(psPred);
jobFilter.ifPresent(f -> wheres.add(toPredicate(em, f, jobsJoin)));
Expression<String> flt = root.get("aircraft").get("fleet");
fleets.ifPresent(f -> wheres.add(f.isEmpty() ? b.isNull(flt) : flt.in(f)));
filter.ifPresent(f -> wheres.add(toPredicate(em, f, root)));
return b.and(wheres.toArray(new Predicate[0]));
};
return page(
pageSpec,
() -> withParams(
countQuery(em, TurnEntity.class, Optional.of(where), false, true),
params),
withParams(
selectQuery(em, TurnEntity.class, Optional.of(where), orderBys)
.setHint(QueryHints.READ_ONLY, true),
params)
);
}