Index: trunk/grails-app/controllers/InventoryItemPurchaseDetailedController.groovy
===================================================================
--- trunk/grails-app/controllers/InventoryItemPurchaseDetailedController.groovy	(revision 467)
+++ trunk/grails-app/controllers/InventoryItemPurchaseDetailedController.groovy	(revision 468)
@@ -1,3 +1,5 @@
 import org.codehaus.groovy.grails.plugins.springsecurity.Secured
+import org.codehaus.groovy.grails.commons.ConfigurationHolder
+import com.zeddware.grails.plugins.filterpane.FilterUtils
 
 @Secured(['ROLE_AppAdmin', 'ROLE_Manager', 'ROLE_InventoryManager'])
@@ -5,12 +7,122 @@
 
     def authService
+    def filterService
+    def exportService
+    def dateUtilService
     def inventoryPurchaseService
 
     def index = {
-        redirect(controller: 'inventoryItemDetailed', action:'search', params:params)
+        redirect(action:'search', params:params)
     }
 
     // the delete, save and update actions only accept POST requests
     static allowedMethods = [delete:'POST', save:'POST', update:'POST']
+
+    def setSearchParamsMax = {
+        def max = 1000
+        if(params.newMax.isInteger()) {
+            def i = params.newMax.toInteger()
+            if(i > 0 && i <= max)
+                session.inventoryItemPurchaseSearchParamsMax = params.newMax
+            if(i > max)
+                session.inventoryItemPurchaseSearchParamsMax = max
+        }
+        forward(action: 'search', params: params)
+    }
+
+    def search = {
+
+        if(session.inventoryItemPurchaseSearchParamsMax)
+            params.max = session.inventoryItemPurchaseSearchParamsMax
+
+        // Protect filterPane.
+        params.max = Math.min( params.max ? params.max.toInteger() : 10,  1000 )
+        params.offset = params.offset?.toInteger() ?: 0
+        params.sort = params.sort ?: "purchaseOrderNumber"
+        params.order = params.order ?: "desc"
+
+        def inventoryItemPurchaseList = []
+        def inventoryItemPurchaseTotal
+        def filterParams = [:]
+
+        // Quick Search:
+        if(!FilterUtils.isFilterApplied(params)) {
+
+            if(params.quickSearch == "searchAllOrders") {
+                inventoryItemPurchaseList = InventoryItemPurchase.findAllByInventoryItemPurchaseType(InventoryItemPurchaseType.read(1),
+                                                                                                                                                                        [max:params.max,
+                                                                                                                                                                        offset:params.offset,
+                                                                                                                                                                        sort:params.sort,
+                                                                                                                                                                        order:params.order])
+                if(inventoryItemPurchaseList.size() > 0) { params.message = "All Orders." }
+                else { params.message = "No orders found." }
+            }
+            else if(params.quickSearch == "searchAllReceived") {
+                inventoryItemPurchaseList = InventoryItemPurchase.findAllByInventoryItemPurchaseTypeOrInventoryItemPurchaseType(InventoryItemPurchaseType.read(2),
+                                                                                                                                                                                                                            InventoryItemPurchaseType.read(3),
+                                                                                                                                                                                                                            [max:params.max,
+                                                                                                                                                                                                                            offset:params.offset,
+                                                                                                                                                                                                                            sort:params.sort,
+                                                                                                                                                                                                                            order:params.order])
+                if(inventoryItemPurchaseList.size() > 0) { params.message = "All Received Complete." }
+                else { params.message = "No orders found." }
+            }
+            else {
+                //Default:
+                inventoryItemPurchaseList = InventoryItemPurchase.list(max:params.max,
+                                                                                                                offset:params.offset,
+                                                                                                                sort:params.sort,
+                                                                                                                order:params.order)
+                if(inventoryItemPurchaseList.size() > 0) { params.message = "All Purchases." }
+                else { params.message = "No orders found." }
+            }
+
+            inventoryItemPurchaseTotal = inventoryItemPurchaseList.size()
+            filterParams.quickSearch = params.quickSearch
+        }
+        else {
+            // filterPane:
+            inventoryItemPurchaseList = filterService.filter( params, InventoryItemPurchase )
+            inventoryItemPurchaseTotal = filterService.count( params, InventoryItemPurchase )
+            filterParams = com.zeddware.grails.plugins.filterpane.FilterUtils.extractFilterParams(params)
+        }
+
+        // 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.quickSearch} inventory purchases."
+            else
+                title = "Filtered inventory purchases."
+
+            response.contentType = ConfigurationHolder.config.grails.mime.types[params.format]
+            response.setHeader("Content-disposition", "attachment; filename=Purchases.${params.extension}")
+            List fields = ["purchaseOrderNumber", "dateEntered", "costCode", "quantity", "orderValueAmount", "invoiceNumber",
+                                    "inventoryItemPurchaseType"]
+            Map labels = ["purchaseOrderNumber": "Order Number", "dateEntered": "Date", "costCode": "Cost Code",
+                                    "quantity": "Quantity", "orderValueAmount": "Order \$", "invoiceNumber": "Invoice Number",
+                                    "inventoryItemPurchaseType": "Type"]
+            Map formatters = [ dateEntered: dateFmt]
+            Map parameters = [title: title, separator: ","]
+
+            exportService.export(params.format, response.outputStream, inventoryItemPurchaseList, fields, labels, formatters, parameters)
+        }
+
+        // Add some basic params to filterParams.
+        filterParams.max = params.max
+        filterParams.offset = params.offset?.toInteger() ?: 0
+        filterParams.sort = params.sort ?: "purchaseOrderNumber"
+        filterParams.order = params.order ?: "desc"
+
+        return[ inventoryItemPurchaseList: inventoryItemPurchaseList,
+                inventoryItemPurchaseTotal: inventoryItemPurchaseTotal,
+                filterParams: filterParams ]
+
+    } // end search()
 
     def show = {
Index: trunk/grails-app/controllers/TaskDetailedController.groovy
===================================================================
--- trunk/grails-app/controllers/TaskDetailedController.groovy	(revision 467)
+++ trunk/grails-app/controllers/TaskDetailedController.groovy	(revision 468)
@@ -40,5 +40,5 @@
             params.max = session.taskSearchParamsMax
 
-        // TaskSearchService protects itself but filterPane does not.
+        // Protect filterPane.
         params.max = Math.min( params.max ? params.max.toInteger() : 10,  1000 )
 
Index: trunk/grails-app/i18n/messages.properties
===================================================================
--- trunk/grails-app/i18n/messages.properties	(revision 467)
+++ trunk/grails-app/i18n/messages.properties	(revision 468)
@@ -257,2 +257,4 @@
 fp.property.text.manufacturer.name=Manufacturer
 fp.property.text.estimatedUnitPriceAmount=Estimated Unit Price
+
+fp.property.text.inventoryItemPurchaseType.name=Type
Index: trunk/grails-app/views/inventoryItemDetailed/search.gsp
===================================================================
--- trunk/grails-app/views/inventoryItemDetailed/search.gsp	(revision 467)
+++ trunk/grails-app/views/inventoryItemDetailed/search.gsp	(revision 468)
@@ -25,4 +25,7 @@
 
             <div class="paginateButtons">
+                <span class="searchButtons">
+                    <a href='' onclick="showElement('searchPane'); return false;">Quick</a>
+                </span>
                 Results: ${inventoryItemInstanceList.size()} / ${inventoryItemInstanceTotal}
                 <span class="searchButtons">
@@ -102,64 +105,66 @@
             </g:if>
 
-            <div class="list">
-                <table>
-                    <thead>
-                        <tr>
-
-                            <th>Picture</th>
-                        
-                   	        <g:sortableColumn property="name" title="Name" params="${filterParams}" />
-                        
-                   	        <g:sortableColumn property="description" title="Description" params="${filterParams}" />
-                        
-                            <g:sortableColumn property="unitsInStock" title="Units In Stock" params="${filterParams}" />
-                            
-                            <th>Unit Of Measure</th>
-
-                            <th></th>
-                        
-                        </tr>
-                    </thead>
-                    <tbody>
-                    <g:each in="${inventoryItemInstanceList}" status="i" var="inventoryItemInstance">
-                        <tr class="${(i % 2) == 0 ? 'clickableOdd' : 'clickableEven'}" />
-
-                            <td class='gallery'>
-                                <g:if test="${inventoryItemInstance.picture}" >
-                                    <wa:pictureLightboxAnchor picture="${inventoryItemInstance.picture}"
-                                                                                        size="${Image.Small}"
-                                                                                        lightboxSize="${Image.Large}"
-                                                                                        target="_blank"
-                                                                                        title="Show Original" />
-                                </g:if>
-                            </td>
-                        
-                            <td onclick='window.location = "${request.getContextPath()}/inventoryItemDetailed/show/${inventoryItemInstance.id}"' >
-                                ${fieldValue(bean:inventoryItemInstance, field:'name')}
-                            </td>
-                        
-                            <td onclick='window.location = "${request.getContextPath()}/inventoryItemDetailed/show/${inventoryItemInstance.id}"' >
-                                ${fieldValue(bean:inventoryItemInstance, field:'description')}
-                            </td>
-                        
-                            <td onclick='window.location = "${request.getContextPath()}/inventoryItemDetailed/show/${inventoryItemInstance.id}"' >
-                                ${fieldValue(bean:inventoryItemInstance, field:'unitsInStock')}
-                            </td>
-                        
-                            <td onclick='window.location = "${request.getContextPath()}/inventoryItemDetailed/show/${inventoryItemInstance.id}"' >
-                                ${fieldValue(bean:inventoryItemInstance, field:'unitOfMeasure')}
-                            </td>
-
-                            <td>
-                                <g:link action="show" id="${inventoryItemInstance.id}">
-                                    <img  src="${resource(dir:'images/skin',file:'database_go.png')}" alt="Show" />
-                                </g:link>
-                            </td>
-                        
-                        </tr>
-                    </g:each>
-                    </tbody>
-                </table>
-            </div>
+            <g:if test="${inventoryItemInstanceList.size() > 0}">
+                <div class="list">
+                    <table>
+                        <thead>
+                            <tr>
+
+                                <th>Picture</th>
+                            
+                                <g:sortableColumn property="name" title="Name" params="${filterParams}" />
+                            
+                                <g:sortableColumn property="description" title="Description" params="${filterParams}" />
+                            
+                                <g:sortableColumn property="unitsInStock" title="Units In Stock" params="${filterParams}" />
+                                
+                                <th>Unit Of Measure</th>
+
+                                <th></th>
+                            
+                            </tr>
+                        </thead>
+                        <tbody>
+                        <g:each in="${inventoryItemInstanceList}" status="i" var="inventoryItemInstance">
+                            <tr class="${(i % 2) == 0 ? 'clickableOdd' : 'clickableEven'}" />
+
+                                <td class='gallery'>
+                                    <g:if test="${inventoryItemInstance.picture}" >
+                                        <wa:pictureLightboxAnchor picture="${inventoryItemInstance.picture}"
+                                                                                            size="${Image.Small}"
+                                                                                            lightboxSize="${Image.Large}"
+                                                                                            target="_blank"
+                                                                                            title="Show Original" />
+                                    </g:if>
+                                </td>
+                            
+                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemDetailed/show/${inventoryItemInstance.id}"' >
+                                    ${fieldValue(bean:inventoryItemInstance, field:'name')}
+                                </td>
+                            
+                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemDetailed/show/${inventoryItemInstance.id}"' >
+                                    ${fieldValue(bean:inventoryItemInstance, field:'description')}
+                                </td>
+                            
+                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemDetailed/show/${inventoryItemInstance.id}"' >
+                                    ${fieldValue(bean:inventoryItemInstance, field:'unitsInStock')}
+                                </td>
+                            
+                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemDetailed/show/${inventoryItemInstance.id}"' >
+                                    ${fieldValue(bean:inventoryItemInstance, field:'unitOfMeasure')}
+                                </td>
+
+                                <td>
+                                    <g:link action="show" id="${inventoryItemInstance.id}">
+                                        <img  src="${resource(dir:'images/skin',file:'database_go.png')}" alt="Show" />
+                                    </g:link>
+                                </td>
+                            
+                            </tr>
+                        </g:each>
+                        </tbody>
+                    </table>
+                </div>
+            </g:if>
             <div class="paginateButtons">
                 <g:paginate total="${inventoryItemInstanceTotal}" params="${filterParams}" />
@@ -182,4 +187,35 @@
                                                                                 ]}"/>
         </div> <!-- end body div -->
+
+        <!-- Start Search Pane -->
+        <div class="overlayPane" id="searchPane" style="display:none;">
+            <h2>Quick Search</h2>
+            <g:form method="post" id="searchForm" name="searchForm" >
+                <table>
+                    <tbody>
+
+                        <tr class="prop">
+                            <td valign="top" class="name">
+                                <label>Links:</label>
+                            </td>
+                            <td valign="top" class="value">
+                                <g:link controller="inventoryItemPurchaseDetailed"
+                                                action="search">
+                                                Purchases
+                                </g:link>
+                                <br />
+                            </td>
+                        </tr>
+
+                    </tbody>
+                </table>
+                <div class="buttons">
+                    <span class="button">
+                        <input type="button" value="${g.message(code:'fp.tag.filterPane.button.cancel.text', default:'Cancel')}" onclick="return hideElement('searchPane');" />
+                    </span>
+                </div>
+            </g:form>
+        </div> <!-- end search pane -->
+
     </body>
 </html>
Index: trunk/grails-app/views/inventoryItemPurchaseDetailed/search.gsp
===================================================================
--- trunk/grails-app/views/inventoryItemPurchaseDetailed/search.gsp	(revision 468)
+++ trunk/grails-app/views/inventoryItemPurchaseDetailed/search.gsp	(revision 468)
@@ -0,0 +1,231 @@
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+        <meta name="layout" content="main" />
+        <title>Inventory Item Purchase Search</title>
+        <filterpane:includes />
+        <nav:resources override="true"/>
+        <export:resource />
+    </head>
+    <body>
+        <div class="nav">
+            <h1>Inventory Purchases</h1>
+        </div>
+
+        <div class="body">
+            <g:render template="/shared/messages" />
+            <g:if test="${params.message}">
+                <div class="message">${params.message}</div>
+            </g:if>
+            <filterpane:currentCriteria domainBean="InventoryItemPurchase"
+                                    action="search"
+                                    dateFormat="EEE, dd-MMM-yyyy"
+                                    removeImgDir="images"
+                                    removeImgFile="bullet_delete.png"
+                                    title="Advanced Search"/>
+
+            <div class="paginateButtons">
+                <span class="searchButtons">
+                    <a href='' onclick="showElement('searchPane'); return false;">Quick</a>
+                </span>
+                Results: ${inventoryItemPurchaseList.size()} / ${inventoryItemPurchaseTotal}
+                <span class="searchButtons">
+                    <filterpane:filterButton text="Advanced" appliedText="Advanced" />
+                </span>
+            </div>
+
+            <jsUtil:toggleControl toggleId="options"
+                                                    imageId="optionsImg"
+                                                    closedImgUrl="${resource(dir:'images/skin',file:'bullet_arrow_right.png')}"
+                                                    openImgUrl="${resource(dir:'images/skin',file:'bullet_arrow_down.png')}"
+                                                    text="${g.message(code: 'default.options.text')}"
+                                                    />
+
+            <div id="options" style="display:none;">
+                <g:form method="post" >
+                    <g:hiddenField name="params" value="${filterParams}" />
+                    <div class="dialog">
+                        <table>
+                            <tbody>
+
+                                <tr class="prop">
+                                    <td valign="top" class="name">
+                                        <label for="max">Results per page:</label>
+                                    </td>
+                                    <td valign="top" class="value">
+                                        <input type="text" maxlength="4" id="description" name="newMax" value="${params.max}"/>
+
+                                        <span class="buttons">
+                                            <g:actionSubmit action="setSearchParamsMax" class="go" value="Update" />
+                                        </span>
+                                    </td>
+                                </tr>
+
+                            </tbody>
+                        </table>
+                    </div>
+                <export:formats  params="${filterParams}" formats="['csv', 'excel', 'pdf', 'rtf']"/>
+                </g:form>
+            </div>
+
+            <br />
+
+            <g:if test="${inventoryItemPurchaseList.size() > 10}">
+                <g:if test="${inventoryItemPurchaseTotal > inventoryItemPurchaseList.size()}">
+                    <div class="paginateButtons">
+                        <g:paginate total="${inventoryItemPurchaseTotal}" params="${filterParams}" />
+                    </div>
+                </g:if>
+            </g:if>
+
+            <g:if test="${inventoryItemPurchaseList.size() > 0}">
+                <div class="list">
+                    <table>
+                        <thead>
+                            <tr>
+                                <g:sortableColumn property="purchaseOrderNumber"
+                                                                    title="Order #" params="${filterParams}"  />
+                                <g:sortableColumn property="dateEntered"
+                                                                    title="Date" params="${filterParams}" />
+                                <g:sortableColumn property="costCode"
+                                                                    title="Cost Code" params="${filterParams}" />
+                                <g:sortableColumn property="quantity"
+                                                                    title="Quantity" params="${filterParams}" />
+                                <g:sortableColumn property="orderValueAmount"
+                                                                    title="Order \$" params="${filterParams}" />
+                                <g:sortableColumn property="invoiceNumber"
+                                                                    title="Invoice Number" params="${filterParams}" />
+                                <g:sortableColumn property="inventoryItemPurchaseType"
+                                                                    title="Type" params="${filterParams}" />
+                                <th>
+                                    <img  src="${resource(dir:'images/skin',file:'database_go_grey.png')}" alt="Show" title="Show" />
+                                </th>
+                                <th>
+                                    <img  src="${resource(dir:'images/skin',file:'basket_put_grey.png')}" alt="Receive" title="Receive" />
+                                </th>
+                                <th>
+                                    <img  src="${resource(dir:'images/skin',file:'tick_grey.png')}" alt="Approve" title="Approve Payment" />
+                                </th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            <g:each in="${inventoryItemPurchaseList}" status="i" var="purchase">
+                                <tr class="${(i % 2) == 0 ? 'clickableOdd' : 'clickableEven'}"/>
+
+                                    <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
+                                        ${fieldValue(bean:purchase, field:'purchaseOrderNumber')}
+                                    </td>
+                                    <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
+                                        <g:formatDate date="${purchase.dateEntered}" format="EEE, dd-MMM-yyyy"/>
+                                    </td>
+                                    <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
+                                        ${fieldValue(bean:purchase, field:'costCode')}
+                                    </td>
+                                    <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
+                                        ${fieldValue(bean:purchase, field:'quantity')}
+                                    </td>
+                                    <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
+                                        ${fieldValue(bean:purchase, field:'orderValueAmount')}
+                                        ${fieldValue(bean:purchase, field:'orderValueCurrency')}
+                                    </td>
+                                    <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
+                                        ${fieldValue(bean:purchase, field:'invoiceNumber')}
+                                    </td>
+                                    <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
+                                        ${fieldValue(bean:purchase, field:'inventoryItemPurchaseType')}
+                                    </td>
+                                    <td>
+                                        <g:link controller="inventoryItemPurchaseDetailed" action="show" id="${purchase.id}">
+                                            <img  src="${resource(dir:'images/skin',file:'database_go.png')}" alt="Show" title="Show" />
+                                        </g:link>
+                                    </td>
+                                    <g:if test="${purchase.inventoryItemPurchaseType.id == 1}">
+                                        <g:if test="${!purchase.receivedComplete}">
+                                            <td>
+                                                <g:link controller="inventoryItemPurchaseDetailed" action="receive" id="${purchase.id}">
+                                                    <img  src="${resource(dir:'images/skin',file:'basket_put.png')}" alt="Receive" title="Receive" />
+                                                </g:link>
+                                            </td>
+                                        </g:if>
+                                        <g:else>
+                                            <td>
+                                            </td>
+                                        </g:else>
+                                        <g:if test="${!purchase.invoicePaymentApproved}">
+                                            <td>
+                                                <g:link controller="inventoryItemPurchaseDetailed" action="approveInvoicePayment" id="${purchase.id}">
+                                                    <img  src="${resource(dir:'images/skin',file:'tick.png')}" alt="Approve" title="Approve Payment" />
+                                                </g:link>
+                                            </td>
+                                        </g:if>
+                                        <g:else>
+                                            <td>
+                                            </td>
+                                        </g:else>
+                                    </g:if>
+                                    <g:else>
+                                        <td>
+                                        </td>
+                                        <td>
+                                        </td>
+                                    </g:else>
+
+                                </tr>
+                            </g:each>
+                        </tbody>
+                    </table>
+                </div>
+            </g:if>
+            <div class="paginateButtons">
+                <g:paginate total="${inventoryItemPurchaseTotal}" params="${filterParams}" />
+            </div>
+
+            <filterpane:filterPane domainBean="InventoryItemPurchase"
+                                    title="Advanced Search"
+                                    action="search"
+                                    class="overlayPane"
+                                    excludeProperties="orderValueCurrency"
+                                    associatedProperties="inventoryItemPurchaseType.name"
+                                    filterPropertyValues="${['inventoryItemPurchaseType.name':[values:InventoryItemPurchaseType.findAllByIsActive(true)],
+                                                                                dateEntered:[years:2020..2000,precision:'day']
+                                                                                ]}"/>
+        </div> <!-- end body  -->
+
+        <!-- Start Search Pane -->
+        <div class="overlayPane" id="searchPane" style="display:none;">
+            <h2>Quick Search</h2>
+            <g:form method="post" id="searchForm" name="searchForm" >
+                <table>
+                    <tbody>
+
+                        <tr class="prop">
+                            <td valign="top" class="name">
+                                <label>Type:</label>
+                            </td>
+                            <td valign="top" class="value">
+                                <g:link controller="inventoryItemPurchaseDetailed"
+                                                action="search"
+                                                params="[quickSearch: 'searchAllOrders']">
+                                                All Orders
+                                </g:link>
+                                <br />
+                                <g:link controller="inventoryItemPurchaseDetailed" 
+                                                action="search"
+                                                params="[quickSearch: 'searchAllReceived']">
+                                                All Received
+                                </g:link>
+                            </td>
+                        </tr>
+
+                    </tbody>
+                </table>
+                <div class="buttons">
+                    <span class="button">
+                        <input type="button" value="${g.message(code:'fp.tag.filterPane.button.cancel.text', default:'Cancel')}" onclick="return hideElement('searchPane');" />
+                    </span>
+                </div>
+            </g:form>
+        </div> <!-- end search pane -->
+
+    </body>
+</html>
