Changeset 441 for trunk/grails-app


Ignore:
Timestamp:
Mar 16, 2010, 12:00:04 PM (15 years ago)
Author:
gav
Message:

Add CostCode and InventoryItemPurchase domain classes with import features.
Includes some fixes to inventory imports, where manufacturer and supplier were crossed.

Location:
trunk/grails-app
Files:
18 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/InventoryItemDetailedController.groovy

    r435 r441  
    3434
    3535    /**
    36     * Disaply the import view.
     36    * Display the import view.
    3737    */
    3838    def importInventory = {
     
    9090        def s = inventoryCsvService.buildInventory(inventoryItemList)
    9191        render s
     92    }
     93
     94    /**
     95    * Display the import view for purchases.
     96    */
     97    def importInventoryItemPurchases = {
     98    }
     99
     100    /**
     101    * Handle the inventory purchases import save.
     102    */
     103    def importInventoryItemPurchasesSave = {
     104        def result = inventoryCsvService.importInventoryItemPurchases(request)
     105
     106        if(!result.error) {
     107            flash.message = g.message(code: "inventory.import.success")
     108            redirect(action:search)
     109            return
     110        }
     111
     112        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
     113        redirect(action: importInventoryItemPurchases)
    92114    }
    93115
     
    194216                                    inventoryMovementListTotal: result.inventoryMovementListTotal,
    195217                                    inventoryMovementListMax: result.inventoryMovementListMax,
     218                                    inventoryItemPurchases: result.inventoryItemPurchases,
     219                                    inventoryItemPurchasesTotal: result.inventoryItemPurchasesTotal,
    196220                                    showTab: result.showTab]
    197221
  • trunk/grails-app/services/CreateDataService.groovy

    r433 r441  
    6262        createBaseAddressTypes()
    6363        createBaseContactTypes()
     64        createBaseInventoryItemPurchaseTypes()
    6465
    6566        // Tasks
     
    113114        createDemoManufacturers()
    114115        createDemoProductionReference()
     116        createDemoCostCodes()
    115117
    116118        // Tasks
     
    612614    }
    613615
     616    def createBaseInventoryItemPurchaseTypes() {
     617
     618        // InventoryItemPurchaseType
     619        def inventoryItemPurchaseTypeInstance
     620
     621        // InventoryItemPurchaseType #1
     622        inventoryItemPurchaseTypeInstance = new InventoryItemPurchaseType(name: "Order Placed",
     623                                                                                description: "Order has been placed.")
     624        saveAndTest(inventoryItemPurchaseTypeInstance)
     625
     626        // InventoryItemPurchaseType #2
     627        inventoryItemPurchaseTypeInstance = new InventoryItemPurchaseType(name: "Received B/order To Come",
     628                                                                                description: "Order has been partially received.")
     629        saveAndTest(inventoryItemPurchaseTypeInstance)
     630        // InventoryItemPurchaseType #3
     631        inventoryItemPurchaseTypeInstance = new InventoryItemPurchaseType(name: "Received Complete",
     632                                                                                description: "Order has been partially received.")
     633        saveAndTest(inventoryItemPurchaseTypeInstance)
     634
     635        // InventoryItemPurchaseType #4
     636        inventoryItemPurchaseTypeInstance = new InventoryItemPurchaseType(name: "Invoice Approved",
     637                                                                                description: "Invoice approved for payment.")
     638        saveAndTest(inventoryItemPurchaseTypeInstance)
     639    }
     640
    614641    def createDemoSuppliers() {
    615642
     
    656683        productionReferenceInstance = new ProductionReference(name: "Tuesday Production")
    657684        saveAndTest(productionReferenceInstance)
     685    }
     686
     687    def createDemoCostCodes() {
     688
     689        // CostCode
     690        def costCodeInstance
     691
     692        // CostCode #1
     693        costCodeInstance = new CostCode(name: "RM Reelstand")
     694        saveAndTest(costCodeInstance)
     695
     696        // CostCode #2
     697        costCodeInstance = new CostCode(name: "CAPEX Reelstand")
     698        saveAndTest(costCodeInstance)
    658699    }
    659700
  • trunk/grails-app/services/InventoryCsvService.groovy

    r436 r441  
    1111
    1212    boolean transactional = false
     13
     14    def dateUtilService
    1315
    1416    def g = new org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib()
     
    4749            if (multiPartFile.getSize() > fileMaxSize)
    4850                return fail(code: "default.file.over.max.size", args: [fileMaxSize/kByteMultiplier, "kB"])
    49 
    50             //TODO: delete
    51             def columnValue = ''
    52             def columnIndex = 0
    53             def numberOfColumns = 0
    5451
    5552            def line = []
     
    105102            def tempAlternateItems = []
    106103
    107             def column = ''
    108 
    109104            def nextLine = {
    110105                    line = reader.readNext()
    111106                    lineNumber ++
    112107                    log.info "Processing line: " + lineNumber
    113             }
    114 
    115             def nextColumn = {
    116 
    117                 if( columnIndex < numberOfColumns ) {
    118                         column = line[columnIndex].trim()
    119                 }
    120                 else {
    121                     log.info "No more columns on line: " + lineNumber
    122                     return false
    123                 }
    124 
    125                 columnIndex++
    126                 // Success.
    127                 return column
    128108            }
    129109
     
    280260                        // Manufacturer Type.
    281261                        if(tempPreferredManufacturerItemAndType.size == 2) {
    282                             tempPreferredManufacturerType = WordUtils.capitalizeFully(tempPreferredManufacturerItemAndType[1])
     262                            tempPreferredManufacturerType = WordUtils.capitalize(tempPreferredManufacturerItemAndType[1])
    283263                            manufacturerTypeInstance = ManufacturerType.findByName(tempPreferredManufacturerType)
    284264                        }
     
    291271
    292272                        preferredManufacturerInstance = new Manufacturer(name: tempPreferredManufacturerItem,
    293                                                                                                             supplierType: manufacturerTypeInstance)
     273                                                                                                            manufacturerType: manufacturerTypeInstance)
    294274                        if(!preferredManufacturerInstance.save()) {
    295275                            log.error "Failed to create preferred manufacturer on line: " + lineNumber
     
    302282
    303283                // Alternate Manufacturers.
    304                 tempAlternateManufacturers = parseInputList(inventoryParams.manufacturers)
    305                 inventoryParams.manufacturers = []
     284                tempAlternateManufacturers = parseInputList(inventoryParams.alternateManufacturers)
     285                inventoryParams.alternateManufacturers = []
    306286
    307287                for(tempManufacturer in tempAlternateManufacturers) {
     
    309289                    tempManufacturerItem = WordUtils.capitalizeFully(tempManufacturerItemAndType[0])
    310290
    311                     manufacturerInstance = Manufacturer.findByName(tempManufacturerItem)
    312                     if(!manufacturerInstance) {
     291                    alternateManufacturerInstance = Manufacturer.findByName(tempManufacturerItem)
     292                    if(!alternateManufacturerInstance) {
    313293
    314294                        // ManufacturerType.
    315295                        if(tempManufacturerItemAndType.size == 2) {
    316                             tempManufacturerType = WordUtils.capitalizeFully(tempManufacturerItemAndType[1])
     296                            tempManufacturerType = WordUtils.capitalize(tempManufacturerItemAndType[1])
    317297                            manufacturerTypeInstance = ManufacturerType.findByName(tempManufacturerType)
    318298                        }
     
    324304                        }
    325305
    326                         manufacturerInstance = new Manufacturer(name: tempManufacturerItem,
     306                        alternateManufacturerInstance = new Manufacturer(name: tempManufacturerItem,
    327307                                                                                                manufacturerType: manufacturerTypeInstance)
    328                         if(!manufacturerInstance.save()) {
     308                        if(!alternateManufacturerInstance.save()) {
    329309                            log.error "Failed to create manufacturers on line: " + lineNumber
    330310                            return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
     
    332312                    }
    333313
    334                     inventoryParams.manufacturers.add(manufacturerInstance)
     314                    inventoryParams.alternateManufacturers.add(alternateManufacturerInstance)
    335315                }
    336316
     
    345325                        // SupplierType.
    346326                        if(tempPreferredSupplierItemAndType.size == 2) {
    347                             tempPreferredSupplierType = WordUtils.capitalizeFully(tempPreferredSupplierItemAndType[1])
     327                            tempPreferredSupplierType = WordUtils.capitalize(tempPreferredSupplierItemAndType[1])
    348328                            supplierTypeInstance = SupplierType.findByName(tempPreferredSupplierType)
    349329                        }
     
    379359                        // SupplierType.
    380360                        if(tempSupplierItemAndType.size == 2) {
    381                             tempSupplierType = WordUtils.capitalizeFully(tempSupplierItemAndType[1])
     361                            tempSupplierType = WordUtils.capitalize(tempSupplierItemAndType[1])
    382362                            supplierTypeInstance = SupplierType.findByName(tempSupplierType)
    383363                        }
     
    397377                    }
    398378
    399                     inventoryParams.suppliers.add(alternateSupplierInstance)
     379                    inventoryParams.alternateSuppliers.add(alternateSupplierInstance)
    400380                }
    401381
     
    475455                // Save inventoryItem.
    476456                if(inventoryItemInstance.hasErrors() || !inventoryItemInstance.save()) {
    477                     log.error "Failed to create item on line: " + column + "(" + lineNumber + ")"
     457                    log.error "Failed to create item on line: " + lineNumber
    478458                    log.debug inventoryItemInstance.errors
    479459                    return fail(code: "inventory.import.failure", args: [lineNumber, logFileLink])
     
    641621        writer.close()
    642622        return sw.toString()
    643     } // end buildInventory
     623    } // end buildInventory()
     624
     625    /**
     626    * Import inventoryItemPurchases creating items as required.
     627    */
     628    def importInventoryItemPurchases(request) {
     629        InventoryItemPurchase.withTransaction { status ->
     630            def result = [:]
     631
     632            def kByteMultiplier = 1000
     633            def fileMaxSize = 800 * kByteMultiplier
     634            def logFileLink = g.link(controller: "appCore", action: "appLog") {"log"}
     635
     636            def multiPartFile = request.getFile('file')
     637
     638            InputStreamReader sr = new InputStreamReader(multiPartFile.inputStream)
     639            CSVReader reader = new CSVReader(sr)
     640
     641            def fail = { Map m ->
     642                status.setRollbackOnly()
     643                reader.close()
     644                result.error = [ code: m.code, args: m.args ]
     645                return result
     646            }
     647
     648            if(!multiPartFile || multiPartFile.isEmpty())
     649                return fail(code: "default.file.not.supplied")
     650
     651            if (multiPartFile.getSize() > fileMaxSize)
     652                return fail(code: "default.file.over.max.size", args: [fileMaxSize/kByteMultiplier, "kB"])
     653
     654            def line = []
     655            def lineNumber = 0
     656            def maxNumberOfColumns = 10
     657            def inventoryItemPurchaseParams = [:]
     658            def inventoryItemPurchaseProperties = ["inventoryItem", "purchaseOrderNumber", "quantity",
     659                                                                                "inventoryItemPurchaseType",
     660                                                                                "costCode", "enteredBy", "dateEntered",
     661                                                                                "orderValueAmount", "orderValueCurrency", "invoiceNumber"]
     662
     663            def personInstance
     664            def costCodeInstance
     665            def inventoryItemInstance
     666            def inventoryItemPurchaseInstance
     667            def inventoryItemPurchaseTypeInstance
     668
     669            def nextLine = {
     670                    line = reader.readNext()
     671                    lineNumber ++
     672                    log.info "Processing line: " + lineNumber
     673            }
     674
     675            def parseInputDate = {
     676                if( (it == null) || (it.trim() == '') ) {
     677                    log.error "Failed to find any date on line: " + lineNumber
     678                    return fail(code: "inventoryItemPurchase.import.failure", args: [lineNumber, logFileLink])
     679                }
     680
     681                def d = it.split("/").collect{it.trim()}
     682                if(d.size() != 3) {
     683                    log.error "Failed to find full date on line: " + lineNumber
     684                    return fail(code: "inventoryItemPurchase.import.failure", args: [lineNumber, logFileLink])
     685                }
     686                dateUtilService.makeDate(d[0], d[1], d[2])
     687            }
     688
     689            // Get first line.
     690            nextLine()
     691
     692            // Check for header line 1.
     693            if(line != purchasesTemplateHeaderLine1) {
     694                log.error "Failed to find header line 1. "
     695                log.error "Required: " + purchasesTemplateHeaderLine1.toString()
     696                log.error "Supplied: " + line.toString()
     697                return fail(code: "default.file.no.header")
     698            }
     699
     700            log.info "Header line found."
     701
     702            // Prepare the first body line.
     703            nextLine()
     704
     705            // Primary loop.
     706            while(line) {
     707
     708                if(line.size() > maxNumberOfColumns) {
     709                    log.error "Too many columns on line: " + lineNumber
     710                    return fail(code: "inventoryItemPurchase.import.failure", args: [lineNumber, logFileLink])
     711                }
     712
     713                // Ignore comment lines.
     714                if(line.toString().toLowerCase().contains("comment")) {
     715                    log.info "Comment line found."
     716                    nextLine()
     717                    continue
     718                }
     719
     720                // Ignore example lines.
     721                if(line.toString().toLowerCase().contains("example")) {
     722                    log.info "Example line found."
     723                    nextLine()
     724                    continue
     725                }
     726
     727                // Parse the line into the params map.
     728                inventoryItemPurchaseParams = [:]
     729                line.eachWithIndex { it, j ->
     730                    inventoryItemPurchaseParams."${inventoryItemPurchaseProperties[j]}" = it.trim()
     731                }
     732
     733                // Debug
     734                log.debug " Supplied params: "
     735                log.debug inventoryItemPurchaseParams
     736
     737                // Ignore blank lines.
     738                if(inventoryItemPurchaseParams.inventoryItem == '') {
     739                    log.info "No inventory item name found."
     740                    nextLine()
     741                    continue
     742                }
     743
     744                // Inventory Item.
     745                inventoryItemPurchaseParams.inventoryItem = WordUtils.capitalize(inventoryItemPurchaseParams.inventoryItem)
     746                inventoryItemInstance = InventoryItem.findByName(inventoryItemPurchaseParams.inventoryItem)
     747                if(!inventoryItemInstance) {
     748                    log.error "Inventory item not found on line: " + lineNumber
     749                    return fail(code: "inventoryItemPurchase.import.failure", args: [lineNumber, logFileLink])
     750                }
     751                inventoryItemPurchaseParams.inventoryItem = inventoryItemInstance
     752
     753                // Quantity.
     754                if(inventoryItemPurchaseParams.quantity.isInteger())
     755                    inventoryItemPurchaseParams.quantity = inventoryItemPurchaseParams.quantity.toInteger()
     756                else {
     757                    log.error "Quantity is not a valid number on line: " + lineNumber
     758                    return fail(code: "inventoryItemPurchase.import.failure", args: [lineNumber, logFileLink])
     759                }
     760
     761                // InventoryItemPurchaseType.
     762                inventoryItemPurchaseParams.inventoryItemPurchaseType = WordUtils.capitalizeFully(inventoryItemPurchaseParams.inventoryItemPurchaseType)
     763                inventoryItemPurchaseTypeInstance = InventoryItemPurchaseType.findByName(inventoryItemPurchaseParams.inventoryItemPurchaseType)
     764                if(!inventoryItemPurchaseTypeInstance) {
     765                    log.error "Inventory item purchase type not found on line: " + lineNumber
     766                    log.debug inventoryItemPurchaseParams.inventoryItemPurchaseType
     767                    return fail(code: "inventoryItemPurchase.import.failure", args: [lineNumber, logFileLink])
     768                }
     769                inventoryItemPurchaseParams.inventoryItemPurchaseType = inventoryItemPurchaseTypeInstance
     770
     771                // CostCode.
     772                if(inventoryItemPurchaseParams.costCode != '') {
     773                    inventoryItemPurchaseParams.costCode = WordUtils.capitalizeFully(inventoryItemPurchaseParams.costCode)
     774                    costCodeInstance = CostCode.findByName(inventoryItemPurchaseParams.costCode)
     775                    if(!costCodeInstance) {
     776                        costCodeInstance = new CostCode(name: inventoryItemPurchaseParams.costCode)
     777                        if(!costCodeInstance.save()) {
     778                            log.error "Failed to create cost code on line: " + lineNumber
     779                            return fail(code: "inventoryItemPurchase.import.failure", args: [lineNumber, logFileLink])
     780                        }
     781                    }
     782                    inventoryItemPurchaseParams.costCode = costCodeInstance
     783                }
     784
     785                // Entered By.
     786                inventoryItemPurchaseParams.enteredBy = inventoryItemPurchaseParams.enteredBy.toLowerCase()
     787                personInstance = Person.findByLoginName(inventoryItemPurchaseParams.enteredBy)
     788                if(!personInstance) {
     789                    log.error "Entered by person not found on line: " + lineNumber
     790                    return fail(code: "inventoryItemPurchase.import.failure", args: [lineNumber, logFileLink])
     791                }
     792                inventoryItemPurchaseParams.enteredBy = personInstance
     793
     794                // Date Entered.
     795                inventoryItemPurchaseParams.dateEntered = parseInputDate(inventoryItemPurchaseParams.dateEntered)
     796
     797                // Debug
     798                log.debug "InventoryItemPurchaseParams: "
     799                log.debug inventoryItemPurchaseParams
     800
     801                // Save inventoryItem.
     802                log.info "Creating new purchase."
     803                inventoryItemPurchaseInstance = new InventoryItemPurchase(inventoryItemPurchaseParams)
     804
     805                if(inventoryItemPurchaseInstance.hasErrors() || !inventoryItemPurchaseInstance.save()) {
     806                    log.error "Failed to create item on line: " + lineNumber
     807                    log.debug inventoryItemPurchaseInstance.errors
     808                    return fail(code: "inventoryItemPurchase.import.failure", args: [lineNumber, logFileLink])
     809                }
     810
     811                if(lineNumber % 100 == 0)
     812                    cleanUpGorm()
     813
     814                if(!result.error) nextLine()
     815            } //while(line)
     816
     817            // Success.
     818            log.info "End of file."
     819            reader.close()
     820            return result
     821
     822
     823         } //end withTransaction
     824    } // end importInventoryItemPurchases()
    644825
    645826    private getTemplateHeaderLine1() {
     
    648829            "Average Delivery Time", "Average Delivery Period", "Supplier's Part Number", "Preferred Supplier", "Alternate Suppliers",
    649830            "Manufacturer's Part Number", "Preferred Manufacturer", "Alternate Manufacturers", "Alternate Item", "Spare For"]
     831    }
     832
     833    private getPurchasesTemplateHeaderLine1() {
     834            ["Inventory Item*", "Purchase Order Number", "Quantity*", "Purchase Type*", "Cost Code*", "Entered By*",
     835            "Date Entered*", "Order Value", "Currency", "Invoice Number"]
    650836    }
    651837
  • trunk/grails-app/services/InventoryItemService.groovy

    r425 r441  
    2828    def show(params) {
    2929        def result = [:]
     30
    3031        def fail = { Map m ->
    3132            result.error = [ code: m.code, args: ["InventoryItem", params.id] ]
     
    3738        if(!result.inventoryItemInstance)
    3839            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            }
    3974
    4075        result.showTab = [:]
     
    4681                result.showTab.movement =  new String("true")
    4782                break
     83            case "showPurchasingTab":
     84                result.showTab.purchasing =  new String("true")
     85                break
    4886            default:
    4987                result.showTab.inventory = new String("true")
    5088        }
    5189
    52         def p = [:]
    5390        p.max = result.inventoryMovementListMax = 10
     91        p.offset = 0
    5492        p.order = "desc"
    5593        p.sort = "id"
    5694        result.inventoryMovementList = InventoryMovement.findAllByInventoryItem(result.inventoryItemInstance, p)
    5795        result.inventoryMovementListTotal = InventoryMovement.countByInventoryItem(result.inventoryItemInstance)
     96
    5897
    5998        // Success.
  • trunk/grails-app/views/inventoryItemDetailed/edit.gsp

    r435 r441  
    164164                                    <label for="averageDeliveryTime">Estimated Unit Price:</label>
    165165                                </td>
    166                                 <td valign="top">
     166                                <td valign="top" class="value">
    167167                                    <input  class="medium ${hasErrors(bean:inventoryItemInstance,field:'estimatedUnitPriceAmount','errors')}"
    168168                                                    type="text" id="estimatedUnitPriceAmount" name="estimatedUnitPriceAmount"
  • trunk/grails-app/views/inventoryItemDetailed/search.gsp

    r435 r441  
    7676                                        /
    7777                                        <g:link action="importInventory">
    78                                             Import
     78                                            Import Inventory
     79                                        </g:link>
     80                                        /
     81                                        <g:link action="importInventoryItemPurchases">
     82                                            Import Purchases
    7983                                        </g:link>
    8084                                    </td>
  • trunk/grails-app/views/inventoryItemDetailed/show.gsp

    r435 r441  
    4343                    <richui:tabLabel selected="${showTab.detail}" title="Detail" />
    4444                    <richui:tabLabel selected="${showTab.movement}" title="Movement" />
     45                    <richui:tabLabel selected="${showTab.purchasing}" title="Purchasing" />
    4546                </richui:tabLabels>
    4647
     
    384385<!-- End Movement tab -->
    385386
     387<!-- Start Purchases tab -->
     388                    <richui:tabContent>
     389
     390                        <g:if test="${inventoryItemPurchases.isEmpty()}">
     391                            <br />
     392                            No Inventory Purchases.
     393                            <br />
     394                            <br />
     395
     396                            <div class="buttons">
     397                                <g:form controller="inventoryItemPurchaseDetailed">
     398                                    <g:hiddenField name="inventoryItem.id" value="${inventoryItemInstance.id}" />
     399                                    <span class="button"><g:actionSubmit action="create" class="add" value="Order" /></span>
     400                                </g:form>
     401                            </div>
     402
     403                        </g:if>
     404                        <g:else>
     405
     406                            <div class="list">
     407                                <table>
     408                                    <thead>
     409                                        <tr>
     410                                            <g:sortableColumn action="show" property="purchaseOrderNumber"
     411                                                                                title="Order #" params="[paginate: 'purchases']"  />
     412                                            <g:sortableColumn action="show"  property="dateEntered"
     413                                                                                title="Date" params="[paginate: 'purchases']" />
     414                                            <g:sortableColumn action="show"  property="costCode"
     415                                                                                title="Cost Code" params="[paginate: 'purchases']" />
     416                                            <g:sortableColumn action="show"  property="quantity"
     417                                                                                title="Quantity" params="[paginate: 'purchases']" />
     418                                            <g:sortableColumn action="show"  property="orderValueAmount"
     419                                                                                title="Order \$" params="[paginate: 'purchases']" />
     420                                            <g:sortableColumn action="show"  property="invoiceNumber"
     421                                                                                title="Invoice Number" params="[paginate: 'purchases']" />
     422                                            <g:sortableColumn action="show"  property="inventoryItemPurchaseType"
     423                                                                                title="Type" params="[paginate: 'purchases']" />
     424                                            <th>
     425                                                <img  src="${resource(dir:'images/skin',file:'database_go_grey.png')}" alt="Show" title="Show" />
     426                                            </th>
     427                                            <th>
     428                                                <img  src="${resource(dir:'images/skin',file:'basket_put_grey.png')}" alt="Receive" title="Receive" />
     429                                            </th>
     430                                            <th>
     431                                                <img  src="${resource(dir:'images/skin',file:'tick_grey.png')}" alt="Approve" title="Approve Payment" />
     432                                            </th>
     433                                        </tr>
     434                                    </thead>
     435                                    <tbody>
     436                                        <g:each in="${inventoryItemPurchases}" status="i" var="purchase">
     437                                            <tr class="${(i % 2) == 0 ? 'clickableOdd' : 'clickableEven'}"/>
     438
     439                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
     440                                                    ${fieldValue(bean:purchase, field:'purchaseOrderNumber')}
     441                                                </td>
     442                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
     443                                                    <g:formatDate date="${purchase.dateEntered}" format="EEE, dd-MMM-yyyy"/>
     444                                                </td>
     445                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
     446                                                    ${fieldValue(bean:purchase, field:'costCode')}
     447                                                </td>
     448                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
     449                                                    ${fieldValue(bean:purchase, field:'quantity')}
     450                                                </td>
     451                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
     452                                                    ${fieldValue(bean:purchase, field:'orderValueAmount')}
     453                                                    ${fieldValue(bean:purchase, field:'orderValueCurrency')}
     454                                                </td>
     455                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
     456                                                    ${fieldValue(bean:purchase, field:'invoiceNumber')}
     457                                                </td>
     458                                                <td onclick='window.location = "${request.getContextPath()}/inventoryItemPurchaseDetailed/show/${purchase.id}"'>
     459                                                    ${fieldValue(bean:purchase, field:'inventoryItemPurchaseType')}
     460                                                </td>
     461                                                <td>
     462                                                    <g:link controller="inventoryItemPurchaseDetailed" action="show" id="${purchase.id}">
     463                                                        <img  src="${resource(dir:'images/skin',file:'database_go.png')}" alt="Show" title="Show" />
     464                                                    </g:link>
     465                                                </td>
     466                                                <g:if test="${purchase.inventoryItemPurchaseType.id == 1}">
     467                                                    <g:if test="${!purchase.receivedComplete}">
     468                                                        <td>
     469                                                            <g:link controller="inventoryItemPurchaseDetailed" action="receive" id="${purchase.id}">
     470                                                                <img  src="${resource(dir:'images/skin',file:'basket_put.png')}" alt="Receive" title="Receive" />
     471                                                            </g:link>
     472                                                        </td>
     473                                                    </g:if>
     474                                                    <g:else>
     475                                                        <td>
     476                                                        </td>
     477                                                    </g:else>
     478                                                    <g:if test="${!purchase.invoicePaymentApproved}">
     479                                                        <td>
     480                                                            <g:link controller="inventoryItemPurchaseDetailed" action="approveInvoicePayment" id="${purchase.id}">
     481                                                                <img  src="${resource(dir:'images/skin',file:'tick.png')}" alt="Approve" title="Approve Payment" />
     482                                                            </g:link>
     483                                                        </td>
     484                                                    </g:if>
     485                                                    <g:else>
     486                                                        <td>
     487                                                        </td>
     488                                                    </g:else>
     489                                                </g:if>
     490                                                <g:else>
     491                                                    <td>
     492                                                    </td>
     493                                                    <td>
     494                                                    </td>
     495                                                </g:else>
     496
     497                                            </tr>
     498                                        </g:each>
     499                                    </tbody>
     500                                </table>
     501                            </div>
     502
     503                            <div class="buttons">
     504                                <g:form controller="inventoryItemPurchaseDetailed">
     505                                    <g:hiddenField name="inventoryItem.id" value="${inventoryItemInstance.id}" />
     506                                    Results: ${inventoryItemPurchases.size()} / ${inventoryItemPurchasesTotal}
     507                                    <span class="button"><g:actionSubmit action="create" class="add" value="Order" /></span>
     508                                </g:form>
     509                            </div>
     510
     511                            <div class="paginateButtons">
     512                                <g:paginate action="show"
     513                                                        id="${inventoryItemInstance?.id}"
     514                                                        total="${inventoryItemPurchasesTotal}"
     515                                                        params="[paginate: 'purchases']" />
     516                            </div>
     517
     518                        </g:else>
     519
     520                    </richui:tabContent>
     521<!-- End Movement tab -->
     522
    386523                </richui:tabContents>
    387524            </richui:tabView>
    388 
    389525
    390526        </div>
Note: See TracChangeset for help on using the changeset viewer.