source: trunk/grails-app/services/InventoryItemSearchService.groovy @ 562

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

Install searchable plugin, configure and start inventory search.

File size: 9.1 KB
Line 
1import grails.orm.PagedResultList
2import org.compass.core.engine.SearchEngineQueryParseException
3
4/**
5* Service class that encapsulates the business logic for InventoryItem searches.
6*/
7class InventoryItemSearchService {
8
9    boolean transactional = false
10
11    def dateUtilService
12    def messageSource
13
14    def paramsMax = 100000
15
16    /**
17    * Selects and returns the correct search results based on the supplied quickSearch.
18    * @param params The request params, may contain params.quickSearch string to specify the search.
19    * @param locale The locale to use when generating result.message.
20    */
21    def getQuickSearch(params, locale) {
22        def result = [:]
23        result.quickSearch = params.quickSearch ?: "all"
24
25        def getMessage = { Map m ->
26            messageSource.getMessage(m.code, m.args == null ? null : m.args.toArray(), locale)
27        }
28
29        switch (result.quickSearch) {
30            case "inventoryBelowReorder":
31                result.inventoryItemList = getInventoryBelowReorder(params)
32                if(result.inventoryItemList.totalCount > 0)
33                    result.message = getMessage(code:"inventoryItem.search.text.below.reorder.description")
34                else
35                    result.message = getMessage(code:"inventoryItem.search.text.below.reorder.none.found")
36                break
37            case "inventoryBelowReorderAll":
38                result.inventoryItemList = getInventoryBelowReorder(params, false)
39                if(result.inventoryItemList.totalCount > 0)
40                    result.message = getMessage(code:"inventoryItem.search.text.below.reorder.all.description")
41                else
42                    result.message = getMessage(code:"inventoryItem.search.text.below.reorder.none.found")
43                break
44            case "recentlyUsed":
45                result.daysBack = params.daysBack?.isInteger() ? params.daysBack.toInteger() : 14
46                result.inventoryItemList = getRecentlyUsed(params, result.daysBack)
47                if(result.inventoryItemList.totalCount > 0)
48                    result.message = getMessage(code:"inventoryItem.search.text.recently.used.description", args:[result.daysBack])
49                else
50                    result.message = getMessage(code:"inventoryItem.search.text.recently.used.none.found", args:[result.daysBack])
51                break
52            default:
53                result.inventoryItemList = getAll(params)
54                if(result.inventoryItemList.totalCount > 0)
55                    result.message = getMessage(code:"inventoryItem.search.text.all.description")
56                else
57                    result.message = getMessage(code:"inventoryItem.search.text.all.none.found")
58                break
59        } // switch.
60
61        // Success.
62        return result
63
64    } // getQuickSearch
65
66    /**
67    * Get all inventory items.
68    * @param params The request params.
69    */
70    def getAll(params) {
71        params.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
72        params.offset = params?.offset?.toInteger() ?: 0
73        params.sort = params?.sort ?: "name"
74        params.order = params?.order ?: "asc"
75
76        def inventoryItemList = InventoryItem.createCriteria().list(
77            max: params.max,
78            offset: params.offset,
79            sort: params.sort,
80            order: params.order) {
81            } // createCriteria
82    } // getAll
83
84    /**
85    * List inventory items that are below reorder point.
86    * @param params The request params.
87    * @param onlyReorderEnabled Only include items with reorder enabled, defaults to true.
88    */
89    def getInventoryBelowReorder(params, onlyReorderEnabled=true) {
90        params.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
91        params.offset = params?.offset?.toInteger() ?: 0
92        params.sort = params?.sort ?: "name"
93        params.order = params?.order ?: "asc"
94
95        def inventoryItemList = InventoryItem.createCriteria().list(
96            max: params.max,
97            offset: params.offset,
98            sort: params.sort,
99            order: params.order) {
100                eq("isActive", true)
101                if(onlyReorderEnabled)
102                    eq("enableReorder", true)
103                leProperty("unitsInStock", "reorderPoint")
104            } // createCriteria
105    } // getInventoryBelowReorder
106
107    /**
108    * Get a list of recently used inventory items.
109    * @param params The request params.
110    * @param daysBack The number of days back to get results for.
111    */
112    def getRecentlyUsed(params, daysBack) {
113        def paginateParams = [:]
114        paginateParams.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
115        paginateParams.offset = params?.offset?.toInteger() ?: 0
116
117        def sort = "inventoryItem." + (params?.sort ?: "name")
118        def order = params?.order == "desc" ? "desc" : "asc"
119        def orderBy = " order by " + sort + ' ' + order
120
121        def namedParams = [:]
122        namedParams.startOfDay = dateUtilService.today - daysBack
123
124        def baseQuery = "from InventoryItem as inventoryItem \
125                                        left join inventoryItem.inventoryMovements as inventoryMovement \
126                                        where (inventoryItem.isActive = true \
127                                                    and inventoryMovement.date > :startOfDay \
128                                                    and inventoryMovement.inventoryMovementType = 1 \
129                                                    )"
130
131        def searchQuery = "select distinct inventoryItem " + baseQuery + orderBy
132        def list = InventoryItem.executeQuery(searchQuery, namedParams, paginateParams)
133
134        def countQuery = "select count(distinct inventoryItem) as inventoryItemCount " + baseQuery
135        def totalCount = InventoryItem.executeQuery(countQuery, namedParams)[0].toInteger()
136
137        def inventoryItemInstanceList = new PagedResultList(list, totalCount)
138        return inventoryItemInstanceList
139    } // getRecentlyUsed
140
141    /**
142    * Get a list of inventory items by search text.
143    * @param params The request params.
144    * @param locale The locale to use when generating result.message.
145    */
146    def getTextSearch(params, locale) {
147        def result = [:]
148        result.searchText = params.searchText.trim() ?: ""
149
150        def getMessage = { Map m ->
151            messageSource.getMessage(m.code, m.args == null ? null : m.args.toArray(), locale)
152        }
153
154        params.max = Math.min(params?.max?.toInteger() ?: 10, paramsMax)
155        params.offset = params?.offset?.toInteger() ?: 0
156        params.sort = params?.sort ?: "id"
157        params.order = params?.order ?: "asc"
158
159        // Build searchableParams.
160        // Do not include params.sort, since not all properites are indexed.
161        def searchableParams = [max: params.max, offset: params.offset,
162                                                    reload: true, defaultOperator: 'or']
163
164        // Perform the searchable query.
165        try {
166            result.inventoryItemList = InventoryItem.search(result.searchText, searchableParams)
167        } catch (e) {
168            log.error e
169            result.inventoryItemList = [:]
170            result.inventoryItemList.results = []
171            result.inventoryItemList.total = 0
172        }
173
174        // Sort the returned instances.
175        if(params.sort != 'id') {
176            if(params.order == 'asc') {
177                if(params.sort == 'name' || params.sort == 'description')
178                    result.inventoryItemList.results.sort { p1, p2 -> p1[params.sort].compareToIgnoreCase(p2[params.sort]) }
179                else if(params.sort == 'inventoryGroup') {
180                    result.inventoryItemList.results.sort { p1, p2 ->
181                        p1.inventoryGroup.name.compareToIgnoreCase(p2.inventoryGroup.name)
182                    }
183                }
184                else if(params.sort == 'unitsInStock')
185                    result.inventoryItemList.results.sort {p1, p2 -> p1[params.sort]  <=> p2[params.sort] }
186            } // asc.
187            else {
188                if(params.sort == 'name' || params.sort == 'description')
189                    result.inventoryItemList.results.sort { p1, p2 -> p2[params.sort].compareToIgnoreCase(p1[params.sort]) }
190                else if(params.sort == 'inventoryGroup') {
191                    result.inventoryItemList.results.sort { p1, p2 ->
192                        p2.inventoryGroup.name.compareToIgnoreCase(p1.inventoryGroup.name)
193                    }
194                }
195                else if(params.sort == 'unitsInStock')
196                    result.inventoryItemList.results.sort {p1, p2 -> p2[params.sort] <=> p1[params.sort]}
197            } // desc.
198        } // sort.
199
200        // Create a PagedResultList.
201        result.inventoryItemList = new PagedResultList(result.inventoryItemList.results, result.inventoryItemList.total)
202
203        // Get the result message.
204        if(result.inventoryItemList.totalCount > 0)
205            result.message = getMessage(code:"inventoryItem.search.text.found", args: [result.searchText])
206        else
207            result.message = getMessage(code:"inventoryItem.search.text.none.found", args: [result.searchText])
208
209        // Success.
210        return result
211
212    } // getTextSearch()
213
214} // end class
Note: See TracBrowser for help on using the repository browser.