source: trunk/grails-app/services/InventoryItemService.groovy @ 548

Last change on this file since 548 was 548, checked in by gav, 9 years ago

Add InventoryItemService savePicture().
Add bulk tests for inventory items.

File size: 11.4 KB
Line 
1/**
2* Provides a service class for the InventoryItem domain class.
3*/
4class InventoryItemService {
5
6    boolean transactional = false
7
8    /**
9    * Prepare a sorted list of possible alternateItems.
10    */
11    def getPossibleAlternateItems(inventoryItemInstance) {
12        def criteria = inventoryItemInstance.createCriteria()
13        def possibleAlternateItems = criteria {
14            and {
15                eq('isActive', true)
16                notEqual('id', inventoryItemInstance.id)
17            }
18        }.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
19    }
20
21    /**
22    * Prepare the data for the show view.
23    * The result can be used to easily construct the model for the show view.
24    * @param params The incoming params as normally passed to the show view
25    * primarily including the id of the inventoryItem.
26    * @returns A map containing result.error, if any error, otherwise result.inventoryItemInstance.
27    */
28    def show(params) {
29        def result = [:]
30
31        def fail = { Map m ->
32            result.error = [ code: m.code, args: ["InventoryItem", params.id] ]
33            return result
34        }
35
36        result.inventoryItemInstance = InventoryItem.get( params.id )
37
38        if(!result.inventoryItemInstance)
39            return fail(code:"default.not.found")
40
41        def p = [:]
42
43        if(params.paginate == "purchases") {
44            params.showTab = "showPurchasingTab"
45            p.max = Math.min(params.max?.toInteger() ?: 10, 100)
46            p.offset = params.offset?.toInteger() ?: 0
47            p.sort = params.sort ?: null
48            p.order = params.order ?: null
49        }
50        else {
51            p.max = 10
52            p.offset = 0
53        }
54
55        result.inventoryItemPurchasesTotal = InventoryItemPurchase.countByInventoryItem(result.inventoryItemInstance)
56
57        result.inventoryItemPurchases = InventoryItemPurchase.withCriteria {
58                eq("inventoryItem", result.inventoryItemInstance)
59                maxResults(p.max)
60                firstResult(p.offset)
61                // Sorting:
62                // Default is to sort by order number then id.
63                // When a sortable column is clicked then we sort by that.
64                // If the sortable column clicked is order number then we add id as the second sort.
65                if(p.sort && p.order) {
66                    order(p.sort, p.order)
67                    if(p.sort == "purchaseOrderNumber") order('id', 'asc')
68                }
69                else {
70                    order('purchaseOrderNumber', 'desc')
71                    order('id', 'asc')
72                }
73            }
74
75        result.showTab = [:]
76        switch (params.showTab) {
77            case "showDetailTab":
78                result.showTab.detail =  new String("true")
79                break
80            case "showMovementTab":
81                result.showTab.movement =  new String("true")
82                break
83            case "showPurchasingTab":
84                result.showTab.purchasing =  new String("true")
85                break
86            default:
87                result.showTab.inventory = new String("true")
88        }
89
90        p.max = result.inventoryMovementListMax = 10
91        p.offset = 0
92        p.order = "desc"
93        p.sort = "id"
94        result.inventoryMovementList = InventoryMovement.findAllByInventoryItem(result.inventoryItemInstance, p)
95        result.inventoryMovementListTotal = InventoryMovement.countByInventoryItem(result.inventoryItemInstance)
96
97
98        // Success.
99        return result
100
101    } // end show()
102
103    def delete(params) {
104        InventoryItem.withTransaction { status ->
105            def result = [:]
106
107            def fail = { Map m ->
108                status.setRollbackOnly()
109                if(result.inventoryItemInstance && m.field)
110                    result.inventoryItemInstance.errors.rejectValue(m.field, m.code)
111                result.error = [ code: m.code, args: ["InventoryItem", params.id] ]
112                return result
113            }
114
115            result.inventoryItemInstance = InventoryItem.get(params.id)
116
117            if(!result.inventoryItemInstance)
118                return fail(code:"default.not.found")
119
120            if(result.inventoryItemInstance.inventoryMovements)
121                return fail(code:"inventoryMovement.still.associated")
122
123            result.inventoryItemInstance.removeReverseAlternateItems()
124
125            try {
126                result.inventoryItemInstance.delete(flush:true)
127                return result //Success.
128            }
129            catch(org.springframework.dao.DataIntegrityViolationException e) {
130                return fail(code:"default.delete.failure")
131            }
132
133        } //end withTransaction
134    } // end delete()
135
136    def edit(params) {
137        def result = [:]
138        def fail = { Map m ->
139            result.error = [ code: m.code, args: ["InventoryItem", params.id] ]
140            return result
141        }
142
143        result.inventoryItemInstance = InventoryItem.get(params.id)
144
145        if(!result.inventoryItemInstance)
146            return fail(code:"default.not.found")
147
148        // Success.
149        return result
150    }
151
152    def update(params) {
153        InventoryItem.withTransaction { status ->
154            def result = [:]
155
156            def fail = { Map m ->
157                status.setRollbackOnly()
158                if(result.inventoryItemInstance && m.field)
159                    result.inventoryItemInstance.errors.rejectValue(m.field, m.code)
160                result.error = [ code: m.code, args: ["InventoryItem", params.id] ]
161                return result
162            }
163
164            result.inventoryItemInstance = InventoryItem.get(params.id)
165
166            if(!result.inventoryItemInstance)
167                return fail(code:"default.not.found")
168
169            // Optimistic locking check.
170            if(params.version) {
171                if(result.inventoryItemInstance.version > params.version.toLong())
172                    return fail(field:"version", code:"default.optimistic.locking.failure")
173            }
174
175            def previousAlternateItems = new ArrayList(result.inventoryItemInstance.alternateItems)
176
177            result.inventoryItemInstance.properties = params
178
179            if(result.inventoryItemInstance.hasErrors() || !result.inventoryItemInstance.save())
180                return fail(code:"default.update.failure")
181
182            result.inventoryItemInstance.removeReverseAlternateItems(previousAlternateItems)
183            result.inventoryItemInstance.addReverseAlternateItems()
184
185            // Success.
186            return result
187
188        } //end withTransaction
189    }  // end update()
190
191    def create(params) {
192        def result = [:]
193        def fail = { Map m ->
194            result.error = [ code: m.code, args: ["InventoryItem", params.id] ]
195            return result
196        }
197
198        result.inventoryItemInstance = new InventoryItem()
199        result.inventoryItemInstance.properties = params
200
201        // success
202        return result
203    }
204
205    def save(params) {
206        InventoryItem.withTransaction { status ->
207            def result = [:]
208
209            def fail = { Map m ->
210                status.setRollbackOnly()
211                if(result.inventoryItemInstance && m.field)
212                    result.inventoryItemInstance.errors.rejectValue(m.field, m.code)
213                result.error = [ code: m.code, args: ["InventoryItem", params.id] ]
214                return result
215            }
216
217            result.inventoryItemInstance = new InventoryItem(params)
218
219            if(result.inventoryItemInstance.hasErrors() || !result.inventoryItemInstance.save())
220                return fail(code:"default.create.failure")
221
222            // success
223            return result
224
225        } //end withTransaction
226    }
227
228    /**
229    * Save an inventory item picture.
230    * @param pictureSource A supported source to get the picture image from.
231    * Supported sources:
232    * HttpServletRequest e.g: 'request' var from controller to run getFile('file') against.
233    * ServletContextResource e.g: grailsApplication.mainContext.getResource('images/logo.png')
234    */
235    def savePicture(params, pictureSource) {
236        InventoryItem.withTransaction { status ->
237            def result = [:]
238
239            def kByteMultiplier = 1000
240
241            def fail = { Map m ->
242                status.setRollbackOnly()
243                if(result.inventoryItemInstance && m.field)
244                    result.inventoryItemInstance.errors.rejectValue(m.field, m.code)
245                result.error = [ code: m.code, args: m.args ?: ["InventoryItem", params.id] ]
246                return result
247            }
248
249            result.inventoryItemInstance = InventoryItem.get(params.id)
250
251            if(!result.inventoryItemInstance)
252                return fail(code:"default.not.found")
253
254            // Optimistic locking check.
255            if(params.version) {
256                if(result.inventoryItemInstance.version > params.version.toLong())
257                    return fail(field:"version", code:"default.optimistic.locking.failure")
258            }
259
260            if(result.inventoryItemInstance.picture)
261                return fail(field:"picture", code:"inventory.item.already.has.picture")
262
263            def picture = new Picture(inventoryItem: result.inventoryItemInstance)
264            def imaging = new Imaging()
265            def images = null
266            def pictureFile
267            def pictureFileName = ''
268            def pictureInputStream
269
270            if(pictureSource instanceof javax.servlet.http.HttpServletRequest) {
271                def multiPartFile = pictureSource.getFile('file')
272                pictureFileName = multiPartFile.originalFilename
273
274                if(!multiPartFile || multiPartFile.isEmpty())
275                    return fail(code: "default.file.not.supplied")
276
277                if (multiPartFile.getSize() > Image.MAX_SIZE)
278                    return fail(code: "default.file.over.max.size", args: [Image.MAX_SIZE/kByteMultiplier, "kB"])
279
280                pictureInputStream = multiPartFile.inputStream
281            }
282            else if(pictureSource instanceof org.springframework.web.context.support.ServletContextResource) {
283                pictureFile = pictureSource.getFile()
284                pictureFileName = pictureFile.name
285
286                if ( !pictureFile.isFile() || (pictureFile.length() == 0) )
287                    return fail(code:"default.file.not.supplied")
288
289                if (pictureFile.length() > Image.MAX_SIZE)
290                    return fail(code:"default.file.over.max.size", args: [Image.MAX_SIZE/kByteMultiplier, "kB"])
291
292                pictureInputStream = pictureSource.inputStream
293            }
294            else {
295                    return fail(code:"default.file.not.supplied")
296            }
297
298            try {
299                images = imaging.createAll(result.inventoryItemInstance, picture, pictureInputStream)
300            }
301            catch(Exception ex) {
302                log.error("picture save", ex)
303                return fail(code:"inventory.item.picture.file.unrecognised", args: [pictureFileName])
304            }
305
306            images.each { image ->
307                picture.addToImages(image)
308            }
309
310            if(picture.hasErrors() || !picture.save())
311                return fail(code:"default.create.failure", args: ["Picture"])
312
313            result.inventoryItemInstance.picture = picture
314
315            if(result.inventoryItemInstance.hasErrors() || !result.inventoryItemInstance.save())
316                return fail(code:"default.create.failure")
317
318            // success
319            return result
320
321        } //end withTransaction
322    }
323
324} // end class
Note: See TracBrowser for help on using the repository browser.