Index: trunk/grails-app/controllers/InventoryItemDetailedController.groovy
===================================================================
--- trunk/grails-app/controllers/InventoryItemDetailedController.groovy	(revision 635)
+++ trunk/grails-app/controllers/InventoryItemDetailedController.groovy	(revision 646)
@@ -34,4 +34,20 @@
         }
         forward(action: 'search', params: params)
+    }
+
+    /**
+    * Set session.inventoryItemReorderSearchParamsMax
+    */
+    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager', 'ROLE_InventoryUser'])
+    def setReorderSearchParamsMax = {
+        def max = 1000
+        if(params.newMax?.isInteger()) {
+            def i = params.newMax.toInteger()
+            if(i > 0 && i <= max)
+                session.inventoryItemReorderSearchParamsMax = params.newMax
+            if(i > max)
+                session.inventoryItemReorderSearchParamsMax = max
+        }
+        forward(action: 'reorder', params: params)
     }
 
@@ -542,3 +558,154 @@
     }
 
+    /**
+    * Search for Inventory items that require reorder.
+    */
+    @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager'])
+    def reorder = {
+
+        // In the case of an actionSubmit button, rewrite action name from 'index'.
+        if(params._action_reorder)
+            params.action='reorder'
+
+        if(session.inventoryItemReorderSearchParamsMax)
+            params.max = session.inventoryItemReorderSearchParamsMax
+
+        def inventoryItemInstanceList = []
+        def inventoryItemInstanceTotal
+        def filterParams = params
+        def suppliers = Supplier.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }
+        def inventoryGroups = InventoryGroup.findAllByIsActive(true)
+        if(!params.selectedGroups)
+            params.selectedGroups = inventoryGroups.collect{it.id}
+        else
+            params.selectedGroups = params.selectedGroups.collect { it.toLong() }
+
+        // Restore search unless a new search is being requested.
+        if(!params.newSearch && !params.quickSearch) {
+            if(session.reorderSearchSelectedGroups) {
+                params.selectedGroups = session.reorderSearchSelectedGroups
+                params.selectedSupplier = session.reorderSearchSelectedSupplier
+                params.includeAlternateSuppliers = session.reorderSearchIncludeAlternateSuppliers
+                params.includeReorderListingDisabled = session.reorderSearchIncludeReorderListingDisabled
+                params.includeOnBackOrder = session.reorderSearchIncludeOnBackOrder
+            }
+            else if(session.inventoryItemReorderQuickSearch) {
+                params.quickSearch = session.inventoryItemReorderQuickSearch
+                if(session.inventoryItemReorderQuickSearchDaysBack)
+                    params.daysBack = session.inventoryItemReorderQuickSearchDaysBack.toString()
+            }
+        }
+
+        // Remember sort if supplied, otherwise try to restore.
+        if(params.sort && params.order) {
+             session.inventoryItemReorderSearchSort = params.sort
+             session.inventoryItemReorderSearchOrder = params.order
+        }
+        else if(session.inventoryItemReorderSearchSort && session.inventoryItemReorderSearchOrder) {
+            params.sort = session.inventoryItemReorderSearchSort
+            params.order = session.inventoryItemReorderSearchOrder
+        }
+
+        if(params.quickSearch) {
+            // Quick Search Links:
+            if(!params.quickSearch) params.quickSearch = "inventoryBelowReorder"
+            def result = inventoryItemSearchService.getQuickSearch(params, RCU.getLocale(request))
+            inventoryItemInstanceList = result.inventoryItemList
+            inventoryItemInstanceTotal = result.inventoryItemList.totalCount
+            params.message = result.message
+            filterParams.quickSearch = result.quickSearch
+            // Remember search.
+            session.inventoryItemReorderQuickSearch = result.quickSearch
+            if(result.daysBack)
+                session.inventoryItemReorderQuickSearchDaysBack = result.daysBack
+            // Clear any previous search.
+            session.removeAttribute("reorderSearchSelectedGroups")
+            session.removeAttribute("reorderSearchSelectedSupplier")
+            session.removeAttribute("reorderSearchIncludeAlternateSuppliers")
+            session.removeAttribute("reorderSearchIncludeReorderListingDisabled")
+            session.removeAttribute("reorderSearchIncludeOnBackOrder")
+        }
+        else {
+            // Reorder Search:
+            def result = inventoryItemSearchService.getReorderSearch(params, RCU.getLocale(request))
+            inventoryItemInstanceList = result.inventoryItemList
+            inventoryItemInstanceTotal = result.inventoryItemList.totalCount
+            params.message = result.message
+            // Place limit search selects in filterParams for pagination.
+            if(params.selectedGroups) {
+                filterParams.selectedGroups = params.selectedGroups
+                filterParams.selectedSupplier = params.selectedSupplier
+                filterParams.includeAlternateSuppliers = params.includeAlternateSuppliers
+                filterParams.includeReorderListingDisabled = params.includeReorderListingDisabled
+                filterParams.includeOnBackOrder = params.includeOnBackOrder
+            }
+            // Remember search.
+            session.reorderSearchSelectedGroups = params.selectedGroups
+            session.reorderSearchSelectedSupplier = params.selectedSupplier
+            session.reorderSearchIncludeAlternateSuppliers = params.includeAlternateSuppliers
+            session.reorderSearchIncludeReorderListingDisabled = params.includeReorderListingDisabled
+            session.reorderSearchIncludeOnBackOrder = params.includeOnBackOrder
+            // Clear any previous search.
+            session.removeAttribute("inventoryItemReorderQuickSearch")
+            session.removeAttribute("inventoryItemReorderQuickSearchDaysBack")
+        }
+
+        // export plugin:
+        if(params?.format && params.format != "html") {
+
+            def dateFmt = { date ->
+                formatDate(format: "EEE, dd-MMM-yyyy", date: date)
+            }
+
+            String title
+            if(params.quickSearch)
+                title = params.message
+            else
+                title = "Filtered Inventory List."
+
+            response.contentType = ConfigurationHolder.config.grails.mime.types[params.format]
+            response.setHeader("Content-disposition", "attachment; filename=Inventory.${params.extension}")
+            List fields = ["name",
+                                "description",
+                                "inventoryGroup",
+                                "unitsInStock",
+                                "reorderPoint",
+                                "unitOfMeasure",
+                                "inventoryLocation",
+                                "inventoryLocation.inventoryStore"]
+            Map labels = ["name": "Name",
+                                "description": "Description",
+                                "inventoryGroup": "Group",
+                                "unitsInStock":"In Stock",
+                                "reorderPoint":"Reorder Point",
+                                "unitOfMeasure": "UOM",
+                                "inventoryLocation": "Location",
+                                "inventoryLocation.inventoryStore": "Store"]
+
+            Map formatters = [:]
+            Map parameters = [title: title, separator: ","]
+
+            exportService.export(params.format,
+                                                response.outputStream,
+                                                inventoryItemInstanceList.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) },
+                                                fields,
+                                                labels,
+                                                formatters,
+                                                parameters)
+        }
+
+        // Add some basic params to filterParams.
+        filterParams.max = params.max
+        filterParams.offset = params.offset?.toInteger() ?: 0
+        filterParams.sort = params.sort ?: "name"
+        filterParams.order = params.order ?: "asc"
+
+        return[ inventoryItemInstanceList: inventoryItemInstanceList,
+                        inventoryItemInstanceTotal: inventoryItemInstanceTotal,
+                        filterParams: filterParams,
+                        params: params,
+                        inventoryGroups: inventoryGroups,
+                        suppliers: suppliers]
+    } // end reorder()
+
 } // end of class
