diff --git a/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java b/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java index 9100df9..e17c2f6 100644 --- a/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java +++ b/backend/src/main/java/com/nttdata/calender/api/KalenderRestController.java @@ -117,7 +117,7 @@ public class KalenderRestController { @CrossOrigin("*") @GetMapping("/api/getPlanTimes") - public ArrayList getPlanTimes(@RequestBody PlanTimesRequest request) throws ARException { + public ArrayList getPlanTimes(@RequestBody PlanTimesRequest request) throws ARException, ValidationError { PlanTimes p = new PlanTimes(javaAPI); p.setPlanTimes(request); return p.getPlanTimes(); diff --git a/backend/src/main/java/com/nttdata/calender/changes/Change.java b/backend/src/main/java/com/nttdata/calender/changes/Change.java index 68ac7fd..b9c4d07 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/Change.java +++ b/backend/src/main/java/com/nttdata/calender/changes/Change.java @@ -16,7 +16,7 @@ import com.bmc.arsys.api.Timestamp; import com.bmc.arsys.api.Value; import com.nttdata.calender.api.Query; 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.ValidationError; @@ -81,7 +81,8 @@ public class Change { 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); var entries = api.queryFieldsById(qualifier, this.queryChange.getFieldIds(), @@ -139,8 +140,10 @@ public class Change { // state)); change.setPackageName(queryPackageName(getValueStringByID(entry, "PackageType").toString())); - var ptMinutes = getValueStringByID(entry, "PlanTimeMinutes").isEmpty() ? "00" : getValueStringByID(entry, "PlanTimeMinutes"); - var ptHours = getValueStringByID(entry, "PlanTimeHours").isEmpty() ? "00" : getValueStringByID(entry, "PlanTimeHours"); + var ptMinutes = getValueStringByID(entry, "PlanTimeMinutes").isEmpty() ? "00" + : getValueStringByID(entry, "PlanTimeMinutes"); + var ptHours = getValueStringByID(entry, "PlanTimeHours").isEmpty() ? "00" + : getValueStringByID(entry, "PlanTimeHours"); change.setPlanTime(convertPlanTime(ptHours, ptMinutes)); change.setPackageName(queryPackageName(getValueStringByID(entry, "PackageType").toString())); @@ -183,15 +186,15 @@ public class Change { throw new NotFoundError("No supportGroups associated to the loginId "); } request.addFilter( - new Filter("SupportGroupId", "equals", peopleSupportGroup)); + new FilterElement("SupportGroupId", "equals", peopleSupportGroup)); 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 * @return the hours and minutes as total hours * @throws ARException diff --git a/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java b/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java index 421ad5f..1dd82d8 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java +++ b/backend/src/main/java/com/nttdata/calender/changes/ChangeRequest.java @@ -10,6 +10,7 @@ import com.bmc.arsys.api.SortInfo; import com.nttdata.calender.api.Query; import com.nttdata.calender.api.RemedyJavaAPI; 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.errorhandling.ErrorTypes.ValidationError; @@ -21,7 +22,7 @@ import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError; public class ChangeRequest { private int sliceStart; private int sliceEnd; - private ArrayList filter; + private Filter filter; private Sort sort; /** @@ -63,19 +64,21 @@ public class ChangeRequest { /** * 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 getFilter() { + public Filter getFilter() { return this.filter; } /** * 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. */ - public void setFilter(ArrayList filter) { + public void setFilter(Filter filter) { this.filter = filter; } @@ -102,11 +105,11 @@ public class ChangeRequest { * * @param filter the filter to add */ - public void addFilter(Filter filter) { + public void addFilter(FilterElement filter) { if (this.filter == null) { - this.filter = new ArrayList(); + this.filter = new Filter(); } - this.filter.add(filter); + this.filter.addFilter(filter); } /** @@ -125,138 +128,4 @@ public class ChangeRequest { } 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; - } } diff --git a/backend/src/main/java/com/nttdata/calender/changes/query/Filter.java b/backend/src/main/java/com/nttdata/calender/changes/query/Filter.java index 6f85879..2ea44d9 100644 --- a/backend/src/main/java/com/nttdata/calender/changes/query/Filter.java +++ b/backend/src/main/java/com/nttdata/calender/changes/query/Filter.java @@ -1,72 +1,161 @@ 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 { - private String column; - private String filter; - private String[] criteria; + private ArrayList filter; - public Filter(String column, String filter, String[] criteria) { - this.column = column; - this.filter = filter; - this.criteria = criteria; + /** + * Adds a filter to the list of filters. + * + * @param filter the filter to add + */ + public void addFilter(FilterElement filter) { + if (this.filter == null) { + this.filter = new ArrayList(); + } + this.filter.add(filter); } /** - * Returns column of {@link Filter} - * - * @return the column + * 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 getColumn() { - return this.column; + 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; } /** - * Sets column of {@link Filter} - * - * @param column the column to set + * 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 */ - public void setColumn(String column) { - this.column = column; + private String constructDateQualifier(FilterElement 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; } /** - * Returns filter of {@link Filter} - * - * @return the filter + * 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 */ - public String getFilter() { - return this.filter; - } + private String convertDate(String date) throws ValidationError { + String inputFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; + String outputFormat = "dd/MM/yyyy"; - /** - * Sets filter of {@link Filter} - * - * @param filter the filter to set - */ - public void setFilter(String filter) { - this.filter = filter; + 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; } - - /** - * 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; - } -} \ No newline at end of file +} diff --git a/backend/src/main/java/com/nttdata/calender/changes/query/FilterElement.java b/backend/src/main/java/com/nttdata/calender/changes/query/FilterElement.java new file mode 100644 index 0000000..1f18e6a --- /dev/null +++ b/backend/src/main/java/com/nttdata/calender/changes/query/FilterElement.java @@ -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; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/nttdata/calender/planTimes/PlanTimes.java b/backend/src/main/java/com/nttdata/calender/planTimes/PlanTimes.java index 3b1f823..96a48ce 100644 --- a/backend/src/main/java/com/nttdata/calender/planTimes/PlanTimes.java +++ b/backend/src/main/java/com/nttdata/calender/planTimes/PlanTimes.java @@ -16,6 +16,7 @@ import com.bmc.thirdparty.org.springframework.cglib.core.Local; import com.nttdata.calender.api.Query; import com.nttdata.calender.api.RemedyJavaAPI; import com.nttdata.calender.changes.ChangeItem; +import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError; public class PlanTimes { private RemedyJavaAPI remedyJavaAPI; @@ -27,13 +28,14 @@ public class PlanTimes { 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"); LocalDate startDate = LocalDate.parse(req.getRenderStartDate(), formatter); LocalDate endDate = LocalDate.parse(req.getRenderEndDate(), formatter); 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)) { CalendarWeek calendarWeek = new CalendarWeek(); @@ -55,9 +57,10 @@ public class PlanTimes { startDate = startDate.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); } + var filter = req.getFilter(); + var qual = filter.constructQualifier(null, remedyJavaAPI); var changesInDateRange = remedyJavaAPI.queryFieldsById( - "\'Scheduled Start Date\' > \"" + req.getRenderStartDate() + "\" AND \'Scheduled Start Date\' <= \"" - + req.getRenderEndDate() + "\"", + qual, queryChanges.getFieldIds(), formName, null, 0, 0); for (var week : calenderWeeks) { @@ -68,10 +71,10 @@ public class PlanTimes { LocalDate dateEnd = LocalDate.parse(week.getEndDate(), formatter); if (d2.isAfter(dateStart) && (d2.isEqual(dateEnd) || d2.isBefore(dateEnd))) { - var minutes = change.get(queryChanges.getFieldId("PlanTimeMinutes")).toString(); - var hours = change.get(queryChanges.getFieldId("PlanTimeHours")).toString(); - double plantime = convertPlanTime(hours, minutes); - planTimePerWeek += plantime; + var minutes = change.get(queryChanges.getFieldId("PlanTimeMinutes")).toString(); + var hours = change.get(queryChanges.getFieldId("PlanTimeHours")).toString(); + double plantime = convertPlanTime(hours, minutes); + planTimePerWeek += plantime; } } week.setPlanTime((int) Math.ceil(planTimePerWeek)); @@ -81,12 +84,13 @@ public class PlanTimes { public double convertPlanTime(String hours, String minutes) throws ARException { double mins = 0.0; double hrs = 0.0; - if (minutes != null) mins = (Double.valueOf(minutes) / 60.0); - if (hours != null) Double.valueOf(hours); + if (minutes != null) + mins = (Double.valueOf(minutes) / 60.0); + if (hours != null) + Double.valueOf(hours); double totalHours = hrs + mins; return totalHours; -} - + } public LocalDate timestampToDate(String timestamp) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); diff --git a/backend/src/main/java/com/nttdata/calender/planTimes/PlanTimesRequest.java b/backend/src/main/java/com/nttdata/calender/planTimes/PlanTimesRequest.java index d608c8a..618fa27 100644 --- a/backend/src/main/java/com/nttdata/calender/planTimes/PlanTimesRequest.java +++ b/backend/src/main/java/com/nttdata/calender/planTimes/PlanTimesRequest.java @@ -1,19 +1,17 @@ package com.nttdata.calender.planTimes; -import java.util.ArrayList; - import com.nttdata.calender.changes.query.Filter; public class PlanTimesRequest { - private ArrayList filter; + private Filter filter; private String renderStartDate; private String renderEndDate; - public ArrayList getFilter() { + public Filter getFilter() { return filter; } - public void setFilter(ArrayList filter) { + public void setFilter(Filter filter) { this.filter = filter; }