Ignore:
Timestamp:
Nov 22, 2010, 10:33:51 AM (13 years ago)
Author:
gav
Message:

Dynamic task quick search feature.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/services/TaskSearchService.groovy

    r701 r713  
     1import net.kromhouts.HqlBuilder
    12import grails.orm.PagedResultList
    23import org.hibernate.FetchMode as FM
     
    1617
    1718    def paramsMax = 100000
     19
     20    // Be sure to update taskQuickSearchPane.js if quickSearchSelection is changed.
     21    def getQuickSearchSelection() {
     22        [ 'allTasks': g.message(code: 'task.search.text.all.tasks'),
     23        'budgetPlanned': g.message(code: 'task.search.text.budget.planned'),
     24        'budgetUnplanned': g.message(code: 'task.search.text.budget.unplanned'),
     25        'personsImmediateCallouts': g.message(code: 'task.search.text.persons.immediate.callouts'),
     26        'personsTasks': g.message(code: 'task.search.text.persons.tasks')
     27        ]
     28    }
    1829
    1930    /**
     
    2233    * @param locale The locale to use when generating result.message.
    2334    */
    24     def getQuickSearch(params, locale) {
     35    def getQuickSearch(params = [:], locale) {
    2536        def result = [:]
    26         result.quickSearch = params.quickSearch ?: "plannersRange"
    27 
    28         def currentUser = authService.currentUser
     37        result.quickSearch = params.quickSearch ?: "personsTasks"
     38        if(params.person)
     39            result.person = Person.get(params.person.id.toLong())
     40        else
     41            result.person = authService.currentUser
     42        result.startDate = params.startDate ?: dateUtilService.today
     43        result.endDate = params.endDate ?: dateUtilService.today
     44        // Auto swap date range.
     45        if(result.startDate > result.endDate) {
     46            def tempStartDate = result.startDate
     47            result.startDate = result.endDate
     48            result.endDate = tempStartDate
     49        }
     50        result.includeCompleted = params.includeCompleted = params.includeCompleted ? true:false
     51
     52        def getMessage = { Map m ->
     53            messageSource.getMessage(m.code, m.args == null ? null : m.args.toArray(), locale)
     54        }
     55
     56        def formatted = { Date d ->
     57            g.formatDate(format: "EEE, dd-MMM-yyyy", date: d)
     58        }
     59
    2960        def startOfToday = dateUtilService.today
    3061        def startOfYesterday = dateUtilService.yesterday
     
    3263        def oneWeekAgo = dateUtilService.oneWeekAgo
    3364
    34         def formattedStartOfToday = g.formatDate(format: "EEE, dd-MMM-yyyy", date: startOfToday)
    35         def formattedStartOfYesterday = g.formatDate(format: "EEE, dd-MMM-yyyy", date: startOfYesterday)
    36         def formattedStartOfTomorrow = g.formatDate(format: "EEE, dd-MMM-yyyy", date: startOfTomorrow)
    37         def formattedOneWeekAgo = g.formatDate(format: "EEE, dd-MMM-yyyy", date: oneWeekAgo)
    38 
    39         def getMessage = { Map m ->
    40             messageSource.getMessage(m.code, m.args == null ? null : m.args.toArray(), locale)
     65        def formattedStartOfToday = formatted(startOfToday)
     66        def formattedStartOfYesterday = formatted(startOfYesterday)
     67        def formattedStartOfTomorrow = formatted(startOfTomorrow)
     68        def formattedOneWeekAgo = formatted(oneWeekAgo)
     69
     70        def allTasks = {
     71            result.taskInstanceList = getTasks(params, result.startDate, result.endDate+1)
     72            if(result.taskInstanceList.totalCount > 0) {
     73                if(result.startDate == result.endDate)
     74                    result.message = getMessage(code:"task.search.text.all.tasks.message",
     75                                                                    args:[ formatted(result.startDate) ])
     76                else
     77                    result.message = getMessage(code:"task.search.text.all.tasks.between.message",
     78                                                                    args:[ formatted(result.startDate), formatted(result.endDate) ])
     79            }
     80            else {
     81                if(result.startDate == result.endDate)
     82                    result.message = getMessage(code:"task.search.text.all.tasks.none.found",
     83                                                                    args:[ formatted(result.startDate) ])
     84                else
     85                    result.message = getMessage(code:"task.search.text.all.tasks.between.none.found",
     86                                                                    args:[ formatted(result.startDate), formatted(result.endDate) ])
     87            }
     88
     89        }
     90
     91        def personsTasks = {
     92            result.taskInstanceList = getPersonsTasks(params, result.person, result.startDate, result.endDate+1)
     93            if(result.taskInstanceList.totalCount > 0) {
     94                if(result.startDate == result.endDate)
     95                    result.message = getMessage(code:"task.search.text.persons.tasks.message",
     96                                                                    args:[ result.person, formatted(result.startDate) ])
     97                else
     98                    result.message = getMessage(code:"task.search.text.persons.tasks.between.message",
     99                                                                    args:[ result.person, formatted(result.startDate), formatted(result.endDate) ])
     100            }
     101            else {
     102                if(result.startDate == result.endDate)
     103                    result.message = getMessage(code:"task.search.text.persons.tasks.none.found",
     104                                                                    args:[ result.person, formatted(result.startDate) ])
     105                else
     106                    result.message = getMessage(code:"task.search.text.persons.tasks.between.none.found",
     107                                                                    args:[ result.person, formatted(result.startDate), formatted(result.endDate) ])
     108            }
     109
     110        }
     111
     112        def personsImmediateCallouts = {
     113            result.taskInstanceList = getPersonsImmediateCallouts(params, result.person, result.startDate, result.endDate+1)
     114            if(result.taskInstanceList.totalCount > 0) {
     115                if(result.startDate == result.endDate)
     116                    result.message = getMessage(code:"task.search.text.persons.immediate.callouts.message",
     117                                                                    args:[ result.person, formatted(result.startDate) ])
     118                else
     119                    result.message = getMessage(code:"task.search.text.persons.immediate.callouts.between.message",
     120                                                                    args:[ result.person, formatted(result.startDate), formatted(result.endDate) ])
     121            }
     122            else {
     123                if(result.startDate == result.endDate)
     124                    result.message = getMessage(code:"task.search.text.persons.immediate.callouts.none.found",
     125                                                                    args:[ result.person, formatted(result.startDate) ])
     126                else
     127                    result.message = getMessage(code:"task.search.text.persons.immediate.callouts.between.none.found",
     128                                                                    args:[ result.person, formatted(result.startDate), formatted(result.endDate) ])
     129            }
     130
    41131        }
    42132
    43133        switch (result.quickSearch) {
    44134            case "myTodays":
    45                 result.taskInstanceList = getPersonsTasks(params)
    46                 if(result.taskInstanceList.totalCount > 0)
    47                     result.message = getMessage(code:"task.search.text.persons.tasks.message",
    48                                                                     args:[currentUser, formattedStartOfToday])
    49                 else
    50                     result.message = getMessage(code:"task.search.text.persons.tasks.none.found",
    51                                                                     args:[currentUser, formattedStartOfToday])
     135                result.quickSearch = "personsTasks"
     136                result.startDate = startOfToday
     137                result.endDate = startOfToday
     138                personsTasks()
    52139                break
    53140            case "myYesterdays":
    54                 result.taskInstanceList = getPersonsTasks(params, currentUser, startOfYesterday, startOfToday)
    55                 if(result.taskInstanceList.totalCount > 0)
    56                     result.message = getMessage(code:"task.search.text.persons.tasks.message",
    57                                                                     args:[currentUser, formattedStartOfYesterday])
    58                 else
    59                     result.message = getMessage(code:"task.search.text.persons.tasks.none.found",
    60                                                                     args:[currentUser, formattedStartOfYesterday])
     141                result.quickSearch = "personsTasks"
     142                result.startDate = startOfYesterday
     143                result.endDate = startOfYesterday
     144                personsTasks()
    61145                break
    62146            case "myTomorrows":
    63                 result.taskInstanceList = getPersonsTasks(params, currentUser, startOfTomorrow, startOfTomorrow+1)
    64                 if(result.taskInstanceList.totalCount > 0)
    65                     result.message = getMessage(code:"task.search.text.persons.tasks.message",
    66                                                                     args:[currentUser, formattedStartOfTomorrow])
    67                 else
    68                     result.message = getMessage(code:"task.search.text.persons.tasks.none.found",
    69                                                                     args:[currentUser, formattedStartOfTomorrow])
     147                result.quickSearch = "personsTasks"
     148                result.startDate = startOfTomorrow
     149                result.endDate = startOfTomorrow
     150                personsTasks()
    70151                break
    71152            case "myPastWeek":
    72                 result.taskInstanceList = getPersonsTasks(params, currentUser, oneWeekAgo, startOfTomorrow)
    73                 if(result.taskInstanceList.totalCount > 0)
    74                     result.message = getMessage(code:"task.search.text.persons.tasks.between.message",
    75                                                                     args:[currentUser, formattedOneWeekAgo, formattedStartOfToday])
    76                 else
    77                     result.message = getMessage(code:"task.search.text.persons.tasks.between.none.found",
    78                                                                     args:[currentUser, formattedOneWeekAgo, formattedStartOfToday])
     153                result.quickSearch = "personsTasks"
     154                result.startDate = oneWeekAgo
     155                result.endDate = startOfToday
     156                personsTasks()
     157                break
     158            case "personsTasks":
     159                personsTasks()
     160                break
     161            case "personsImmediateCallouts":
     162                personsImmediateCallouts()
    79163                break
    80164            case "todays":
    81                 result.taskInstanceList = getTasks(params)
    82                 if(result.taskInstanceList.totalCount > 0)
    83                     result.message = getMessage(code:"task.search.text.all.tasks.message",
    84                                                                     args:[formattedStartOfToday])
    85                 else
    86                     result.message = getMessage(code:"task.search.text.all.tasks.none.found",
    87                                                                     args:[formattedStartOfToday])
     165                result.quickSearch = "allTasks"
     166                result.startDate = startOfToday
     167                result.endDate = startOfToday
     168                allTasks()
    88169                break
    89170            case "yesterdays":
    90                 result.taskInstanceList = getTasks(params, startOfYesterday, startOfToday)
    91                 if(result.taskInstanceList.totalCount > 0)
    92                     result.message = getMessage(code:"task.search.text.all.tasks.message",
    93                                                                     args:[formattedStartOfYesterday])
    94                 else
    95                     result.message = getMessage(code:"task.search.text.all.tasks.none.found",
    96                                                                     args:[formattedStartOfYesterday])
     171                result.quickSearch = "allTasks"
     172                result.startDate = startOfYesterday
     173                result.endDate = startOfToday
     174                allTasks()
    97175                break
    98176            case "tomorrows":
    99                 result.taskInstanceList = getTasks(params, startOfTomorrow, startOfTomorrow+1)
    100                 if(result.taskInstanceList.totalCount > 0)
    101                     result.message = getMessage(code:"task.search.text.all.tasks.message",
    102                                                                     args:[formattedStartOfTomorrow])
    103                 else
    104                     result.message = getMessage(code:"task.search.text.all.tasks.none.found",
    105                                                                     args:[formattedStartOfTomorrow])
     177                result.quickSearch = "allTasks"
     178                result.startDate = startOfTomorrow
     179                result.endDate = startOfTomorrow+1
     180                allTasks()
    106181                break
    107182            case "pastWeek":
    108                 result.taskInstanceList = getTasks(params, oneWeekAgo, startOfTomorrow)
    109                 if(result.taskInstanceList.totalCount > 0)
    110                     result.message = getMessage(code:"task.search.text.all.tasks.between.message",
    111                                                                     args:[formattedOneWeekAgo, formattedStartOfToday])
    112                 else
    113                     result.message = getMessage(code:"task.search.text.all.tasks.between.none.found",
    114                                                                     args:[formattedOneWeekAgo, formattedStartOfToday])
     183                result.quickSearch = "allTasks"
     184                result.startDate = oneWeekAgo
     185                result.endDate = startOfTomorrow
     186                allTasks()
     187                break
     188            case "allTasks":
     189                allTasks()
    115190                break
    116191            case "budgetUnplanned":
    117                 result.taskInstanceList = getBudgetTasks(params, TaskBudgetStatus.read(1), oneWeekAgo, startOfTomorrow)
    118                 if(result.taskInstanceList.totalCount > 0)
    119                     result.message = getMessage(code:"task.search.text.budget.unplanned.message",
    120                                                                     args:[formattedOneWeekAgo, formattedStartOfToday])
    121                 else
    122                     result.message = getMessage(code:"task.search.text.budget.unplanned.none.found",
    123                                                                     args:[formattedOneWeekAgo, formattedStartOfToday])
     192                result.taskInstanceList = getBudgetTasks(params, TaskBudgetStatus.read(1), result.startDate, result.endDate+1)
     193                if(result.taskInstanceList.totalCount > 0) {
     194                    if(result.startDate == result.endDate)
     195                        result.message = getMessage(code:"task.search.text.budget.unplanned.message",
     196                                                                        args:[ formatted(result.startDate) ])
     197                    else
     198                        result.message = getMessage(code:"task.search.text.budget.unplanned.between.message",
     199                                                                        args:[ formatted(result.startDate), formatted(result.endDate) ])
     200                }
     201                else {
     202                    if(result.startDate == result.endDate)
     203                        result.message = getMessage(code:"task.search.text.budget.unplanned.none.found",
     204                                                                        args:[ formatted(result.startDate) ])
     205                    else
     206                        result.message = getMessage(code:"task.search.text.budget.unplanned.between.none.found",
     207                                                                        args:[ formatted(result.startDate), formatted(result.endDate) ])
     208                }
    124209                break
    125210            case "budgetPlanned":
    126                 result.taskInstanceList = getBudgetTasks(params, TaskBudgetStatus.read(2), oneWeekAgo, startOfTomorrow)
    127                 if(result.taskInstanceList.totalCount > 0)
    128                     result.message = getMessage(code:"task.search.text.budget.planned.message",
    129                                                                     args:[formattedOneWeekAgo, formattedStartOfToday])
    130                 else
    131                     result.message = getMessage(code:"task.search.text.budget.planned.none.found",
    132                                                                     args:[formattedOneWeekAgo, formattedStartOfToday])
     211                result.taskInstanceList = getBudgetTasks(params, TaskBudgetStatus.read(2), result.startDate, result.endDate+1)
     212                if(result.taskInstanceList.totalCount > 0) {
     213                    if(result.startDate == result.endDate)
     214                        result.message = getMessage(code:"task.search.text.budget.planned.message",
     215                                                                        args:[ formatted(result.startDate) ])
     216                    else
     217                        result.message = getMessage(code:"task.search.text.budget.planned.between.message",
     218                                                                        args:[ formatted(result.startDate), formatted(result.endDate) ])
     219                }
     220                else {
     221                    if(result.startDate == result.endDate)
     222                        result.message = getMessage(code:"task.search.text.budget.planned.none.found",
     223                                                                        args:[ formatted(result.startDate) ])
     224                    else
     225                        result.message = getMessage(code:"task.search.text.budget.planned.between.none.found",
     226                                                                        args:[ formatted(result.startDate), formatted(result.endDate) ])
     227                }
    133228                break
    134229            default:
    135230                //case "plannersRange":
    136                 result.taskInstanceList = getTasks(params, oneWeekAgo, startOfToday+15)
    137                 if(result.taskInstanceList.totalCount > 0)
    138                     result.message = getMessage(code:"task.search.text.all.tasks.between.message",
    139                                                                     args:[formattedOneWeekAgo,
    140                                                                             g.formatDate(format: "EEE, dd-MMM-yyyy", date: startOfToday+14)])
    141                 else
    142                     result.message = getMessage(code:"task.search.text.all.tasks.between.none.found",
    143                                                                     args:[formattedOneWeekAgo,
    144                                                                             g.formatDate(format: "EEE, dd-MMM-yyyy", date: startOfToday+14)])
     231                result.quickSearch = "allTasks"
     232                result.startDate = oneWeekAgo
     233                result.endDate = startOfToday+15
     234                allTasks()
    145235                break
    146236        } // switch.
     
    202292    */
    203293    def getPersonsTasks(params, person=null, startDate=null, endDate=null) {
    204         def paginateParams = [:]
    205         paginateParams.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
    206         paginateParams.offset = params?.offset?.toInteger() ?: 0
     294
     295        def max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
     296        def offset = params?.offset?.toInteger() ?: 0
    207297
    208298        def orderBy = ''
     
    212302            def sort = "task." + params.sort
    213303            def order = (params.order == "asc") ? "asc" : "desc"
    214             orderBy = " order by " + sort + ' ' + order
    215         }
    216         else
    217             orderBy = " order by task.taskStatus, task.taskPriority, task.targetStartDate"
    218 
    219         def namedParams = [:]
    220         namedParams.person = person ?: authService.currentUser
    221         namedParams.startDate = startDate ?: dateUtilService.today
    222         namedParams.endDate = endDate ?: dateUtilService.tomorrow
    223 
    224         def baseQuery = "from Task as task \
    225                                         left join task.assignedPersons as assignedPersonOfTask \
    226                                         left join assignedPersonOfTask.person as assignedPerson \
    227                                         left join task.assignedGroups as assignedGroupOfTask \
    228                                         left join assignedGroupOfTask.personGroup as personGroup \
    229                                         left join personGroup.persons as assignedPersonViaGroup \
    230                                         left join task.taskModifications as taskModification \
    231                                         left join taskModification.person as createdBy \
    232                                         left join taskModification.taskModificationType as taskModificationType \
    233                                         where (task.trash = false \
    234                                                     and task.targetStartDate < :endDate \
    235                                                     and task.targetCompletionDate >= :startDate \
    236                                                     and ( \
    237                                                         (taskModificationType.id = 1 \
    238                                                         and createdBy = :person \
    239                                                         and task.leadPerson = :person) \
    240                                                         or ( \
    241                                                             task.approved = true \
    242                                                             and ( \
    243                                                                 task.leadPerson = :person \
    244                                                                 or assignedPerson = :person \
    245                                                                 or assignedPersonViaGroup = :person \
    246                                                             ) \
    247                                                         ) \
    248                                                     ) \
    249                                         )"
    250 
    251         def searchQuery = "select distinct task " + baseQuery + orderBy
    252         def list = Task.executeQuery(searchQuery, namedParams, paginateParams)
    253 
    254         def countQuery = "select count(distinct task) as taskCount " + baseQuery
    255         def totalCount = Task.executeQuery(countQuery, namedParams)[0].toInteger()
     304            orderBy = "by " + sort + ' ' + order
     305        }
     306        else
     307            orderBy = "by task.taskStatus, task.taskPriority, task.targetStartDate"
     308
     309        def q = new HqlBuilder().query {
     310
     311            select 'count(distinct task) as taskCount'
     312            from 'Task as task',
     313                    'left join task.assignedPersons as assignedPersonOfTask',
     314                    'left join assignedPersonOfTask.person as assignedPerson',
     315                    'left join task.assignedGroups as assignedGroupOfTask',
     316                    'left join assignedGroupOfTask.personGroup as personGroup',
     317                    'left join personGroup.persons as assignedPersonViaGroup',
     318                    'left join task.taskModifications as taskModification',
     319                    'left join taskModification.person as createdBy',
     320                    'left join taskModification.taskModificationType as taskModificationType'
     321            where 'task.trash = false'
     322                    and 'task.targetStartDate < :endDate'
     323                    and 'task.targetCompletionDate >= :startDate'
     324                    if(!params.includeCompleted) {
     325                        and 'task.taskStatus.id != 3' // Complete.
     326                    }
     327                    and {
     328                        where '(taskModificationType.id = 1 and createdBy = :person and task.leadPerson = :person)' // Created.
     329                        or '(task.approved = true and (task.leadPerson = :person or assignedPerson = :person or assignedPersonViaGroup = :person))'
     330                    }
     331        }
     332
     333        q.namedParams.person = person ?: authService.currentUser
     334        q.namedParams.startDate = startDate ?: dateUtilService.today
     335        q.namedParams.endDate = endDate ?: dateUtilService.tomorrow
     336
     337        def totalCount = Task.executeQuery(q.query, q.namedParams)[0].toInteger()
     338
     339        q.select = "distinct task"
     340        q.order = orderBy
     341        def list = Task.executeQuery(q.query, q.namedParams, q.paginateParams)
    256342
    257343        def taskInstanceList = new PagedResultList(list, totalCount)
    258344        return taskInstanceList
    259345    } // getPersonsTasks()
     346
     347    /**
     348    * Get a person's immediateCallout tasks, by default all users and today's tasks.
     349    * @param params The request params.
     350    * @param person The person to get tasks for, defaults to null and therefore all immediateCallouts.
     351    * @param startDate The start date to get tasks for, defaults to the start of today and is inclusive (greater than or equal to).
     352    * @param endDate The end date to get tasks for, defaults to the start of tomorrow and is exclusive (less than).
     353    */
     354    def getPersonsImmediateCallouts(params, person=null, startDate=null, endDate=null) {
     355
     356        def max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
     357        def offset = params?.offset?.toInteger() ?: 0
     358
     359        def orderBy = ''
     360        if(params.sort?.contains('.')) // protect against filterpane bug.
     361            params.sort = null
     362        if(params.sort && params.order) {
     363            def sort = "task." + params.sort
     364            def order = (params.order == "asc") ? "asc" : "desc"
     365            orderBy = "by " + sort + ' ' + order
     366        }
     367        else
     368            orderBy = "by task.taskStatus, task.taskPriority, task.targetStartDate"
     369
     370        def q = new HqlBuilder().query {
     371
     372            select 'count(distinct task) as taskCount'
     373            from 'Task as task',
     374                    'left join task.taskModifications as taskModification',
     375                    'left join taskModification.person as createdBy',
     376                    'left join taskModification.taskModificationType as taskModificationType'
     377            where 'task.taskType.id = 1' // Immediate Callout.
     378                    and 'task.targetStartDate < :endDate'
     379                    and 'task.targetCompletionDate >= :startDate'
     380                    if(!params.includeCompleted) {
     381                        and 'task.taskStatus.id != 3' // Complete.
     382                    }
     383                    if(person) {
     384                        namedParams.person = person
     385                        and '( (taskModificationType.id = 1 and createdBy = :person) or task.leadPerson = :person)' // Created or Lead Person.
     386                    }
     387                    and 'task.trash = false'
     388        }
     389
     390        q.namedParams.startDate = startDate ?: dateUtilService.today
     391        q.namedParams.endDate = endDate ?: dateUtilService.tomorrow
     392
     393        def totalCount = Task.executeQuery(q.query, q.namedParams)[0].toInteger()
     394
     395        q.select = "distinct task"
     396        q.order = orderBy
     397        def list = Task.executeQuery(q.query, q.namedParams, q.paginateParams)
     398
     399        def taskInstanceList = new PagedResultList(list, totalCount)
     400        return taskInstanceList
     401    } // getPersonsImmediateCallouts()
    260402
    261403    /**
Note: See TracChangeset for help on using the changeset viewer.