source: trunk/grails-app/controllers/InventoryItemDetailedController.groovy @ 546

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

Add inventoryGroup to inventory search view and export.

File size: 18.3 KB
RevLine 
[116]1import org.codehaus.groovy.grails.plugins.springsecurity.Secured
[392]2import org.codehaus.groovy.grails.commons.ConfigurationHolder
[485]3import com.zeddware.grails.plugins.filterpane.FilterUtils
4import org.springframework.web.servlet.support.RequestContextUtils as RCU
[116]5
[298]6@Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager'])
[116]7class InventoryItemDetailedController extends BaseController {
[156]8
9    def filterService
[392]10    def exportService
[423]11    def inventoryCsvService
[225]12    def inventoryItemService
[485]13    def inventoryItemSearchService
[225]14    def inventoryMovementService
[156]15
[116]16    // the delete, save and update actions only accept POST requests
[225]17    static allowedMethods = [delete:'POST', save:'POST', update:'POST', useInventoryItem:'POST']
[116]18
[298]19    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager', 'ROLE_InventoryUser'])
20    def index = { redirect(action:search, params:params) }
21
[392]22    /**
23    * Set session.inventoryItemSearchParamsMax
24    */
[298]25    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager', 'ROLE_InventoryUser'])
[392]26    def setSearchParamsMax = {
27        def max = 1000
28        if(params.newMax.isInteger()) {
29            def i = params.newMax.toInteger()
30            if(i > 0 && i <= max)
31                session.inventoryItemSearchParamsMax = params.newMax
32            if(i > max)
33                session.inventoryItemSearchParamsMax = max
34        }
35        forward(action: 'search', params: params)
36    }
37
[423]38    /**
[441]39    * Display the import view.
[423]40    */
41    def importInventory = {
42    }
43
44    /**
45    * Handle the import save.
46    */
47    def importInventorySave = {
48        def result = inventoryCsvService.importInventory(request)
49
50        if(!result.error) {
51            flash.message = g.message(code: "inventory.import.success")
52            redirect(action:search)
53            return
54        }
55
56        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
57        redirect(action: importInventory)
58    }
59
60    /**
61    * Export a csv template.
62    * NOTE: IE has a 'validating' bug in dev mode that causes the export to take a long time!
63    * This does not appear to be a problem once deployed to Tomcat.
64    */
[392]65    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager', 'ROLE_InventoryUser'])
[423]66    def exportInventoryTemplate = {
67        response.contentType = ConfigurationHolder.config.grails.mime.types["csv"]
68        response.setHeader("Content-disposition", "attachment; filename=InventoryTemplate.csv")
69        def s = inventoryCsvService.buildInventoryTemplate()
70        render s
71    }
72
73    /**
74    * Export a csv test file.
75    */
76    def exportInventoryExample = {
77        response.contentType = ConfigurationHolder.config.grails.mime.types["csv"]
78        response.setHeader("Content-disposition", "attachment; filename=InventoryExample.csv")
79        def s = inventoryCsvService.buildInventoryExample()
80        render s
81    }
82
83    /**
84    * Export the entire inventory as a csv file.
85    */
86    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager', 'ROLE_InventoryUser'])
87    def exportInventory = {
88
89        def inventoryItemList = InventoryItem.list()
90
91        response.contentType = ConfigurationHolder.config.grails.mime.types["csv"]
92        response.setHeader("Content-disposition", "attachment; filename=Inventory.csv")
93        def s = inventoryCsvService.buildInventory(inventoryItemList)
94        render s
95    }
96
[441]97    /**
98    * Display the import view for purchases.
99    */
100    def importInventoryItemPurchases = {
101    }
102
103    /**
104    * Handle the inventory purchases import save.
105    */
106    def importInventoryItemPurchasesSave = {
107        def result = inventoryCsvService.importInventoryItemPurchases(request)
108
109        if(!result.error) {
110            flash.message = g.message(code: "inventory.import.success")
111            redirect(action:search)
112            return
113        }
114
115        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
116        redirect(action: importInventoryItemPurchases)
117    }
118
[485]119    /**
120    * Search for Inventory items.
121    */
[423]122    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager', 'ROLE_InventoryUser'])
[139]123    def search = {
[392]124
125        if(session.inventoryItemSearchParamsMax)
126            params.max = session.inventoryItemSearchParamsMax
127
[485]128        // Protect filterPane.
129        params.max = Math.min( params.max ? params.max.toInteger() : 10,  1000)
[156]130
[392]131        def inventoryItemInstanceList = []
132        def inventoryItemInstanceTotal
[485]133        def filterParams = com.zeddware.grails.plugins.filterpane.FilterUtils.extractFilterParams(params)
134        def isFilterApplied = FilterUtils.isFilterApplied(params)
[392]135
[485]136        // Restore search unless a new search is being requested.
137        if(!params.quickSearch && !filterParams) {
[489]138            if(session.inventoryItemQuickSearch) {
[485]139                params.quickSearch = session.inventoryItemQuickSearch
[489]140                if(session.inventoryItemQuickSearchDaysBack)
141                    params.daysBack = session.inventoryItemQuickSearchDaysBack.toString()
142            }
[485]143            else if(session.inventoryItemSearchFilterParams) {
144                session.inventoryItemSearchFilterParams.each() { params[it.key] = it.value }
145                params.filter = session.inventoryItemSearchFilter
146                isFilterApplied = FilterUtils.isFilterApplied(params)
147            }
[156]148        }
[485]149
150        // Remember sort if supplied, otherwise try to restore.
151        if(params.sort && params.order) {
152             session.inventoryItemSearchSort = params.sort
153             session.inventoryItemSearchOrder = params.order
154        }
155        else if(session.inventoryItemSearchSort && session.inventoryItemSearchOrder) {
156            params.sort = session.inventoryItemSearchSort
157            params.order = session.inventoryItemSearchOrder
158        }
159
160        if(isFilterApplied) {
161            // filterPane:
[392]162            inventoryItemInstanceList = filterService.filter( params, InventoryItem )
163            inventoryItemInstanceTotal = filterService.count( params, InventoryItem )
164            filterParams = com.zeddware.grails.plugins.filterpane.FilterUtils.extractFilterParams(params)
[485]165            // Remember search.
166            session.inventoryItemSearchFilterParams = new LinkedHashMap(filterParams)
167            session.inventoryItemSearchFilter = new LinkedHashMap(params.filter)
[489]168            session.removeAttribute("inventoryItemQuickSearch")
169            session.removeAttribute("inventoryItemQuickSearchDaysBack")
[392]170        }
[485]171        else {
172            // Quick Search:
173            if(!params.quickSearch) params.quickSearch = "all"
174            def result = inventoryItemSearchService.getQuickSearch(params, RCU.getLocale(request))
175            inventoryItemInstanceList = result.inventoryItemList
176            inventoryItemInstanceTotal = result.inventoryItemList.totalCount
177            params.message = result.message
178            filterParams.quickSearch = result.quickSearch
179            // Remember search.
[489]180            session.removeAttribute("inventoryItemSearchFilterParams")
181            session.removeAttribute("inventoryItemSearchFilter")
[485]182            session.inventoryItemQuickSearch = result.quickSearch
[489]183            if(result.daysBack)
184                session.inventoryItemQuickSearchDaysBack = result.daysBack
[485]185        }
[139]186
[392]187        // export plugin:
188        if(params?.format && params.format != "html") {
189
190            def dateFmt = { date ->
191                formatDate(format: "EEE, dd-MMM-yyyy", date: date)
192            }
193
[485]194            String title
195            if(params.quickSearch)
196                title = params.message
197            else
198                title = "Filtered Inventory List."
199
[392]200            response.contentType = ConfigurationHolder.config.grails.mime.types[params.format]
201            response.setHeader("Content-disposition", "attachment; filename=Inventory.${params.extension}")
202            List fields = ["name",
203                                "description",
[507]204                                "inventoryGroup",
[392]205                                "unitsInStock",
[485]206                                "reorderPoint",
[392]207                                "unitOfMeasure",
208                                "inventoryLocation",
209                                "inventoryLocation.inventoryStore"]
210            Map labels = ["name": "Name",
211                                "description": "Description",
[507]212                                "inventoryGroup": "Group",
[392]213                                "unitsInStock":"In Stock",
[485]214                                "reorderPoint":"Reorder Point",
[392]215                                "unitOfMeasure": "UOM",
216                                "inventoryLocation": "Location",
217                                "inventoryLocation.inventoryStore": "Store"]
218
219            Map formatters = [:]
220            Map parameters = [title: title, separator: ","]
221
222            exportService.export(params.format,
223                                                response.outputStream,
224                                                inventoryItemInstanceList.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) },
225                                                fields,
226                                                labels,
227                                                formatters,
228                                                parameters)
229        }
230
231        // Add some basic params to filterParams.
232        filterParams.max = params.max
233        filterParams.offset = params.offset?.toInteger() ?: 0
[485]234        filterParams.sort = params.sort ?: "name"
235        filterParams.order = params.order ?: "asc"
[392]236
237        return[ inventoryItemInstanceList: inventoryItemInstanceList,
238                inventoryItemInstanceTotal: inventoryItemInstanceTotal,
[485]239                filterParams: filterParams,
240                params: params ]
[392]241    } // end search()
242
[225]243    /**
244    * Simply assigns a passed in task id to a session variable and redirects to search.
245    */
[298]246    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager', 'ROLE_InventoryUser'])
[225]247    def findInventoryItemForMovement = {
248        if(!params.task?.id) {
249            flash.message = "No task id supplied, please select a task then the inventory tab."
250            redirect(controller: "taskDetailed", action: "search")
251            return
252        }
253
254        session.inventoryMovementTaskId = params.task.id
255        flash.message = "Please find and then select the inventory item."
256        redirect(action: search)
257    }
258
[298]259    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager', 'ROLE_InventoryUser'])
[116]260    def show = {
[225]261
[139]262        // In the case of an actionSubmit button, rewrite action name from 'index'.
263        if(params._action_Show)
[375]264            params.action='show'
[116]265
[405]266        def result = inventoryItemService.show(params)
[225]267
[405]268        if(!result.error) {
[225]269
[405]270            def model = [ inventoryItemInstance: result.inventoryItemInstance,
271                                    inventoryMovementList: result.inventoryMovementList,
272                                    inventoryMovementListTotal: result.inventoryMovementListTotal,
273                                    inventoryMovementListMax: result.inventoryMovementListMax,
[441]274                                    inventoryItemPurchases: result.inventoryItemPurchases,
275                                    inventoryItemPurchasesTotal: result.inventoryItemPurchasesTotal,
[405]276                                    showTab: result.showTab]
[225]277
[405]278            if(session.inventoryMovementTaskId) {
279                model.inventoryMovementInstance = new InventoryMovement()
280                model.inventoryMovementInstance.task = Task.get(session.inventoryMovementTaskId)
281                model.inventoryMovementInstance.quantity = 1
282            }
[225]283
[405]284            // Success.
285            return model
[225]286        }
287
[405]288        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
289        redirect(action:search)
[116]290    }
291
292    def delete = {
[405]293        def result = inventoryItemService.delete(params)
294
295        if(!result.error) {
296            flash.message = g.message(code: "default.delete.success", args: ["InventoryItem", params.id])
[408]297            redirect(action:search)
[405]298            return
[116]299        }
[405]300
301        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
302
303        if(result.error.code == "default.not.found") {
[139]304            redirect(action:search)
[405]305            return
[116]306        }
[405]307
308        redirect(action:show, id: params.id)
[116]309    }
310
311    def edit = {
[375]312
[139]313        // In the case of an actionSubmit button, rewrite action name from 'index'.
314        if(params._action_Edit)
[375]315            params.action='edit'
316
[405]317        def result = inventoryItemService.edit(params)
[116]318
[425]319        if(!result.error) {
320            def possibleAlternateItems = inventoryItemService.getPossibleAlternateItems(result.inventoryItemInstance)
[435]321            def suppliers = Supplier.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
322            def manufacturers = Manufacturer.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
323
324            return [ inventoryItemInstance : result.inventoryItemInstance,
325                            possibleAlternateItems: possibleAlternateItems,
326                            suppliers: suppliers,
327                            manufacturers: manufacturers]
[425]328        }
[405]329
330        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
331        redirect(action:search)
[116]332    }
333
334    def update = {
[405]335        def result = inventoryItemService.update(params)
336
337        if(!result.error) {
338            flash.message = g.message(code: "default.update.success", args: ["InventoryItem", params.id])
339            redirect(action:show, id: params.id)
340            return
[116]341        }
[405]342
343        if(result.error.code == "default.not.found") {
344            flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
[175]345            redirect(action:search)
[405]346            return
[116]347        }
[405]348
[425]349        def possibleAlternateItems = inventoryItemService.getPossibleAlternateItems(result.inventoryItemInstance)
[435]350        def suppliers = Supplier.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
351        def manufacturers = Manufacturer.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
352        render(view:'edit', model:[inventoryItemInstance: result.inventoryItemInstance.attach(),
353                                                possibleAlternateItems: possibleAlternateItems,
354                                                suppliers: suppliers,
355                                                manufacturers: manufacturers])
[116]356    }
357
358    def create = {
[405]359        def result = inventoryItemService.create(params)
[435]360        def suppliers = Supplier.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
361        def manufacturers = Manufacturer.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
[405]362
363        if(!result.error)
[435]364            return [inventoryItemInstance: result.inventoryItemInstance,
365                            suppliers: suppliers,
366                            manufacturers: manufacturers]
[405]367
368        //flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
369        redirect(action: search)
[116]370    }
371
372    def save = {
[405]373        def result = inventoryItemService.save(params)
374
375        if(!result.error) {
376            flash.message = g.message(code: "default.create.success", args: ["InventoryItem", result.inventoryItemInstance.id])
377            redirect(action:show, id: result.inventoryItemInstance.id)
378            return
[116]379        }
[405]380
[435]381        def suppliers = Supplier.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
382        def manufacturers = Manufacturer.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
383
[405]384        //flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
[435]385        render(view:'create', model:[inventoryItemInstance: result.inventoryItemInstance,
386                                                    suppliers: suppliers,
387                                                    manufacturers: manufacturers])
[116]388    }
[225]389
390    /**
391    * Handles the use inventory item form submit in the show view.
392    */
[298]393    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager', 'ROLE_InventoryUser'])
[225]394    def useInventoryItem = {
395
[226]396        params.inventoryMovementType = InventoryMovementType.get(1) // Set type to "Used".
[225]397        def result = inventoryMovementService.move(params)
398
399        if(!result.error) {
400            flash.message = "Inventory Movement for ${result.inventoryMovementInstance.inventoryItem.name.encodeAsHTML()} created."
[453]401            session.inventoryMovementTaskId = null
402            redirect(controller: "taskDetailed",
403                            action: "show",
404                            id: result.taskId,
405                            params: [showTab: "showInventoryTab"])
406            // Success.
407            return
[225]408        }
409
[453]410        // Prepare data for the show view.
411        def p = [:]
412        p.id = result.inventoryMovementInstance.inventoryItem?.id
413        def r = inventoryItemService.show(p)
[225]414
[453]415        // Render show view if data was successfully prepared.
416        if(!r.error) {
417            def model = [ inventoryItemInstance: r.inventoryItemInstance,
418                                    inventoryMovementList: r.inventoryMovementList,
419                                    inventoryMovementListTotal: r.inventoryMovementListTotal,
420                                    inventoryMovementListMax: r.inventoryMovementListMax,
421                                    inventoryItemPurchases: r.inventoryItemPurchases,
422                                    inventoryItemPurchasesTotal: r.inventoryItemPurchasesTotal,
423                                    showTab: r.showTab]
[225]424
[453]425            model.inventoryMovementInstance = result.inventoryMovementInstance // This will pass in the errors.
[225]426
[453]427            render(view: 'show', model: model)
428            return
[225]429        }
[453]430
431        // Could not prepare data for show view so doing the next best thing.
432        flash.errorMessage = g.message(code: r.error.code, args: r.error.args)
433        redirect(action:search)
434
435    } // useInventoryItem
436
437    /**
438    * Clear the use inventory item form in the show view.
439    * Accomplished by clearing the session variable and ajax.
440    */
441    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager', 'ROLE_InventoryUser'])
442    def clearUseInventoryItem = {
443            session.inventoryMovementTaskId = null
444            render ''
[225]445    }
446
[453]447} // end of class
Note: See TracBrowser for help on using the repository browser.