/** * Service class that encapsulates the business logic for Inventory Reports. */ class InventoryReportService { boolean transactional = false // def authService // def dateUtilService // def messageSource def g = new org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib() def paramsMax = 250 /** * Get the data for the inventory stock take overiew report. * @param params The request params, may contain params to specify the search. * @param locale The locale to use when generating result.message. */ def getStockTakeOverview(params, locale) { def result = [:] result.summaryOfCalculationMethod = 'This report should be used in conjunction with the `Stock Take (By Location)` Report.' def namedParams = [:] result.query = "from InventoryLocation as inventoryLocation \ left join inventoryLocation.inventoryStore as inventoryStore \ where (inventoryLocation.isActive = true \ ) \ order by inventoryStore.name, inventoryLocation.name" result.query = "select new Map(inventoryLocation.name as location, inventoryStore.name as store) " + result.query result.queryResult = InventoryLocation.executeQuery(result.query, namedParams) result.inventoryLocationCount = result.queryResult.size() result.inventoryLocationList = result.queryResult // Success. return result } // getStockTakeOverview() /** * Get the data for the inventory stock take by location report. * @param params The request params, may contain params to specify the search. * @param locale The locale to use when generating result.message. */ def getStockTakeByLocation(params, locale) { def result = [:] result.summaryOfCalculationMethod = 'This report should be used in conjunction with the `Stock Take (Overview)` Report.' // Sanitise the locations string and convert to a list. result.locations = params.locationString.trim() if(result.locations.startsWith('e.g:')) result.locations = result.locations.split(':')[-1].trim() result.locations = result.locations.split(',') result.locations = result.locations.collect {it.trim()} def paginateParams = [:] paginateParams.max = Math.min(params?.max?.toInteger() ?: paramsMax, paramsMax) def namedParams = [:] namedParams.locationList = [null] // null protects against HQL unexpected end of subtree exception with an empty list. // Fill namedParams.locationList result.locations.each() { InventoryLocation.findAllByNameIlike(it).each() { namedParams.locationList << it } } // Return the actual locations as a string. if(namedParams.locationList.size() > 1) result.locations = namedParams.locationList[1..-1].toString()[1..-2] else result.locations = g.message(code: 'default.none.text') // Inventory List. result.inventoryListQuery = "from InventoryItem as inventoryItem \ left join inventoryItem.inventoryLocation as inventoryLocation \ where (inventoryItem.isActive = true \ and inventoryItem.inventoryLocation in (:locationList) \ ) " result.inventoryCountQuery = "select count(distinct inventoryItem) " + result.inventoryListQuery result.inventoryItemCount = InventoryItem.executeQuery(result.inventoryCountQuery, namedParams)[0] // Exit if too many results. result.countWarning = null if(result.inventoryItemCount > paramsMax) { result.countWarning = g.message(code: 'report.too.many.results.warning', args: [paramsMax], default: "Warning over ${paramsMax} results, please run report again!") result.inventoryItemList = [] return result } result.inventoryListQuery = "select distinct inventoryItem " + result.inventoryListQuery def inventoryList = InventoryItem.executeQuery(result.inventoryListQuery, namedParams, paginateParams) // Reset namedParams for next query. namedParams = [:] namedParams.inventoryList = inventoryList // Note: HQL docs advise not using fetch aliases in where clause (or any other clause). // Access is via the parent object, however that does not work for the order by clause in this case. result.query = "from InventoryItem as inventoryItem \ left join fetch inventoryItem.unitOfMeasure as unitOfMeasure \ left join fetch inventoryItem.inventoryLocation as inventoryLocation \ left join fetch inventoryLocation.inventoryStore as inventoryStore \ left join fetch inventoryItem.picture as picture \ left join fetch picture.images as Image \ where (inventoryItem in (:inventoryList) \ ) \ order by inventoryStore.name, inventoryLocation.name" result.query = "select inventoryItem " + result.query result.inventoryItemList = InventoryItem.executeQuery(result.query, namedParams, paginateParams) // Success. return result } // getStockTakeOverview() } // end class