reusable filter

main
Julius Sula 2023-06-19 16:01:45 +02:00
parent b4e6181cc0
commit ef1f5bf401
7 changed files with 255 additions and 220 deletions

View File

@ -117,7 +117,7 @@ public class KalenderRestController {
@CrossOrigin("*") @CrossOrigin("*")
@GetMapping("/api/getPlanTimes") @GetMapping("/api/getPlanTimes")
public ArrayList<CalendarWeek> getPlanTimes(@RequestBody PlanTimesRequest request) throws ARException { public ArrayList<CalendarWeek> getPlanTimes(@RequestBody PlanTimesRequest request) throws ARException, ValidationError {
PlanTimes p = new PlanTimes(javaAPI); PlanTimes p = new PlanTimes(javaAPI);
p.setPlanTimes(request); p.setPlanTimes(request);
return p.getPlanTimes(); return p.getPlanTimes();

View File

@ -16,7 +16,7 @@ import com.bmc.arsys.api.Timestamp;
import com.bmc.arsys.api.Value; import com.bmc.arsys.api.Value;
import com.nttdata.calender.api.Query; import com.nttdata.calender.api.Query;
import com.nttdata.calender.api.RemedyJavaAPI; import com.nttdata.calender.api.RemedyJavaAPI;
import com.nttdata.calender.changes.query.Filter; import com.nttdata.calender.changes.query.FilterElement;
import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError; import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError;
import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError; import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError;
@ -81,7 +81,8 @@ public class Change {
var peopleFullName = processPeopleInfo(request); var peopleFullName = processPeopleInfo(request);
var qualifier = request.constructQualifier(queryChange, api); var filter = request.getFilter();
var qualifier = filter.constructQualifier(queryChange, api);
SortInfo sort = request.constructSortInfo(queryChange); SortInfo sort = request.constructSortInfo(queryChange);
var entries = api.queryFieldsById(qualifier, this.queryChange.getFieldIds(), var entries = api.queryFieldsById(qualifier, this.queryChange.getFieldIds(),
@ -139,8 +140,10 @@ public class Change {
// state)); // state));
change.setPackageName(queryPackageName(getValueStringByID(entry, "PackageType").toString())); change.setPackageName(queryPackageName(getValueStringByID(entry, "PackageType").toString()));
var ptMinutes = getValueStringByID(entry, "PlanTimeMinutes").isEmpty() ? "00" : getValueStringByID(entry, "PlanTimeMinutes"); var ptMinutes = getValueStringByID(entry, "PlanTimeMinutes").isEmpty() ? "00"
var ptHours = getValueStringByID(entry, "PlanTimeHours").isEmpty() ? "00" : getValueStringByID(entry, "PlanTimeHours"); : getValueStringByID(entry, "PlanTimeMinutes");
var ptHours = getValueStringByID(entry, "PlanTimeHours").isEmpty() ? "00"
: getValueStringByID(entry, "PlanTimeHours");
change.setPlanTime(convertPlanTime(ptHours, ptMinutes)); change.setPlanTime(convertPlanTime(ptHours, ptMinutes));
change.setPackageName(queryPackageName(getValueStringByID(entry, "PackageType").toString())); change.setPackageName(queryPackageName(getValueStringByID(entry, "PackageType").toString()));
@ -183,15 +186,15 @@ public class Change {
throw new NotFoundError("No supportGroups associated to the loginId "); throw new NotFoundError("No supportGroups associated to the loginId ");
} }
request.addFilter( request.addFilter(
new Filter("SupportGroupId", "equals", peopleSupportGroup)); new FilterElement("SupportGroupId", "equals", peopleSupportGroup));
return peopleInfos.get(0).get(queryPerson.getFieldId("FullName")).toString(); return peopleInfos.get(0).get(queryPerson.getFieldId("FullName")).toString();
} }
/** /**
* Converts the planned time which is passed in hours and minutes to total hours * Converts the planned time which is passed in hours and minutes to total hours
* *
* @param hours the hours as a String * @param hours the hours as a String
* @param minutes the minutes as a String * @param minutes the minutes as a String
* @return the hours and minutes as total hours * @return the hours and minutes as total hours
* @throws ARException * @throws ARException

View File

@ -10,6 +10,7 @@ import com.bmc.arsys.api.SortInfo;
import com.nttdata.calender.api.Query; import com.nttdata.calender.api.Query;
import com.nttdata.calender.api.RemedyJavaAPI; import com.nttdata.calender.api.RemedyJavaAPI;
import com.nttdata.calender.changes.query.Filter; import com.nttdata.calender.changes.query.Filter;
import com.nttdata.calender.changes.query.FilterElement;
import com.nttdata.calender.changes.query.Sort; import com.nttdata.calender.changes.query.Sort;
import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError; import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError;
@ -21,7 +22,7 @@ import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError;
public class ChangeRequest { public class ChangeRequest {
private int sliceStart; private int sliceStart;
private int sliceEnd; private int sliceEnd;
private ArrayList<Filter> filter; private Filter filter;
private Sort sort; private Sort sort;
/** /**
@ -63,19 +64,21 @@ public class ChangeRequest {
/** /**
* Returns the array of filter criteria. * Returns the array of filter criteria.
* *
* @return an array of {@link Filter} objects representing the filter criteria. * @return an array of {@link FilterElement} objects representing the filter
* criteria.
*/ */
public ArrayList<Filter> getFilter() { public Filter getFilter() {
return this.filter; return this.filter;
} }
/** /**
* Sets the array of filter criteria. * Sets the array of filter criteria.
* *
* @param filter an array of {@link Filter} objects representing the filter * @param filter an array of {@link FilterElement} objects representing the
* filter
* criteria. * criteria.
*/ */
public void setFilter(ArrayList<Filter> filter) { public void setFilter(Filter filter) {
this.filter = filter; this.filter = filter;
} }
@ -102,11 +105,11 @@ public class ChangeRequest {
* *
* @param filter the filter to add * @param filter the filter to add
*/ */
public void addFilter(Filter filter) { public void addFilter(FilterElement filter) {
if (this.filter == null) { if (this.filter == null) {
this.filter = new ArrayList<Filter>(); this.filter = new Filter();
} }
this.filter.add(filter); this.filter.addFilter(filter);
} }
/** /**
@ -125,138 +128,4 @@ public class ChangeRequest {
} }
return null; return null;
} }
/**
* Constructs and returns a qualifier based on the filters defined in the object
* and the given Query object.
*
* @param query the Query object containing form and field information
* @param api the RemedyJavaAPI object used for accessing the AR System API
* @return a String representing the constructed qualifier
* @throws ARException if an error occurs while constructing the qualifier
* or an invalid filter is provided
* @throws ValidationError if the fields inside the filter are empty or an
* invalid inner filter argument is provided
*/
public String constructQualifier(Query query, RemedyJavaAPI api) throws ARException, ValidationError {
var qualifier = "";
if (this.filter == null) {
return qualifier;
}
for (int i = 0; i < this.filter.size(); i++) {
var current_filter = this.filter.get(i);
var column = current_filter.getColumn();
var criterias = current_filter.getCriteria();
if (column.isEmpty() || criterias.length <= 0) {
throw new ValidationError("Fields inside filter empty");
}
var inner_qualifier = "";
if (column.equals("D2")) {
var dateQualifier = constructDateQualifier(current_filter, column, query, api);
qualifier = "(" + dateQualifier + ")";
} else {
column = api.getFieldDatabaseName(query.getFormName(), query.getFieldId(column));
var inner_filter = "\'" + column + "\' ";
var inner_concat = " OR ";
var inner_criteria_prefix = "";
switch (current_filter.getFilter()) {
case "equals":
inner_filter += "= ";
break;
case "contains":
inner_filter += "LIKE ";
inner_concat = " AND ";
inner_criteria_prefix = "%";
break;
default:
throw new ValidationError("Invalid inner filter argument");
}
for (int j = 0; j < criterias.length; j++) {
criterias[j] = inner_criteria_prefix + criterias[j] + inner_criteria_prefix;
inner_qualifier += "(" + inner_filter + "\"" + criterias[j] + "\")";
if (j < criterias.length - 1) {
inner_qualifier += inner_concat;
}
}
qualifier += "(" + inner_qualifier + ")";
}
if (i < filter.size() - 1) {
qualifier += " AND ";
}
}
return qualifier;
}
/**
* Constructs and returns a date qualifier for the given filter, column, query,
* and API.
* Throws a ValidationError if the date filter does not contain two date
* elements.
*
* @param current_filter the current filter to construct the date qualifier for
* @param column the column to apply the date qualifier on
* @param query the query object
* @param api the RemedyJavaAPI object
* @return the constructed date qualifier as a string
* @throws ValidationError if the date filter does not contain two date elements
* @throws ARException if an AR exception occurs
*/
private String constructDateQualifier(Filter current_filter, String column, Query query, RemedyJavaAPI api)
throws ValidationError, ARException {
if (current_filter.getCriteria().length != 2) {
throw new ValidationError("Date Filter does not contain 2 date elements");
}
var startFrom = current_filter.getCriteria()[0];
var startTo = current_filter.getCriteria()[1];
var startFromFormatted = convertDate(startFrom);
var startToFormatted = convertDate(startTo);
var qualifier = "";
var dateColumn = api.getFieldDatabaseName(query.getFormName(), query.getFieldId(column));
// Same day changes need to startFrom=day and startTo=day+24h 60m 60s
if (startFromFormatted.equals(startToFormatted)) {
startToFormatted = "\' < (\"" + startToFormatted + "\"" + " + (24 * (60 * 60)))";
} else
startToFormatted = "\' <= \"" + startToFormatted + "\"";
qualifier += "\'" + dateColumn + "\' >= \"" + startFromFormatted + "\" AND ";
qualifier += "\'" + dateColumn + startToFormatted;
return qualifier;
}
/**
* Converts the provided date string into a Remedy-specific date format and
* returns it.
* Throws a ValidationError if the provided date format cannot be parsed into
* the Remedy-specific date format.
*
* @param date the date string to convert
* @return the converted date string in Remedy-specific format
* @throws ValidationError if the provided date format cannot be parsed into the
* Remedy-specific date format
*/
private String convertDate(String date) throws ValidationError {
String inputFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
String outputFormat = "dd/MM/yyyy";
var parsed = "";
try {
LocalDateTime parser = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(inputFormat));
parsed = parser.format(DateTimeFormatter.ofPattern(outputFormat));
} catch (DateTimeParseException e) {
throw new ValidationError("Provided date format cannot be parsed into Remedy specific date format");
}
return parsed;
}
} }

View File

@ -1,72 +1,161 @@
package com.nttdata.calender.changes.query; package com.nttdata.calender.changes.query;
import com.nttdata.calender.changes.Change; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import com.bmc.arsys.api.ARException;
import com.nttdata.calender.api.Query;
import com.nttdata.calender.api.RemedyJavaAPI;
import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError;
/**
* Defines the filter objects used in the retrieval of {@link Change}.
*/
public class Filter { public class Filter {
private String column; private ArrayList<FilterElement> filter;
private String filter;
private String[] criteria;
public Filter(String column, String filter, String[] criteria) { /**
this.column = column; * Adds a filter to the list of filters.
this.filter = filter; *
this.criteria = criteria; * @param filter the filter to add
*/
public void addFilter(FilterElement filter) {
if (this.filter == null) {
this.filter = new ArrayList<FilterElement>();
}
this.filter.add(filter);
} }
/** /**
* Returns column of {@link Filter} * Constructs and returns a qualifier based on the filters defined in the object
* * and the given Query object.
* @return the column *
* @param query the Query object containing form and field information
* @param api the RemedyJavaAPI object used for accessing the AR System API
* @return a String representing the constructed qualifier
* @throws ARException if an error occurs while constructing the qualifier
* or an invalid filter is provided
* @throws ValidationError if the fields inside the filter are empty or an
* invalid inner filter argument is provided
*/ */
public String getColumn() { public String constructQualifier(Query query, RemedyJavaAPI api) throws ARException, ValidationError {
return this.column; var qualifier = "";
if (this.filter == null) {
return qualifier;
}
for (int i = 0; i < this.filter.size(); i++) {
var current_filter = this.filter.get(i);
var column = current_filter.getColumn();
var criterias = current_filter.getCriteria();
if (column.isEmpty() || criterias.length <= 0) {
throw new ValidationError("Fields inside filter empty");
}
var inner_qualifier = "";
if (column.equals("D2")) {
var dateQualifier = constructDateQualifier(current_filter, column, query, api);
qualifier = "(" + dateQualifier + ")";
} else {
column = api.getFieldDatabaseName(query.getFormName(), query.getFieldId(column));
var inner_filter = "\'" + column + "\' ";
var inner_concat = " OR ";
var inner_criteria_prefix = "";
switch (current_filter.getFilter()) {
case "equals":
inner_filter += "= ";
break;
case "contains":
inner_filter += "LIKE ";
inner_concat = " AND ";
inner_criteria_prefix = "%";
break;
default:
throw new ValidationError("Invalid inner filter argument");
}
for (int j = 0; j < criterias.length; j++) {
criterias[j] = inner_criteria_prefix + criterias[j] + inner_criteria_prefix;
inner_qualifier += "(" + inner_filter + "\"" + criterias[j] + "\")";
if (j < criterias.length - 1) {
inner_qualifier += inner_concat;
}
}
qualifier += "(" + inner_qualifier + ")";
}
if (i < filter.size() - 1) {
qualifier += " AND ";
}
}
return qualifier;
} }
/** /**
* Sets column of {@link Filter} * Constructs and returns a date qualifier for the given filter, column, query,
* * and API.
* @param column the column to set * Throws a ValidationError if the date filter does not contain two date
* elements.
*
* @param current_filter the current filter to construct the date qualifier for
* @param column the column to apply the date qualifier on
* @param query the query object
* @param api the RemedyJavaAPI object
* @return the constructed date qualifier as a string
* @throws ValidationError if the date filter does not contain two date elements
* @throws ARException if an AR exception occurs
*/ */
public void setColumn(String column) { private String constructDateQualifier(FilterElement current_filter, String column, Query query, RemedyJavaAPI api)
this.column = column; throws ValidationError, ARException {
if (current_filter.getCriteria().length != 2) {
throw new ValidationError("Date Filter does not contain 2 date elements");
}
var startFrom = current_filter.getCriteria()[0];
var startTo = current_filter.getCriteria()[1];
var startFromFormatted = convertDate(startFrom);
var startToFormatted = convertDate(startTo);
var qualifier = "";
var dateColumn = api.getFieldDatabaseName(query.getFormName(), query.getFieldId(column));
// Same day changes need to startFrom=day and startTo=day+24h 60m 60s
if (startFromFormatted.equals(startToFormatted)) {
startToFormatted = "\' < (\"" + startToFormatted + "\"" + " + (24 * (60 * 60)))";
} else
startToFormatted = "\' <= \"" + startToFormatted + "\"";
qualifier += "\'" + dateColumn + "\' >= \"" + startFromFormatted + "\" AND ";
qualifier += "\'" + dateColumn + startToFormatted;
return qualifier;
} }
/** /**
* Returns filter of {@link Filter} * Converts the provided date string into a Remedy-specific date format and
* * returns it.
* @return the filter * Throws a ValidationError if the provided date format cannot be parsed into
* the Remedy-specific date format.
*
* @param date the date string to convert
* @return the converted date string in Remedy-specific format
* @throws ValidationError if the provided date format cannot be parsed into the
* Remedy-specific date format
*/ */
public String getFilter() { private String convertDate(String date) throws ValidationError {
return this.filter; String inputFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
} String outputFormat = "dd/MM/yyyy";
/** var parsed = "";
* Sets filter of {@link Filter} try {
* LocalDateTime parser = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(inputFormat));
* @param filter the filter to set parsed = parser.format(DateTimeFormatter.ofPattern(outputFormat));
*/ } catch (DateTimeParseException e) {
public void setFilter(String filter) { throw new ValidationError("Provided date format cannot be parsed into Remedy specific date format");
this.filter = filter; }
return parsed;
} }
}
/**
* Returns the criterias of {@link Filter}.
*
* @return the criteria
*/
public String[] getCriteria() {
return this.criteria;
}
/**
* Sets the criteria of the {@link Filter}.
*
* @param criteria the criteria to set
*/
public void setCriteria(String[] criteria) {
this.criteria = criteria;
}
}

View File

@ -0,0 +1,72 @@
package com.nttdata.calender.changes.query;
import com.nttdata.calender.changes.Change;
/**
* Defines the filter objects used in the retrieval of {@link Change}.
*/
public class FilterElement {
private String column;
private String filter;
private String[] criteria;
public FilterElement(String column, String filter, String[] criteria) {
this.column = column;
this.filter = filter;
this.criteria = criteria;
}
/**
* Returns column of {@link FilterElement}
*
* @return the column
*/
public String getColumn() {
return this.column;
}
/**
* Sets column of {@link FilterElement}
*
* @param column the column to set
*/
public void setColumn(String column) {
this.column = column;
}
/**
* Returns filter of {@link FilterElement}
*
* @return the filter
*/
public String getFilter() {
return this.filter;
}
/**
* Sets filter of {@link FilterElement}
*
* @param filter the filter to set
*/
public void setFilter(String filter) {
this.filter = filter;
}
/**
* Returns the criterias of {@link FilterElement}.
*
* @return the criteria
*/
public String[] getCriteria() {
return this.criteria;
}
/**
* Sets the criteria of the {@link FilterElement}.
*
* @param criteria the criteria to set
*/
public void setCriteria(String[] criteria) {
this.criteria = criteria;
}
}

View File

@ -16,6 +16,7 @@ import com.bmc.thirdparty.org.springframework.cglib.core.Local;
import com.nttdata.calender.api.Query; import com.nttdata.calender.api.Query;
import com.nttdata.calender.api.RemedyJavaAPI; import com.nttdata.calender.api.RemedyJavaAPI;
import com.nttdata.calender.changes.ChangeItem; import com.nttdata.calender.changes.ChangeItem;
import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError;
public class PlanTimes { public class PlanTimes {
private RemedyJavaAPI remedyJavaAPI; private RemedyJavaAPI remedyJavaAPI;
@ -27,13 +28,14 @@ public class PlanTimes {
this.calenderWeeks = new ArrayList<>(); this.calenderWeeks = new ArrayList<>();
} }
public void setPlanTimes(PlanTimesRequest req) throws ARException { public void setPlanTimes(PlanTimesRequest req) throws ARException, ValidationError {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
LocalDate startDate = LocalDate.parse(req.getRenderStartDate(), formatter); LocalDate startDate = LocalDate.parse(req.getRenderStartDate(), formatter);
LocalDate endDate = LocalDate.parse(req.getRenderEndDate(), formatter); LocalDate endDate = LocalDate.parse(req.getRenderEndDate(), formatter);
var queryChanges = new Query.QueryBuilder(formName).addFieldId("D2", 1000000350) var queryChanges = new Query.QueryBuilder(formName).addFieldId("D2", 1000000350)
.addFieldId("ChangeNr", 1000000182).addFieldId("PlanTimeHours", 666000009).addFieldId("PlanTimeMinutes", 666000010).build(); .addFieldId("ChangeNr", 1000000182).addFieldId("PlanTimeHours", 666000009)
.addFieldId("PlanTimeMinutes", 666000010).build();
while (!startDate.isAfter(endDate)) { while (!startDate.isAfter(endDate)) {
CalendarWeek calendarWeek = new CalendarWeek(); CalendarWeek calendarWeek = new CalendarWeek();
@ -55,9 +57,10 @@ public class PlanTimes {
startDate = startDate.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); startDate = startDate.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
} }
var filter = req.getFilter();
var qual = filter.constructQualifier(null, remedyJavaAPI);
var changesInDateRange = remedyJavaAPI.queryFieldsById( var changesInDateRange = remedyJavaAPI.queryFieldsById(
"\'Scheduled Start Date\' > \"" + req.getRenderStartDate() + "\" AND \'Scheduled Start Date\' <= \"" qual,
+ req.getRenderEndDate() + "\"",
queryChanges.getFieldIds(), formName, null, 0, 0); queryChanges.getFieldIds(), formName, null, 0, 0);
for (var week : calenderWeeks) { for (var week : calenderWeeks) {
@ -68,10 +71,10 @@ public class PlanTimes {
LocalDate dateEnd = LocalDate.parse(week.getEndDate(), formatter); LocalDate dateEnd = LocalDate.parse(week.getEndDate(), formatter);
if (d2.isAfter(dateStart) && (d2.isEqual(dateEnd) || d2.isBefore(dateEnd))) { if (d2.isAfter(dateStart) && (d2.isEqual(dateEnd) || d2.isBefore(dateEnd))) {
var minutes = change.get(queryChanges.getFieldId("PlanTimeMinutes")).toString(); var minutes = change.get(queryChanges.getFieldId("PlanTimeMinutes")).toString();
var hours = change.get(queryChanges.getFieldId("PlanTimeHours")).toString(); var hours = change.get(queryChanges.getFieldId("PlanTimeHours")).toString();
double plantime = convertPlanTime(hours, minutes); double plantime = convertPlanTime(hours, minutes);
planTimePerWeek += plantime; planTimePerWeek += plantime;
} }
} }
week.setPlanTime((int) Math.ceil(planTimePerWeek)); week.setPlanTime((int) Math.ceil(planTimePerWeek));
@ -81,12 +84,13 @@ public class PlanTimes {
public double convertPlanTime(String hours, String minutes) throws ARException { public double convertPlanTime(String hours, String minutes) throws ARException {
double mins = 0.0; double mins = 0.0;
double hrs = 0.0; double hrs = 0.0;
if (minutes != null) mins = (Double.valueOf(minutes) / 60.0); if (minutes != null)
if (hours != null) Double.valueOf(hours); mins = (Double.valueOf(minutes) / 60.0);
if (hours != null)
Double.valueOf(hours);
double totalHours = hrs + mins; double totalHours = hrs + mins;
return totalHours; return totalHours;
} }
public LocalDate timestampToDate(String timestamp) { public LocalDate timestampToDate(String timestamp) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");

View File

@ -1,19 +1,17 @@
package com.nttdata.calender.planTimes; package com.nttdata.calender.planTimes;
import java.util.ArrayList;
import com.nttdata.calender.changes.query.Filter; import com.nttdata.calender.changes.query.Filter;
public class PlanTimesRequest { public class PlanTimesRequest {
private ArrayList<Filter> filter; private Filter filter;
private String renderStartDate; private String renderStartDate;
private String renderEndDate; private String renderEndDate;
public ArrayList<Filter> getFilter() { public Filter getFilter() {
return filter; return filter;
} }
public void setFilter(ArrayList<Filter> filter) { public void setFilter(Filter filter) {
this.filter = filter; this.filter = filter;
} }