Changeset 633


Ignore:
Timestamp:
Jul 19, 2010, 8:47:38 AM (10 years ago)
Author:
gav
Message:

Domain change: Add PurchasingGroup?.
Logic and views to suite.

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

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/conf/Config.groovy

    r627 r633  
    401401            [order:91, controller:'inventoryItemPurchaseDetailed', title:'Edit', action:'edit', isVisible: { params.action == 'edit' }]
    402402        ]
     403    ],
     404    [order:230, controller:'purchasingGroupDetailed', title:'purchasingGroup', action:'list',
     405        subItems: [
     406            [order:10, controller:'purchasingGroupDetailed', title:'Purchasing Group List', action:'list', isVisible: { true }],
     407            [order:20, controller:'purchasingGroupDetailed', title:'Create', action:'create', isVisible: { true }],
     408            [order:90, controller:'purchasingGroupDetailed', title:'Show', action:'show', isVisible: { params.action == 'show' }],
     409            [order:91, controller:'purchasingGroupDetailed', title:'Edit', action:'edit', isVisible: { params.action == 'edit' }]
     410        ]
    403411    ]
    404412]
  • trunk/grails-app/controllers/CostCodeDetailedController.groovy

    r632 r633  
    7878            }
    7979            costCodeInstance.properties = params
     80            // Trim name to avoid spaces.
     81            costCodeInstance.name = costCodeInstance.name.trim()
    8082            if(!costCodeInstance.hasErrors() && costCodeInstance.save(flush: true)) {
    8183                flash.message = "CostCode ${params.id} updated"
     
    100102    def save = {
    101103        def costCodeInstance = new CostCode(params)
     104        // Trim name to avoid spaces.
     105        costCodeInstance.name = costCodeInstance.name.trim()
    102106        if(!costCodeInstance.hasErrors() && costCodeInstance.save(flush: true)) {
    103107            flash.message = "CostCode ${costCodeInstance.id} created"
  • trunk/grails-app/controllers/InventoryItemPurchaseDetailedController.groovy

    r615 r633  
    226226        params.returnTo = params.returnTo ?: 'inventoryItem'
    227227
    228         if(!result.error)
    229             return [ inventoryItemPurchaseInstance : result.inventoryItemPurchaseInstance ]
     228        def costCodes = []
     229
     230        if(!result.error) {
     231            if(inventoryPurchaseService.isPersonInPurchasingGroup(result.inventoryItemPurchaseInstance.costCode.purchasingGroup))
     232                costCodes = inventoryPurchaseService.getCostCodesByPerson()
     233
     234            return [ inventoryItemPurchaseInstance : result.inventoryItemPurchaseInstance,
     235                            'costCodes': costCodes ]
     236        }
    230237
    231238        flash.errorMessage = g.message(code: result.error.code, args: result.error.args)
     
    248255        }
    249256
    250         render(view:'edit', model:[inventoryItemPurchaseInstance: result.inventoryItemPurchaseInstance.attach()])
     257        result.inventoryItemPurchaseInstance.attach()
     258        result.inventoryItemPurchaseInstance.costCode.attach()
     259        result.inventoryItemPurchaseInstance.costCode.purchasingGroup.attach()
     260
     261        def costCodes = []
     262        if(inventoryPurchaseService.isPersonInPurchasingGroup(result.inventoryItemPurchaseInstance.costCode.purchasingGroup))
     263            costCodes = inventoryPurchaseService.getCostCodesByPerson()
     264
     265        render(view:'edit', model:[inventoryItemPurchaseInstance: result.inventoryItemPurchaseInstance,
     266                                                'costCodes': costCodes])
    251267    }
    252268
     
    262278        }
    263279
    264         return ['inventoryItemPurchaseInstance':inventoryItemPurchaseInstance]
     280        def costCodes = inventoryPurchaseService.getCostCodesByPerson()
     281
     282        return ['inventoryItemPurchaseInstance': inventoryItemPurchaseInstance,
     283                        'costCodes': costCodes]
    265284    }
    266285
     
    282301        }
    283302
     303        def costCodes = inventoryPurchaseService.getCostCodesByPerson()
     304
    284305        params.errorMessage = g.message(code: result.error.code, args: result.error.args)
    285         render(view:'create', model:['inventoryItemPurchaseInstance': result.inventoryItemPurchaseInstance])
     306        render(view:'create', model:['inventoryItemPurchaseInstance': result.inventoryItemPurchaseInstance,
     307                                                    'costCodes': costCodes])
    286308    }
    287309
  • trunk/grails-app/controllers/PersonController.groovy

    r628 r633  
    157157            person.properties = params
    158158            person.setPersonGroupsFromCheckBoxList(params.personGroups)
     159            person.setPurchasingGroupsFromCheckBoxList(params.purchasingGroups)
    159160
    160161            if(params.pass == "") {
     
    194195            person.password = authenticateService.encodePassword(params.pass)
    195196            person.setPersonGroupsFromCheckBoxList(params.personGroups)
     197            person.setPurchasingGroupsFromCheckBoxList(params.purchasingGroups)
    196198            if (person.save(flush: true)) {
    197199                addRemoveAuthorities(person)
  • trunk/grails-app/domain/CostCode.groovy

    r441 r633  
    11class CostCode {
     2
     3    PurchasingGroup purchasingGroup
     4
    25    String name
    36    String description = ""
     
    710
    811    static constraints = {
    9         name(maxSize:50,unique:true,blank:false)
     12        name(blank:false, maxSize:50, validator: {val, obj ->
     13            // Name must be unique for a purchasingGroup.
     14            def list = CostCode.withCriteria {
     15                eq('purchasingGroup', obj.purchasingGroup)
     16                eq('name', obj.name)
     17                if(obj.id)
     18                    notEqual('id', obj.id)
     19            }
     20            if(list.size() > 0)
     21                return 'not.unique.for.purchasing.group'
     22            // Success.
     23            return true
     24        })
    1025        description(maxSize:100)
    1126    }
    1227
    1328    String toString() {
    14         "${this.name}"
     29        "${this.name}.${this.purchasingGroup}"
    1530    }
     31
    1632}
  • trunk/grails-app/domain/Person.groovy

    r402 r633  
    77                        tasks: Task,
    88                        contacts: Contact,
    9                         addresses: Address]
     9                        addresses: Address,
     10                        purchasingGroups: PurchasingGroup]
    1011
    1112    static belongsTo = [Authority]
     
    6869    }
    6970
     71    //  This additional setter is used to convert the checkBoxList string or string array
     72    //  of ids selected to the corresponding domain objects.
     73    public void setPurchasingGroupsFromCheckBoxList(ids) {
     74        def idList = []
     75        if(ids instanceof String) {
     76                if(ids.isInteger())
     77                    idList << ids.toInteger()
     78        }
     79        else {
     80            ids.each() {
     81                if(it.isInteger())
     82                    idList << it.toInteger()
     83            }
     84        }
     85        this.purchasingGroups = idList.collect { PurchasingGroup.get( it ) }
     86    }
     87
    7088} // end class
  • trunk/grails-app/i18n/messages.properties

    r631 r633  
    4545person.pass.doesNotMatch=Passwords must match
    4646
     47costCode.name.not.unique.for.purchasing.group=CostCode name must be unique for purchasingGroup.
     48
    4749#
    4850# Help Balloon and property definitions.
     
    6163may also provide a record of persons qualified or trained in a specific area. \
    6264    Groups provide no application authorisations.
     65person.purchasingGroups=Purchasing Groups
     66person.purchasingGroups.help=Purchasing groups determine the available cost codes that a person may purchase against.
    6367person.loginName=Login Name
    6468person.loginName.help=This is the id or name that the person will use to login to the application.
     
    231235inventoryItemPurchase.delete.failure.payment.approved=Could not delete, payment has been approved.
    232236inventoryItemPurchase.operation.not.permitted.on.inactive.or.obsolete.item=This operation is not permitted on an inactive or obsolete inventory item.
     237inventoryItemPurchase.costCodes.not.found=No cost codes found, a person needs to be assigned to a purchasing group that has cost codes.
    233238
    234239assignedGroup.task.not.found=Please select a task and then ''Add Assigned Group''.
  • trunk/grails-app/services/CreateDataService.groovy

    r622 r633  
    115115
    116116        // Person and Utils
    117         createDemoPersons()
    118117        createDemoSites()
    119118        createDemoDepartments()
     
    121120        createDemoManufacturers()
    122121        createDemoProductionReference()
     122        createDemoPurchasingGroups()  /// @todo: Perhaps a 'createQuickStartData' method?
    123123        createDemoCostCodes()
     124        createDemoPersons()
    124125
    125126        // Assets
     
    307308        personInstance.addToAuthorities(Authority.get(2)) // ROLE_Manager.
    308309        personInstance.addToAuthorities(Authority.get(3)) // ROLE_AppUser.
     310        personInstance.addToPersonGroups(PersonGroup.get(1))
     311        personInstance.addToPurchasingGroups(PurchasingGroup.get(1))
     312        personInstance.addToPurchasingGroups(PurchasingGroup.get(2))
    309313
    310314        //Person #4
     
    697701    }
    698702
     703    void createDemoPurchasingGroups() {
     704
     705        // PurchasingGroup
     706        def purchasingGroupInstance
     707
     708        purchasingGroupInstance = new PurchasingGroup(name:"R&M")
     709        saveAndTest(purchasingGroupInstance)
     710
     711        purchasingGroupInstance = new PurchasingGroup(name:"Raw Materials")
     712        saveAndTest(purchasingGroupInstance)
     713
     714        purchasingGroupInstance = new PurchasingGroup(name:"Safety")
     715        saveAndTest(purchasingGroupInstance)
     716    }
     717
    699718    def createDemoCostCodes() {
    700719
     
    703722
    704723        // CostCode #1
    705         costCodeInstance = new CostCode(name: "RM Reelstand")
     724        costCodeInstance = new CostCode(name: "Reelstand.172",
     725                                                                    purchasingGroup: PurchasingGroup.get(1))
    706726        saveAndTest(costCodeInstance)
    707727
    708728        // CostCode #2
    709         costCodeInstance = new CostCode(name: "CAPEX Reelstand")
     729        costCodeInstance = new CostCode(name: "Reelstand.CAPEX",
     730                                                                    purchasingGroup: PurchasingGroup.get(1))
     731        saveAndTest(costCodeInstance)
     732
     733        // CostCode #2
     734        costCodeInstance = new CostCode(name: "PrintUnit.123",
     735                                                                    purchasingGroup: PurchasingGroup.get(3))
    710736        saveAndTest(costCodeInstance)
    711737    }
  • trunk/grails-app/services/InventoryPurchaseService.groovy

    r610 r633  
    8989    }
    9090
     91    /**
     92    * Get costCodes by person and the purchasingGroups they have been assigned.
     93    * @param person A Person, defaults to currentUser.
     94    * @returns A list of CostCodes.
     95    */
     96    def getCostCodesByPerson(person = authService.currentUser) {
     97        if(person.purchasingGroups) {
     98            CostCode.withCriteria {
     99                    eq('isActive', true)
     100                    or {
     101                        person.purchasingGroups.each() { purchasingGroup ->
     102                            eq('purchasingGroup', purchasingGroup)
     103                        }
     104                    }
     105            }.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } // withCriteria
     106        }
     107        else
     108            []
     109    } // getCostCodesByPerson
     110
     111    /**
     112    * Check if a person is in a purchasing group.
     113    * @param person A PurchasingGroup to check for.
     114    * @param person A Person, defaults to currentUser.
     115    * @returns True if person is in group.
     116    */
     117    def isPersonInPurchasingGroup(purchasingGroup, person = authService.currentUser) {
     118        for(pg in person.purchasingGroups) {
     119            if(pg.id == purchasingGroup.id)
     120                return true
     121        }
     122    } // isPersonInPurchasingGroup
     123
    91124    def delete(params) {
    92125        InventoryItemPurchase.withTransaction { status ->
  • trunk/grails-app/views/appCore/manager.gsp

    r624 r633  
    2727                                <a href="${createLink(controller:'personGroupDetailed', action:'list')}">Assigned Groups</a>
    2828                                <br />
     29                                <a href="${createLink(controller:'costCodeDetailed', action:'list')}">Cost Codes</a>
     30                                <br />
    2931                                <a href="${createLink(controller:'departmentDetailed', action:'list')}">Departments</a>
    3032                                <br />
     
    3840                                <br />
    3941                                <a href="${createLink(controller:'manufacturerDetailed', action:'list')}">Manufacturers</a>
     42                                <br />
     43                                <a href="${createLink(controller:'purchasingGroupDetailed', action:'list')}">Purchasing Groups</a>
    4044                                <br />
    4145                                <a href="${createLink(controller:'productionReferenceDetailed', action:'list')}">Production Reference</a>
  • trunk/grails-app/views/costCodeDetailed/create.gsp

    r441 r633  
    3535                            <tr class="prop">
    3636                                <td valign="top" class="name">
     37                                    <label for="purchasingGroup">Purchasing Group:</label>
     38                                </td>
     39                                <td valign="top" class="value ${hasErrors(bean:costCodeInstance,field:'purchasingGroup','errors')}">
     40                                    <g:select optionKey="id"
     41                                                    from="${PurchasingGroup.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }}"
     42                                                    name="purchasingGroup.id"
     43                                                    value="${costCodeInstance?.purchasingGroup?.id}" >
     44                                    </g:select>
     45                                    <p>
     46                                        <g:link controller="purchasingGroupDetailed" action="create">+Add Group</g:link>
     47                                    </p>
     48                                </td>
     49                            </tr>
     50                       
     51                            <tr class="prop">
     52                                <td valign="top" class="name">
    3753                                    <label for="description">Description:</label>
    3854                                </td>
  • trunk/grails-app/views/costCodeDetailed/edit.gsp

    r441 r633  
    3737                            <tr class="prop">
    3838                                <td valign="top" class="name">
     39                                    <label for="purchasingGroup">Purchasing Group:</label>
     40                                </td>
     41                                <td valign="top" class="value ${hasErrors(bean:costCodeInstance,field:'purchasingGroup','errors')}">
     42                                    <g:select optionKey="id"
     43                                                    from="${PurchasingGroup.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) }}"
     44                                                    name="purchasingGroup.id"
     45                                                    value="${costCodeInstance?.purchasingGroup?.id}" >
     46                                    </g:select>
     47                                    <p>
     48                                        <g:link controller="purchasingGroupDetailed" action="create">+Add Group</g:link>
     49                                    </p>
     50                                </td>
     51                            </tr>
     52                       
     53                            <tr class="prop">
     54                                <td valign="top" class="name">
    3955                                    <label for="description">Description:</label>
    4056                                </td>
  • trunk/grails-app/views/costCodeDetailed/list.gsp

    r498 r633  
    2323                                <g:sortableColumn property="name" title="Name" />
    2424                       
     25                            <g:sortableColumn property="purchasingGroup" title="Group" />
     26                       
    2527                                <g:sortableColumn property="description" title="Description" />
    2628                       
     
    4143                            <td onclick='window.location = "${request.getContextPath()}/costCodeDetailed/show/${costCodeInstance.id}"'>
    4244                                ${fieldValue(bean:costCodeInstance, field:'name')}
     45                            </td>
     46                       
     47                            <td onclick='window.location = "${request.getContextPath()}/costCodeDetailed/show/${costCodeInstance.id}"'>
     48                                ${fieldValue(bean:costCodeInstance, field:'purchasingGroup')}
    4349                            </td>
    4450                       
  • trunk/grails-app/views/costCodeDetailed/show.gsp

    r441 r633  
    3434                   
    3535                        <tr class="prop">
     36                            <td valign="top" class="name">Purchasing Group:</td>
     37                            <td valign="top" class="value">
     38                                <g:link controller="purchasingGroupDetailed" action="show" id="${costCodeInstance?.purchasingGroup?.id}">
     39                                    ${costCodeInstance?.purchasingGroup?.encodeAsHTML()}
     40                                </g:link>
     41                            </td>
     42                        </tr>
     43                   
     44                        <tr class="prop">
    3645                            <td valign="top" class="name">Description:</td>
    3746                           
     
    4453                           
    4554                            <td valign="top" class="value">${fieldValue(bean:costCodeInstance, field:'isActive')}</td>
    46                            
    47                         </tr>
    48                    
    49                         <tr class="prop">
    50                             <td valign="top" class="name">Inventory Item Purchases:</td>
    51                            
    52                             <td  valign="top" style="text-align:left;" class="value">
    53                                 <ul>
    54                                 <g:each var="i" in="${costCodeInstance.inventoryItemPurchases}">
    55                                     <li><g:link controller="inventoryItemPurchaseDetailed" action="show" id="${i.id}">${i?.encodeAsHTML()}</g:link></li>
    56                                 </g:each>
    57                                 </ul>
    58                             </td>
    5955                           
    6056                        </tr>
  • trunk/grails-app/views/inventoryItemPurchaseDetailed/create.gsp

    r609 r633  
    1515        <div class="body">
    1616            <g:render template="/shared/messages" />
     17            <g:if test="${!costCodes}" >
     18                <div class="errors">
     19                    <ul>
     20                        <li><g:message code="inventoryItemPurchase.costCodes.not.found" /><li>
     21                </div>
     22            </g:if>
    1723            <g:hasErrors bean="${inventoryItemPurchaseInstance}">
    1824            <div class="errors">
     
    6672                                <td valign="top" class="value ${hasErrors(bean:inventoryItemPurchaseInstance,field:'costCode','errors')}">
    6773                                    <g:select optionKey="id"
    68                                                         from="${ CostCode.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } }"
     74                                                        from="${ costCodes }"
    6975                                                        name="costCode.id"
    7076                                                        value="${inventoryItemPurchaseInstance?.costCode?.id}"
  • trunk/grails-app/views/inventoryItemPurchaseDetailed/edit.gsp

    r609 r633  
    5959                                </td>
    6060                            </tr>
    61                        
     61
    6262                            <tr class="prop">
    6363                                <td valign="top" class="name">
     
    6565                                </td>
    6666                                <td valign="top" class="value ${hasErrors(bean:inventoryItemPurchaseInstance,field:'costCode','errors')}">
    67                                     <g:select optionKey="id"
    68                                                         from="${ CostCode.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } }"
    69                                                         name="costCode.id"
    70                                                         value="${inventoryItemPurchaseInstance?.costCode?.id}" >
    71                                     </g:select>
     67                                    <g:if test="${costCodes}">
     68                                        <g:select optionKey="id"
     69                                                            from="${ costCodes }"
     70                                                            name="costCode.id"
     71                                                            value="${inventoryItemPurchaseInstance.costCode?.id}" >
     72                                        </g:select>
     73                                    </g:if>
     74                                    <g:else>
     75                                        <g:link controller="costCodeDetailed" action="show" id="${inventoryItemPurchaseInstance?.costCode?.id}">
     76                                            ${inventoryItemPurchaseInstance?.costCode?.encodeAsHTML()}
     77                                        </g:link>
     78                                    </g:else>
    7279                                    <g:helpBalloon code="inventoryItemPurchase.cost.code" />
    7380                                </td>
     
    96103                                                        from="${ Supplier.findAllByIsActive(true).sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } }"
    97104                                                        name="supplier.id"
    98                                                         value="${inventoryItemPurchaseInstance?.supplier?.id}"
    99                                                         noSelection="['null':/${g.message(code:'default.please.select.text')}/]">
     105                                                        value="${inventoryItemPurchaseInstance?.supplier?.id}">
    100106                                    </g:select>
    101107                                    <g:helpBalloon code="inventoryItemPurchase.supplier" />
  • trunk/grails-app/views/person/create.gsp

    r506 r633  
    105105
    106106                    <tr class="prop">
     107                        <td valign="top" class="name">
     108                            <label for="purchasingGroups">Purchasing Groups:</label>
     109                        </td>
     110                        <td valign="top" class="value ${hasErrors(bean:person,field:'purchasingGroups','errors')}">
     111                            <g:helpBalloon class="helpballoon" code="person.purchasingGroups" />
     112                            <custom:checkBoxList name="purchasingGroups"
     113                                                            from="${PurchasingGroup.findAllByIsActive(true)}"
     114                                                            value="${person?.purchasingGroups?.collect{it.id}}"
     115                                                            optionKey="id"
     116                                                            sortBy="name"
     117                                                            linkController="purchasingGroupDetailed"
     118                                                            linkAction="show"/>
     119                            <g:link controller="purchasingGroupDetailed" action="create">+Add Group</g:link>
     120                        </td>
     121                    </tr>
     122
     123                    <tr class="prop">
    107124                        <td valign="top" class="name" align="left">
    108125                            Authorities:
  • trunk/grails-app/views/person/edit.gsp

    r506 r633  
    144144
    145145                    <tr class="prop">
     146                        <td valign="top" class="name">
     147                            <label for="purchasingGroups">Purchasing Groups:</label>
     148                        </td>
     149                        <td valign="top" class="value ${hasErrors(bean:person,field:'purchasingGroups','errors')}">
     150                            <g:helpBalloon class="helpballoon" code="person.purchasingGroups" />
     151                            <custom:checkBoxList name="purchasingGroups"
     152                                                            from="${PurchasingGroup.findAllByIsActive(true)}"
     153                                                            value="${person?.purchasingGroups?.collect{it.id}}"
     154                                                            optionKey="id"
     155                                                            sortBy="name"
     156                                                            linkController="purchasingGroupDetailed"
     157                                                            linkAction="show"/>
     158                            <g:link controller="purchasingGroupDetailed" action="create">+Add Group</g:link>
     159                        </td>
     160                    </tr>
     161
     162                    <tr class="prop">
    146163                        <td valign="top" class="name" align="left">
    147164                            Authorities:
  • trunk/grails-app/views/person/show.gsp

    r402 r633  
    8989                    <td valign="top" class="value">
    9090                        <ul>
    91                         <g:each in="${person.personGroups}" var='group'>
    92                             <li>${group}</li>
     91                        <g:each var='group' in="${ person.personGroups.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } }">
     92                            <li>
     93                                <g:link controller="personGroupDetailed"
     94                                                action="show"
     95                                                id="${group.id}">
     96                                    ${group.encodeAsHTML()}
     97                                </g:link>
     98                            </li>
     99                        </g:each>
     100                        </ul>
     101                    </td>
     102                </tr>
     103
     104                <tr class="prop">
     105                    <td valign="top" class="name">Purchasing Groups:</td>
     106                    <td valign="top" class="value">
     107                        <ul>
     108                        <g:each  var='a' in="${ person.purchasingGroups.sort { p1, p2 -> p1.name.compareToIgnoreCase(p2.name) } }">
     109                            <li>
     110                                <g:link controller="purchasingGroupDetailed"
     111                                                action="show"
     112                                                id="${a.id}">
     113                                    ${a.encodeAsHTML()}
     114                                </g:link>
     115                            </li>
    93116                        </g:each>
    94117                        </ul>
Note: See TracChangeset for help on using the changeset viewer.