package com.nttdata.calender.changes; 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.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.Sort; import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError; /** * Represents a change request object that stores information about slice start, * slice end, * filter criteria, and sorting options. */ public class ChangeRequest { private int sliceStart; private int sliceEnd; private ArrayList filter; private Sort sort; /** * Returns the starting index of the slice. * * @return an int representing the slice start index. */ public int getSliceStart() { return this.sliceStart; } /** * Sets the starting index of the slice. * * @param sliceStart an int representing the slice start index. */ public void setSliceStart(int sliceStart) { this.sliceStart = sliceStart; } /** * Returns the ending index of the slice. * * @return an int representing the slice end index. */ public int getSliceEnd() { return this.sliceEnd; } /** * Sets the ending index of the slice. * * @param sliceEnd an int representing the slice end index. */ public void setSliceEnd(int sliceEnd) { this.sliceEnd = sliceEnd; } /** * Returns the array of filter criteria. * * @return an array of {@link Filter} objects representing the filter criteria. */ public ArrayList getFilter() { return this.filter; } /** * Sets the array of filter criteria. * * @param filter an array of {@link Filter} objects representing the filter * criteria. */ public void setFilter(ArrayList filter) { this.filter = filter; } /** * Returns the sorting options for the change request. * * @return a {@link Sort} object representing the sorting options. */ public Sort getSort() { return this.sort; } /** * Sets the sorting options for the change request. * * @param sort a {@link Sort} object representing the sorting options. */ public void setSort(Sort sort) { this.sort = sort; } /** * Adds a filter to the list of filters. * * @param filter the filter to add */ public void addFilter(Filter filter) { if (this.filter == null) { this.filter = new ArrayList(); } this.filter.add(filter); } /** * Constructs and returns a `SortInfo` object based on the provided `Query` * object. * If no sort information is available, returns `null`. * * @param query the query object used for constructing the `SortInfo` * @return the constructed `SortInfo` object, or `null` if no sort information * is available * @throws ValidationError if a validation error occurs during construction */ public SortInfo constructSortInfo(Query query) throws ValidationError { if (this.sort != null) { return this.sort.getSortInfo(query); } 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; } }