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

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

Tweak CreateDataService to prevent issues during testing.
Repair getBudgetTasks() search.
Complete testGetBudgetTasks() test.

File size: 18.4 KB
Line 
1import grails.orm.PagedResultList
2
3/**
4* Service class that encapsulates the business logic for Task searches.
5*/
6class TaskSearchService {
7
8    boolean transactional = false
9
10    def authService
11    def dateUtilService
12    def messageSource
13
14    def g = new org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib()
15
16    def paramsMax = 100000
17
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 = [:]
25        result.quickSearch = params.quickSearch ?: "plannersRange"
26
27        def currentUser = authService.currentUser
28        def startOfToday = dateUtilService.today
29        def startOfYesterday = dateUtilService.yesterday
30        def startOfTomorrow = dateUtilService.tomorrow
31        def oneWeekAgo = dateUtilService.oneWeekAgo
32
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
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":
44                result.taskInstanceList = getPersonsTasks(params)
45                if(result.taskInstanceList.totalCount > 0)
46                    result.message = getMessage(code:"task.search.text.persons.tasks.message",
47                                                                    args:[currentUser, formattedStartOfToday])
48                else
49                    result.message = getMessage(code:"task.search.text.persons.tasks.none.found",
50                                                                    args:[currentUser, formattedStartOfToday])
51                break
52            case "myYesterdays":
53                result.taskInstanceList = getPersonsTasks(params, currentUser, startOfYesterday, startOfToday)
54                if(result.taskInstanceList.totalCount > 0)
55                    result.message = getMessage(code:"task.search.text.persons.tasks.message",
56                                                                    args:[currentUser, formattedStartOfYesterday])
57                else
58                    result.message = getMessage(code:"task.search.text.persons.tasks.none.found",
59                                                                    args:[currentUser, formattedStartOfYesterday])
60                break
61            case "myTomorrows":
62                result.taskInstanceList = getPersonsTasks(params, currentUser, startOfTomorrow, startOfTomorrow+1)
63                if(result.taskInstanceList.totalCount > 0)
64                    result.message = getMessage(code:"task.search.text.persons.tasks.message",
65                                                                    args:[currentUser, formattedStartOfTomorrow])
66                else
67                    result.message = getMessage(code:"task.search.text.persons.tasks.none.found",
68                                                                    args:[currentUser, formattedStartOfTomorrow])
69                break
70            case "myPastWeek":
71                result.taskInstanceList = getPersonsTasks(params, currentUser, oneWeekAgo, startOfTomorrow)
72                if(result.taskInstanceList.totalCount > 0)
73                    result.message = getMessage(code:"task.search.text.persons.tasks.between.message",
74                                                                    args:[currentUser, formattedOneWeekAgo, formattedStartOfToday])
75                else
76                    result.message = getMessage(code:"task.search.text.persons.tasks.between.none.found",
77                                                                    args:[currentUser, formattedOneWeekAgo, formattedStartOfToday])
78                break
79            case "todays":
80                result.taskInstanceList = getTasks(params)
81                if(result.taskInstanceList.totalCount > 0)
82                    result.message = getMessage(code:"task.search.text.all.tasks.message",
83                                                                    args:[formattedStartOfToday])
84                else
85                    result.message = getMessage(code:"task.search.text.all.tasks.none.found",
86                                                                    args:[formattedStartOfToday])
87                break
88            case "yesterdays":
89                result.taskInstanceList = getTasks(params, startOfYesterday, startOfToday)
90                if(result.taskInstanceList.totalCount > 0)
91                    result.message = getMessage(code:"task.search.text.all.tasks.message",
92                                                                    args:[formattedStartOfYesterday])
93                else
94                    result.message = getMessage(code:"task.search.text.all.tasks.none.found",
95                                                                    args:[formattedStartOfYesterday])
96                break
97            case "tomorrows":
98                result.taskInstanceList = getTasks(params, startOfTomorrow, startOfTomorrow+1)
99                if(result.taskInstanceList.totalCount > 0)
100                    result.message = getMessage(code:"task.search.text.all.tasks.message",
101                                                                    args:[formattedStartOfTomorrow])
102                else
103                    result.message = getMessage(code:"task.search.text.all.tasks.none.found",
104                                                                    args:[formattedStartOfTomorrow])
105                break
106            case "pastWeek":
107                result.taskInstanceList = getTasks(params, oneWeekAgo, startOfTomorrow)
108                if(result.taskInstanceList.totalCount > 0)
109                    result.message = getMessage(code:"task.search.text.all.tasks.between.message",
110                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
111                else
112                    result.message = getMessage(code:"task.search.text.all.tasks.between.none.found",
113                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
114                break
115            case "budgetUnplanned":
116                result.taskInstanceList = getBudgetTasks(params, TaskBudgetStatus.read(1), oneWeekAgo, startOfTomorrow)
117                if(result.taskInstanceList.totalCount > 0)
118                    result.message = getMessage(code:"task.search.text.budget.unplanned.message",
119                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
120                else
121                    result.message = getMessage(code:"task.search.text.budget.unplanned.none.found",
122                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
123                break
124            case "budgetPlanned":
125                result.taskInstanceList = getBudgetTasks(params, TaskBudgetStatus.read(2), oneWeekAgo, startOfTomorrow)
126                if(result.taskInstanceList.totalCount > 0)
127                    result.message = getMessage(code:"task.search.text.budget.planned.message",
128                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
129                else
130                    result.message = getMessage(code:"task.search.text.budget.planned.none.found",
131                                                                    args:[formattedOneWeekAgo, formattedStartOfToday])
132                break
133            default:
134                //case "plannersRange":
135                result.taskInstanceList = getTasks(params, oneWeekAgo, startOfToday+15)
136                if(result.taskInstanceList.totalCount > 0)
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)])
140                else
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)])
144                break
145        } // switch.
146
147        // Success.
148        return result
149
150    } // getQuickSearch
151
152    /**
153    * Get all tasks that are not in the trash bin, by default today's tasks.
154    * @param params The request params.
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).
157    */
158    def getTasks(params, startDate=null, endDate=null) {
159        def paginateParams = [:]
160        paginateParams.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
161        paginateParams.offset = params?.offset?.toInteger() ?: 0
162
163        def sort = "task." + (params?.sort ?: "attentionFlag")
164        def order = params?.order == "asc" ? "asc" : "desc"
165        def orderBy = " order by " + sort + ' ' + order
166
167        def namedParams = [:]
168        namedParams.startDate = startDate ?: dateUtilService.today
169        namedParams.endDate = endDate ?: dateUtilService.tomorrow
170
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
187    /**
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"
190    * @param params The request params.
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).
194    */
195    def getPersonsTasks(params, person=null, startDate=null, endDate=null) {
196        def paginateParams = [:]
197        paginateParams.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
198        paginateParams.offset = params?.offset?.toInteger() ?: 0
199
200        def sort = "task." + (params?.sort ?: "attentionFlag")
201        def order = params?.order == "asc" ? "asc" : "desc"
202        def orderBy = " order by " + sort + ' ' + order
203
204        def namedParams = [:]
205        namedParams.person = person ?: authService.currentUser
206        namedParams.startDate = startDate ?: dateUtilService.today
207        namedParams.endDate = endDate ?: dateUtilService.tomorrow
208
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 \
215                                        left join task.taskModifications as taskModification \
216                                        left join taskModification.person as createdBy \
217                                        left join taskModification.taskModificationType as taskModificationType \
218                                        where (task.trash = false \
219                                                    and task.targetStartDate < :endDate \
220                                                    and task.targetCompletionDate >= :startDate \
221                                                    and ( \
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                                                            ) \
232                                                        ) \
233                                                    ) \
234                                        )"
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
244    } // getPersonsTasks()
245
246    /**
247    * Get tasks by budget status, by default planned in the last week.
248    * @param params The request params.
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).
252    */
253    def getBudgetTasks(params, taskBudgetStatus=null, startDate=null, endDate=null) {
254        def paginateParams = [:]
255        paginateParams.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
256        paginateParams.offset = params?.offset?.toInteger() ?: 0
257
258        def sort = "task." + (params?.sort ?: "targetStartDate")
259        def order = params?.order == "desc" ? "desc" : "asc"
260        def orderBy = " order by " + sort + ' ' + order
261
262        def namedParams = [:]
263        namedParams.taskBudgetStatus = taskBudgetStatus ?: TaskBudgetStatus.read(2) // Planned.
264        namedParams.startDate = startDate ?: dateUtilService.today
265        namedParams.endDate = endDate ?: dateUtilService.tomorrow
266
267        def baseQuery = "from Task as task \
268                                        where (task.trash = false \
269                                                    and task.taskBudgetStatus = :taskBudgetStatus \
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
282    } // getBudgetTasks()
283
284    /**
285    * Get work done by person and date.
286    * A person ID and date may be specified in params otherwise the current user and today are used.
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
334    } // getWorkDone()
335
336} // end class
Note: See TracBrowser for help on using the repository browser.