Index: trunk/grails-app/services/TaskReportService.groovy
===================================================================
--- trunk/grails-app/services/TaskReportService.groovy	(revision 533)
+++ trunk/grails-app/services/TaskReportService.groovy	(revision 533)
@@ -0,0 +1,106 @@
+import grails.orm.PagedResultList
+
+/**
+* Service class that encapsulates the business logic for Task searches.
+*/
+class TaskReportService {
+
+    boolean transactional = false
+
+    def authService
+    def dateUtilService
+//     def messageSource
+
+//     def g = new org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib()
+
+    def paramsMax = 100000
+
+    /**
+    * Selects and returns the reactive ratio.
+    * @param params The request params, may contain param to specify the search.
+    * @param locale The locale to use when generating result.message.
+    */
+    def getReactiveRatio(params, locale) {
+        def result = [:]
+
+        def currentUser = authService.currentUser
+        def startOfToday = dateUtilService.today
+        def startOfYesterday = dateUtilService.yesterday
+        def startOfTomorrow = dateUtilService.tomorrow
+        def oneWeekAgo = dateUtilService.oneWeekAgo
+
+        def paginateParams = [:]
+        paginateParams.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
+        paginateParams.offset = params?.offset?.toInteger() ?: 0
+
+        def sort = "task." + (params?.sort ?: "targetStartDate")
+        def order = params?.order == "desc" ? "desc" : "asc"
+        def orderBy = " order by " + sort + ' ' + order
+
+        def namedParams = [:]
+        namedParams.startDate = params.startDate ?: dateUtilService.today
+        namedParams.endDate = params.endDate ?: dateUtilService.tomorrow
+        namedParams.immediateCallout = TaskType.read(1)
+        namedParams.unscheduledBreakin = TaskType.read(2)
+        namedParams.preventativeMaintenance = TaskType.read(4)
+
+        result.taskQuery = "from Task as task \
+                                        where (task.trash = false \
+                                                    and task.targetStartDate < :endDate \
+                                                    and task.targetStartDate >= :startDate \
+                                                    and ( \
+                                                        task.taskType = :immediateCallout \
+                                                        or task.taskType = :unscheduledBreakin \
+                                                        or task.taskType = :preventativeMaintenance \
+                                                    ) \
+                                        )"
+
+        result.taskQuery = "select distinct task " + result.taskQuery + orderBy
+        result.taskList = Task.executeQuery(result.taskQuery, namedParams, paginateParams)
+        result.taskCount = result.taskList.size()
+
+        // Counts
+        result.totalTaskOnAssetCount = 0
+        result.immediateCalloutCount = 0
+        result.unscheduledBreakinCount = 0
+        result.preventativeMaintenanceCount = 0
+
+        // Count the tasks performed against assets.
+        result.taskList.each() { task ->
+            if(task.primaryAsset) {
+                result.totalTaskOnAssetCount++
+                if(task.taskType == namedParams.immediateCallout) result.immediateCalloutCount++
+                if(task.taskType == namedParams.unscheduledBreakin) result.unscheduledBreakinCount++
+                if(task.taskType == namedParams.preventativeMaintenance) result.preventativeMaintenanceCount++
+            }
+            task.associatedAssets.each() { associatedAsset ->
+                if(associatedAsset.id != task.primaryAsset?.id) {
+                    result.totalTaskOnAssetCount++
+                    if(task.taskType == namedParams.immediateCallout) result.immediateCalloutCount++
+                    if(task.taskType == namedParams.unscheduledBreakin) result.unscheduledBreakinCount++
+                    if(task.taskType == namedParams.preventativeMaintenance) result.preventativeMaintenanceCount++
+                }
+            }
+        } // each() task
+
+        // Percentages
+        result.immediateCalloutPercentage = 0
+        result.totalPreventativePercentage = 0
+
+        result.totalPreventativeCount = result.unscheduledBreakinCount + result.preventativeMaintenanceCount
+        try {
+            result.immediateCalloutPercentage = (result.immediateCalloutCount / result.totalTaskOnAssetCount)*100
+            result.immediateCalloutPercentage = result.immediateCalloutPercentage.toInteger()
+            result.totalPreventativePercentage = (result.totalPreventativeCount / result.totalTaskOnAssetCount)*100
+            result.totalPreventativePercentage = result.totalPreventativePercentage.toInteger()
+        }
+        catch(ArithmeticException e) {
+        }
+
+        // Success.
+        return result
+
+    } // getQuickSearch
+
+
+} // end class
