source: trunk/grails-app/services/InventoryReportService.groovy @ 547

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

Improvements to Inventory Stock Take reports, MSSQL does not like using distinct the way it was, also improved protection against too many results.

File size: 5.9 KB
Line 
1
2/**
3* Service class that encapsulates the business logic for Inventory Reports.
4*/
5class InventoryReportService {
6
7    boolean transactional = false
8
9//     def authService
10//     def dateUtilService
11//     def messageSource
12
13    def g = new org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib()
14
15    def paramsMax = 250
16
17    /**
18    * Get the data for the inventory stock take overiew report.
19    * @param params The request params, may contain params to specify the search.
20    * @param locale The locale to use when generating result.message.
21    */
22    def getStockTakeOverview(params, locale) {
23        def result = [:]
24
25        result.summaryOfCalculationMethod = 'This report should be used in conjunction with the `Stock Take (By Location)` Report.'
26
27        def namedParams = [:]
28
29        result.query = "from InventoryLocation as inventoryLocation \
30                                        left join inventoryLocation.inventoryStore as inventoryStore \
31                                        where (inventoryLocation.isActive = true \
32                                                    ) \
33                                        order by inventoryStore.name, inventoryLocation.name"
34
35        result.query = "select new Map(inventoryLocation.name as location, inventoryStore.name as store) " + result.query
36        result.queryResult = InventoryLocation.executeQuery(result.query, namedParams)
37        result.inventoryLocationCount = result.queryResult.size()
38
39        result.inventoryLocationList = result.queryResult
40
41        // Success.
42        return result
43
44    } // getStockTakeOverview()
45
46    /**
47    * Get the data for the inventory stock take by location report.
48    * @param params The request params, may contain params to specify the search.
49    * @param locale The locale to use when generating result.message.
50    */
51    def getStockTakeByLocation(params, locale) {
52        def result = [:]
53
54        result.summaryOfCalculationMethod = 'This report should be used in conjunction with the `Stock Take (Overview)` Report.'
55
56        // Sanitise the locations string and convert to a list.
57        result.locations = params.locationString.trim()
58        if(result.locations.startsWith('e.g:'))
59            result.locations = result.locations.split(':')[-1].trim()
60        result.locations = result.locations.split(',')
61        result.locations = result.locations.collect {it.trim()}
62
63        def paginateParams = [:]
64        paginateParams.max = Math.min(params?.max?.toInteger() ?: paramsMax, paramsMax)
65
66        def namedParams = [:]
67        namedParams.locationList = [null] // null protects against HQL unexpected end of subtree exception with an empty list.
68
69        // Fill namedParams.locationList
70        result.locations.each() {
71            InventoryLocation.findAllByNameIlike(it).each() {
72                namedParams.locationList << it
73            }
74        }
75
76        // Return the actual locations as a string.
77        if(namedParams.locationList.size() > 1)
78            result.locations = namedParams.locationList[1..-1].toString()[1..-2]
79        else
80            result.locations = g.message(code: 'default.none.text')
81
82        // Inventory List.
83        result.inventoryListQuery = "from InventoryItem as inventoryItem \
84                                                        left join inventoryItem.inventoryLocation as inventoryLocation \
85                                                        where (inventoryItem.isActive = true \
86                                                                    and  inventoryItem.inventoryLocation in (:locationList) \
87                                                                    ) "
88
89        result.inventoryCountQuery = "select count(distinct inventoryItem) " + result.inventoryListQuery
90        result.inventoryItemCount = InventoryItem.executeQuery(result.inventoryCountQuery, namedParams)[0]
91
92        // Exit if too many results.
93        result.countWarning = null
94        if(result.inventoryItemCount > paramsMax) {
95            result.countWarning = g.message(code: 'report.too.many.results.warning',
96                                                                    args: [paramsMax],
97                                                                    default: "Warning over ${paramsMax} results, please run report again!")
98            result.inventoryItemList = []
99            return result
100        }
101
102        result.inventoryListQuery = "select distinct inventoryItem " + result.inventoryListQuery
103        def inventoryList = InventoryItem.executeQuery(result.inventoryListQuery, namedParams, paginateParams)
104
105        // Reset namedParams for next query.
106        namedParams = [:]
107        namedParams.inventoryList = inventoryList
108
109        // Note: HQL docs advise not using fetch aliases in where clause (or any other clause).
110        // Access is via the parent object, however that does not work for the order by clause in this case.
111        result.query = "from InventoryItem as inventoryItem \
112                                        left join fetch inventoryItem.unitOfMeasure as unitOfMeasure \
113                                        left join fetch inventoryItem.inventoryLocation as inventoryLocation \
114                                        left join fetch inventoryLocation.inventoryStore as inventoryStore \
115                                        left join fetch inventoryItem.picture as picture \
116                                        left join fetch picture.images as Image \
117                                        where (inventoryItem in (:inventoryList) \
118                                                    ) \
119                                        order by inventoryStore.name, inventoryLocation.name"
120
121        result.query = "select inventoryItem " + result.query
122        result.inventoryItemList = InventoryItem.executeQuery(result.query, namedParams, paginateParams)
123
124        // Success.
125        return result
126
127    } // getStockTakeOverview()
128
129} // end class
Note: See TracBrowser for help on using the repository browser.