source: trunk/grails-app/services/TaskSearchService.groovy @ 524

Last change on this file since 524 was 524, checked in by gav, 14 years ago

Refactor TaskSearchServicve getBudgetTasks() to use HQL.

File size: 18.3 KB
RevLine 
[479]1import grails.orm.PagedResultList
2
[476]3/**
4* Service class that encapsulates the business logic for Task searches.
5*/
[143]6class TaskSearchService {
7
8    boolean transactional = false
9
[476]10    def authService
[143]11    def dateUtilService
[476]12    def messageSource
[143]13
[490]14    def g = new org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib()
15
[476]16    def paramsMax = 100000
[260]17
[476]18    /**
19    * Selects and returns the correct search results based on the supplied quickSearch.
20    * @param params The request params, may contain params.quickSearch string to specify the search.
21    * @param locale The locale to use when generating result.message.
22    */
23    def getQuickSearch(params, locale) {
24        def result = [:]
[503]25        result.quickSearch = params.quickSearch ?: "plannersRange"
26
[476]27        def currentUser = authService.currentUser
[503]28        def startOfToday = dateUtilService.today
29        def startOfYesterday = dateUtilService.yesterday
30        def startOfTomorrow = dateUtilService.tomorrow
31        def oneWeekAgo = dateUtilService.oneWeekAgo
[476]32
[503]33        def formattedStartOfToday = g.formatDate(format: "EEE, dd-MMM-yyyy", date: startOfToday)
34        def formattedStartOfYesterday = g.formatDate(format: "EEE, dd-MMM-yyyy", date: startOfYesterday)
35        def formattedStartOfTomorrow = g.formatDate(format: "EEE, dd-MMM-yyyy", date: startOfTomorrow)
36        def formattedOneWeekAgo = g.formatDate(format: "EEE, dd-MMM-yyyy", date: oneWeekAgo)
37
[476]38        def getMessage = { Map m ->
39            messageSource.getMessage(m.code, m.args == null ? null : m.args.toArray(), locale)
40        }
41
42        switch (result.quickSearch) {
43            case "myTodays":
[503]44                result.taskInstanceList = getPersonsTasks(params)
[476]45                if(result.taskInstanceList.totalCount > 0)
[503]46                    result.message = getMessage(code:"task.search.text.persons.tasks.message",
47                                                                    args:[currentUser, formattedStartOfToday])
[476]48                else
[503]49                    result.message = getMessage(code:"task.search.text.persons.tasks.none.found",
50                                                                    args:[currentUser, formattedStartOfToday])
[476]51                break
52            case "myYesterdays":
[503]53                result.taskInstanceList = getPersonsTasks(params, currentUser, startOfYesterday, startOfToday)
[476]54                if(result.taskInstanceList.totalCount > 0)
[503]55                    result.message = getMessage(code:"task.search.text.persons.tasks.message",
56                                                                    args:[currentUser, formattedStartOfYesterday])
[476]57                else
[503]58                    result.message = getMessage(code:"task.search.text.persons.tasks.none.found",
59                                                                    args:[currentUser, formattedStartOfYesterday])
[476]60                break
61            case "myTomorrows":
[503]62                result.taskInstanceList = getPersonsTasks(params, currentUser, startOfTomorrow, startOfTomorrow+1)
[476]63                if(result.taskInstanceList.totalCount > 0)
[503]64                    result.message = getMessage(code:"task.search.text.persons.tasks.message",
65                                                                    args:[currentUser, formattedStartOfTomorrow])
[476]66                else
[503]67                    result.message = getMessage(code:"task.search.text.persons.tasks.none.found",
68                                                                    args:[currentUser, formattedStartOfTomorrow])
[476]69                break
70            case "myPastWeek":
[503]71                result.taskInstanceList = getPersonsTasks(params, currentUser, oneWeekAgo, startOfTomorrow)
[476]72                if(result.taskInstanceList.totalCount > 0)
[503]73                    result.message = getMessage(code:"task.search.text.persons.tasks.between.message",
74                                                                    args:[currentUser, formattedOneWeekAgo, formattedStartOfToday])
[476]75                else
[503]76                    result.message = getMessage(code:"task.search.text.persons.tasks.between.none.found",
77                                                                    args:[currentUser, formattedOneWeekAgo, formattedStartOfToday])
[476]78                break
79            case "todays":
[503]80                result.taskInstanceList = getTasks(params)
[476]81                if(result.taskInstanceList.totalCount > 0)
[503]82                    result.message = getMessage(code:"task.search.text.all.tasks.message",
83                                                                    args:[formattedStartOfToday])
[476]84                else
[503]85                    result.message = getMessage(code:"task.search.text.all.tasks.none.found",
86                                                                    args:[formattedStartOfToday])
[476]87                break
88            case "yesterdays":
[503]89                result.taskInstanceList = getTasks(params, startOfYesterday, startOfToday)
[476]90                if(result.taskInstanceList.totalCount > 0)
[503]91                    result.message = getMessage(code:"task.search.text.all.tasks.message",
92                                                                    args:[formattedStartOfYesterday])
[476]93                else
[503]94                    result.message = getMessage(code:"task.search.text.all.tasks.none.found",
95                                                                    args:[formattedStartOfYesterday])
[476]96                break
97            case "tomorrows":
[503]98                result.taskInstanceList = getTasks(params, startOfTomorrow, startOfTomorrow+1)
[476]99                if(result.taskInstanceList.totalCount > 0)
[503]100                    result.message = getMessage(code:"task.search.text.all.tasks.message",
101                                                                    args:[formattedStartOfTomorrow])
[476]102                else
[503]103                    result.message = getMessage(code:"task.search.text.all.tasks.none.found",
104                                                                    args:[formattedStartOfTomorrow])
[476]105                break
106            case "pastWeek":
[503]107                result.taskInstanceList = getTasks(params, oneWeekAgo, startOfTomorrow)
[476]108                if(result.taskInstanceList.totalCount > 0)
[503]109                    result.message = getMessage(code:"task.search.text.all.tasks.between.message",
110                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
[476]111                else
[503]112                    result.message = getMessage(code:"task.search.text.all.tasks.between.none.found",
113                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
[476]114                break
115            case "budgetUnplanned":
[503]116                result.taskInstanceList = getBudgetTasks(params, TaskBudgetStatus.read(1), oneWeekAgo, startOfTomorrow)
[476]117                if(result.taskInstanceList.totalCount > 0)
[503]118                    result.message = getMessage(code:"task.search.text.budget.unplanned.message",
119                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
[476]120                else
[503]121                    result.message = getMessage(code:"task.search.text.budget.unplanned.none.found",
122                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
[476]123                break
124            case "budgetPlanned":
[503]125                result.taskInstanceList = getBudgetTasks(params, TaskBudgetStatus.read(2), oneWeekAgo, startOfTomorrow)
[476]126                if(result.taskInstanceList.totalCount > 0)
[503]127                    result.message = getMessage(code:"task.search.text.budget.planned.message",
128                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
[476]129                else
[503]130                    result.message = getMessage(code:"task.search.text.budget.planned.none.found",
131                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
[476]132                break
133            default:
[503]134                //case "plannersRange":
135                result.taskInstanceList = getTasks(params, oneWeekAgo, startOfToday+15)
[476]136                if(result.taskInstanceList.totalCount > 0)
[503]137                    result.message = getMessage(code:"task.search.text.all.tasks.between.message",
138                                                                    args:[formattedOneWeekAgo,
139                                                                            g.formatDate(format: "EEE, dd-MMM-yyyy", date: startOfToday+14)])
[476]140                else
[503]141                    result.message = getMessage(code:"task.search.text.all.tasks.between.none.found",
142                                                                    args:[formattedOneWeekAgo,
143                                                                            g.formatDate(format: "EEE, dd-MMM-yyyy", date: startOfToday+14)])
[476]144                break
145        } // switch.
146
147        // Success.
148        return result
149
150    } // getQuickSearch
151
[479]152    /**
[503]153    * Get all tasks that are not in the trash bin, by default today's tasks.
[479]154    * @param params The request params.
[503]155    * @param startDate The start date to get tasks for, defaults to the start of today and is inclusive (greater than or equal to).
156    * @param endDate The end date to get tasks for, defaults to the start of tomorrow and is exclusive (less than).
[479]157    */
[503]158    def getTasks(params, startDate=null, endDate=null) {
[512]159        def paginateParams = [:]
160        paginateParams.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
161        paginateParams.offset = params?.offset?.toInteger() ?: 0
[143]162
[512]163        def sort = "task." + (params?.sort ?: "attentionFlag")
164        def order = params?.order == "asc" ? "asc" : "desc"
165        def orderBy = " order by " + sort + ' ' + order
[143]166
[512]167        def namedParams = [:]
168        namedParams.startDate = startDate ?: dateUtilService.today
169        namedParams.endDate = endDate ?: dateUtilService.tomorrow
[144]170
[512]171        def baseQuery = "from Task as task \
172                                        where (task.trash = false \
173                                                    and task.targetStartDate < :endDate \
174                                                    and task.targetCompletionDate >= :startDate \
175                                        )"
176
177        def searchQuery = "select distinct task " + baseQuery + orderBy
178        def list = Task.executeQuery(searchQuery, namedParams, paginateParams)
179
180        def countQuery = "select count(distinct task) as taskCount " + baseQuery
181        def totalCount = Task.executeQuery(countQuery, namedParams)[0].toInteger()
182
183        def taskInstanceList = new PagedResultList(list, totalCount)
184        return taskInstanceList
185    } // getPTasks()
186
[479]187    /**
[503]188    * Get a person's tasks, by default current user and today's tasks.
189    * "My tasks and approved tasks that I am assigned to"
[479]190    * @param params The request params.
[503]191    * @param person The person to get tasks for, defaults to current user.
192    * @param startDate The start date to get tasks for, defaults to the start of today and is inclusive (greater than or equal to).
193    * @param endDate The end date to get tasks for, defaults to the start of tomorrow and is exclusive (less than).
[479]194    */
[503]195    def getPersonsTasks(params, person=null, startDate=null, endDate=null) {
[479]196        def paginateParams = [:]
197        paginateParams.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
198        paginateParams.offset = params?.offset?.toInteger() ?: 0
[144]199
[479]200        def sort = "task." + (params?.sort ?: "attentionFlag")
201        def order = params?.order == "asc" ? "asc" : "desc"
202        def orderBy = " order by " + sort + ' ' + order
[476]203
[479]204        def namedParams = [:]
[503]205        namedParams.person = person ?: authService.currentUser
206        namedParams.startDate = startDate ?: dateUtilService.today
207        namedParams.endDate = endDate ?: dateUtilService.tomorrow
[165]208
[479]209        def baseQuery = "from Task as task \
210                                        left join task.assignedPersons as assignedPersonOfTask \
211                                        left join assignedPersonOfTask.person as assignedPerson \
212                                        left join task.assignedGroups as assignedGroupOfTask \
213                                        left join assignedGroupOfTask.personGroup as personGroup \
214                                        left join personGroup.persons as assignedPersonViaGroup \
[511]215                                        left join task.taskModifications as taskModification \
216                                        left join taskModification.person as createdBy \
217                                        left join taskModification.taskModificationType as taskModificationType \
[479]218                                        where (task.trash = false \
[511]219                                                    and task.targetStartDate < :endDate \
220                                                    and task.targetCompletionDate >= :startDate \
[479]221                                                    and ( \
[511]222                                                        (taskModificationType.id = 1 \
223                                                        and createdBy = :person \
224                                                        and task.leadPerson = :person) \
225                                                        or ( \
226                                                            task.approved = true \
227                                                            and ( \
228                                                                task.leadPerson = :person \
229                                                                or assignedPerson = :person \
230                                                                or assignedPersonViaGroup = :person \
231                                                            ) \
[479]232                                                        ) \
[511]233                                                    ) \
234                                        )"
[479]235
236        def searchQuery = "select distinct task " + baseQuery + orderBy
237        def list = Task.executeQuery(searchQuery, namedParams, paginateParams)
238
239        def countQuery = "select count(distinct task) as taskCount " + baseQuery
240        def totalCount = Task.executeQuery(countQuery, namedParams)[0].toInteger()
241
242        def taskInstanceList = new PagedResultList(list, totalCount)
243        return taskInstanceList
[503]244    } // getPersonsTasks()
[479]245
246    /**
[503]247    * Get tasks by budget status, by default planned in the last week.
[479]248    * @param params The request params.
[503]249    * @param budgetStatus Defaults to planned.
250    * @param startDate The start date to get tasks for, defaults to the start of today and is inclusive (greater than or equal to).
251    * @param endDate The end date to get tasks for, defaults to the start of tomorrow and is exclusive (less than).
[479]252    */
[503]253    def getBudgetTasks(params, budgetStatus=null, startDate=null, endDate=null) {
[524]254        def paginateParams = [:]
255        paginateParams.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
256        paginateParams.offset = params?.offset?.toInteger() ?: 0
[165]257
[524]258        def sort = "task." + (params?.sort ?: "targetStartDate")
259        def order = params?.order == "desc" ? "desc" : "asc"
260        def orderBy = " order by " + sort + ' ' + order
[165]261
[524]262        def namedParams = [:]
263        namedParams.budgetStatus = budgetStatus ?: TaskBudgetStatus.read(2) // Planned.
264        namedParams.startDate = startDate ?: dateUtilService.today
265        namedParams.endDate = endDate ?: dateUtilService.oneWeekAgo
266
267        def baseQuery = "from Task as task \
268                                        where (task.trash = false \
269                                                    and task.budgetStatus = :budgetStatus \
270                                                    and task.targetStartDate < :endDate \
271                                                    and task.targetCompletionDate >= :startDate \
272                                        )"
273
274        def searchQuery = "select distinct task " + baseQuery + orderBy
275        def list = Task.executeQuery(searchQuery, namedParams, paginateParams)
276
277        def countQuery = "select count(distinct task) as taskCount " + baseQuery
278        def totalCount = Task.executeQuery(countQuery, namedParams)[0].toInteger()
279
280        def taskInstanceList = new PagedResultList(list, totalCount)
281        return taskInstanceList
[503]282    } // getBudgetTasks()
[476]283
[479]284    /**
[490]285    * Get work done by person and date.
[503]286    * A person ID and date may be specified in params otherwise the current user and today are used.
[490]287    * @param params The request params.
288    * @returns A map containing entries, totalEntries, startOfDay, person, totalHours, totalMinutes.
289    */
290    def getWorkDone(params, locale) {
291        def result = [:]
292        result.person = params.person?.id ? Person.get(params.person.id.toInteger()) : authService.currentUser
293
294        if(params.date_year && params.date_month && params.date_day)
295            result.startOfDay = dateUtilService.makeDate(params.date_year, params.date_month, params.date_day)
296        else
297            result.startOfDay = dateUtilService.today
298
299        result.startOfNextDay = result.startOfDay + 1
300
301        def formattedStartOfDay = g.formatDate(format: "EEE, dd-MMM-yyyy", date: result.startOfDay)
302
303        def getMessage = { Map m ->
304            messageSource.getMessage(m.code, m.args == null ? null : m.args.toArray(), locale)
305        }
306
307        result.entries = Entry.createCriteria().list() {
308            eq("enteredBy", result.person)
309            ge("dateDone", result.startOfDay)
310            lt("dateDone", result.startOfNextDay)
311            entryType {
312                eq("id", 3L)
313            }
314        } // createCriteria
315
316        result.totalEntries = result.entries.size()
317
318        if(result.totalEntries > 0)
319            result.message = getMessage(code:"task.search.text.work.done.message",
320                                                                args:[result.person, formattedStartOfDay])
321        else
322            result.message = getMessage(code:"task.search.text.work.done.none.found",
323                                                                args:[result.person, formattedStartOfDay])
324
325        result.totalHours = 0
326        result.totalMinutes = 0
327        result.entries.each() {
328            result.totalMinutes += (it.durationHour*60) + it.durationMinute
329        }
330        result.totalHours = (result.totalMinutes / 60).toInteger()
331        result.totalMinutes = result.totalMinutes % 60
332
333        return result
[503]334    } // getWorkDone()
[490]335
336} // end class
Note: See TracBrowser for help on using the repository browser.