package com.lemans.ds.search import com.lemans.LemansApiController import org.json.JSONObject import org.json.XML import java.sql.Clob import java.time.Instant import java.time.ZoneId @SuppressWarnings(['CatchException']) class GenericSearchController extends LemansApiController { def genericSearchService def filterOptions(String searchType, String filterName, GenericSearchCommand cmd) { String filterType = params.filterType ?: params.searchType List errors = collectFilterOptionErrors(searchType, filterType, filterName) if (errors) { renderErrors(errors) } else { renderPaginated genericSearchService.filterOptions(searchType, filterType, cmd.properties + [filterName: filterName] + multiValuedParameters() + activeVendor()) } } def filters(String searchType, String filterType, GenericSearchCommand cmd) { if (filterType && validFilterType(filterType, searchType)) { renderXMLasJSON genericSearchService.filters(searchType, filterType, cmd.properties) } else { renderErrors(['Invalid Filter Type']) } } def search(String searchType, GenericSearchCommand cmd) { String filterType = params.filterType ?: params.searchType List errors = collectErrors(filterType, searchType) if (errors) { renderErrors(errors) } else { Map criteria = searchParameters(cmd, params) if (criteria.mode) { renderXMLasPaginatedJSON genericSearchService.searchResultsByMode(searchType, filterType, criteria) } else { renderPaginated genericSearchService.searchResults(searchType, filterType, criteria) } } } Map searchParameters(cmd, Map parameters) { if (parameters.goliveDateRange) { goliveDateRange(cmd, parameters.goliveDateRange) } if (parameters.hiddenDateRange) { hiddenDateParser(cmd, parameters.hiddenDateRange) } if (parameters.renewalDateRange) { renewalDateRange(cmd, parameters.renewalDateRange) } if (parameters.activeVendorId) { cmd.vendorId = parameters.activeVendorId } Map criteria = pagination() + common() + cmd.properties + multiValuedParameters() + ['export': 0] criteria } def download(String searchType, GenericSearchCommand cmd) { String filterType = params.filterType ?: params.searchType if (params.goliveDateRange) { goliveDateRange(cmd, params.goliveDateRange) } Map criteria = cmd.properties + common() + multiValuedParameters() + ['export': 1] Map output = genericSearchService.searchResults(searchType, filterType, criteria) if (output?.totalRecords > 10000) { response.status = 400 render toJson([messages: [type: 'error', text: 'count greater than 10,000']]) } else { genericSearchService.downloadCSVFile(output.results, response, (filterType + (criteria.mode ? "-${criteria.mode}" : ''))) } } private boolean validFilterType(String filterType, String searchType) { Map acceptableFilterTypes = FilterXmlGenerator.SEARCH_FILTER_TYPE_MAPPING[searchType.toUpperCase()] acceptableFilterTypes && acceptableFilterTypes[filterType.toUpperCase()] } private boolean validFilterName(String filterType, String searchType, String filterName) { Map acceptableFilterTypes = FilterXmlGenerator.SEARCH_FILTER_TYPE_MAPPING[searchType.toUpperCase()] if (acceptableFilterTypes) { filterName in acceptableFilterTypes[filterType.toUpperCase()] } } private List collectErrors(String filterType, String searchType) { List errors = [] if (!params.pageSize) { errors << 'pageSize is required' } if (!filterType) { errors << 'filterType is required' } if ((filterType && !validFilterType(filterType, searchType))) { errors << 'Invalid Filter Type' } errors } private List collectFilterOptionErrors(String searchType, String filterType, String filterName) { List errors = [] if (!filterType) { errors << 'filterType is required' } if ((filterType && !validFilterType(filterType, searchType))) { errors << 'Invalid Filter Type' } if (!validFilterName(filterType, searchType, filterName)) { errors << 'Invalid Filter Name' } errors } private void renderXMLasPaginatedJSON(Map data) { if (data.totalRecords) { JSONObject json = new JSONObject() String xmlString = (data.resultXML instanceof Clob) ? data.resultXML.getSubString(1 as Long, data.resultXML.length() as Integer) : data.resultXML json.put('meta', [totalRecords: data.totalRecords]) json.put('results', ((JSONObject) XML.toJSONObject(xmlString).get('root')).get('part')) render contentType: 'application/json', text: json } else { render toJson([meta: [totalRecords: 0], results: []]) } } private void renderXMLasJSON(String xml) { if (xml && xml != '') { JSONObject json = new JSONObject() json.put('results', XML.toJSONObject(xml)) render contentType: 'application/json', text: json } else { render toJson([results: [:]]) } } private Map multiValuedParameters() { Map multiValuedParams = [:] if (params.derivedPartStatusId) { multiValuedParams.derivedPartStatusId = params.list('derivedPartStatusId') } if (params.categoryId) { multiValuedParams.categoryId = params.list('categoryId') } if (params.tagId) { multiValuedParams.tagId = params.list('tagId') } if (params.productTagId) { multiValuedParams.productTagId = params.list('productTagId') } if (params.brandId) { multiValuedParams.brandId = params.list('brandId') } multiValuedParams } private Map activeVendor() { Map criteria = [:] if (params.activeVendorId) { criteria.vendorId = params.activeVendorId } criteria } private void goliveDateRange(GenericSearchCommand cmd, String goliveDateRange) { JSONObject json = new JSONObject(goliveDateRange) try { cmd.goliveStartDate = Instant.parse(json.getString('start')).atZone(ZoneId.systemDefault()).toLocalDate() cmd.goliveEndDate = Instant.parse(json.getString('end')).atZone(ZoneId.systemDefault()).toLocalDate() } catch (Exception e) { cmd.goliveStartDate = json.getString('start') cmd.goliveEndDate = json.getString('end') } } private void hiddenDateParser(GenericSearchCommand cmd, String hiddenDateRange) { JSONObject json = new JSONObject(hiddenDateRange) try { cmd.hiddenStartDate = Instant.parse(json.getString('start')).atZone(ZoneId.systemDefault()).toLocalDate() cmd.hiddenEndDate= Instant.parse(json.getString('end')).atZone(ZoneId.systemDefault()).toLocalDate() } catch (Exception e) { cmd.hiddenStartDate = json.getString('start') cmd.hiddenEndDate = json.getString('end') } } private void renewalDateRange(GenericSearchCommand cmd, String renewalDateRange) { JSONObject json = new JSONObject(renewalDateRange) try { cmd.renewalStartDate = Instant.parse(json.getString('start')).atZone(ZoneId.systemDefault()).toLocalDate() cmd.renewalEndDate = Instant.parse(json.getString('end')).atZone(ZoneId.systemDefault()).toLocalDate() } catch (Exception e) { cmd.renewalStartDate = json.getString('start') cmd.renewalEndDate = json.getString('end') } } }