Ignore:
Timestamp:
Apr 11, 2011, 4:02:04 PM (11 years ago)
Author:
robert@…
Message:

Updated assay export to be able to export multiple assays or studies (in the search results page).
Also changed the assay export such that the assay can still be exported if the module is not reachable (without module measurements but with a message in the excel sheet)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/dbnp/studycapturing/AssayController.groovy

    r1730 r1752  
    33class AssayController {
    44
    5     def assayService
    6     def authenticationService
    7    
    8     static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
    9 
    10     def index = {
    11         redirect(action: "list", params: params)
    12     }
    13 
    14     def list = {
    15         params.max = Math.min(params.max ? params.int('max') : 10, 100)
    16         [assayInstanceList: Assay.list(params), assayInstanceTotal: Assay.count()]
    17     }
    18 
    19     def create = {
    20         def assayInstance = new Assay()
    21         assayInstance.properties = params
    22         return [assayInstance: assayInstance]
    23     }
    24 
    25     def save = {
    26         def assayInstance = new Assay(params)
    27 
    28         // The following lines deviate from the generate-all generated code.
    29         // See http://jira.codehaus.org/browse/GRAILS-3783 for why we have this shameful workaround...
    30         def study = assayInstance.parent
    31         study.addToAssays(assayInstance)
    32 
    33         if (assayInstance.save(flush: true)) {
    34             flash.message = "${message(code: 'default.created.message', args: [message(code: 'assay.label', default: 'Assay'), assayInstance.id])}"
    35             redirect(action: "show", id: assayInstance.id)
    36         }
    37         else {
    38             render(view: "create", model: [assayInstance: assayInstance])
    39         }
    40     }
    41 
    42     def show = {
    43         def assayInstance = Assay.get(params.id)
    44         if (!assayInstance) {
    45             flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
    46             redirect(action: "list")
    47         }
    48         else {
    49             [assayInstance: assayInstance]
    50         }
    51     }
     5        def assayService
     6        def authenticationService
     7
     8        static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
     9
     10        def index = {
     11                redirect(action: "list", params: params)
     12        }
     13
     14        def list = {
     15                params.max = Math.min(params.max ? params.int('max') : 10, 100)
     16                [assayInstanceList: Assay.list(params), assayInstanceTotal: Assay.count()]
     17        }
     18
     19        def create = {
     20                def assayInstance = new Assay()
     21                assayInstance.properties = params
     22                return [assayInstance: assayInstance]
     23        }
     24
     25        def save = {
     26                def assayInstance = new Assay(params)
     27
     28                // The following lines deviate from the generate-all generated code.
     29                // See http://jira.codehaus.org/browse/GRAILS-3783 for why we have this shameful workaround...
     30                def study = assayInstance.parent
     31                study.addToAssays(assayInstance)
     32
     33                if (assayInstance.save(flush: true)) {
     34                        flash.message = "${message(code: 'default.created.message', args: [message(code: 'assay.label', default: 'Assay'), assayInstance.id])}"
     35                        redirect(action: "show", id: assayInstance.id)
     36                }
     37                else {
     38                        render(view: "create", model: [assayInstance: assayInstance])
     39                }
     40        }
     41
     42        def show = {
     43                def assayInstance = Assay.get(params.id)
     44                if (!assayInstance) {
     45                        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
     46                        redirect(action: "list")
     47                }
     48                else {
     49                        [assayInstance: assayInstance]
     50                }
     51        }
    5252
    5353        def showByToken = {
    54             def assayInstance = Assay.findByAssayUUID(params.id)
    55             if (!assayInstance) {
    56                 flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
    57                 redirect(action: "list")
    58             }
    59             else {
    60                     redirect(action: "show", id: assayInstance.id)
    61             }
    62         }
    63 
    64     def edit = {
    65         def assayInstance = Assay.get(params.id)
    66         if (!assayInstance) {
    67             flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
    68             redirect(action: "list")
    69         }
    70         else {
    71             return [assayInstance: assayInstance]
    72         }
    73     }
    74 
    75     def update = {
    76         def assayInstance = Assay.get(params.id)
    77         if (assayInstance) {
    78             if (params.version) {
    79                 def version = params.version.toLong()
    80                 if (assayInstance.version > version) {
    81                    
    82                     assayInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'assay.label', default: 'Assay')] as Object[], "Another user has updated this Assay while you were editing")
    83                     render(view: "edit", model: [assayInstance: assayInstance])
    84                     return
    85                 }
    86             }
    87             assayInstance.properties = params
    88             if (!assayInstance.hasErrors() && assayInstance.save(flush: true)) {
    89                 flash.message = "${message(code: 'default.updated.message', args: [message(code: 'assay.label', default: 'Assay'), assayInstance.id])}"
    90                 redirect(action: "show", id: assayInstance.id)
    91             }
    92             else {
    93                 render(view: "edit", model: [assayInstance: assayInstance])
    94             }
    95         }
    96         else {
    97             flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
    98             redirect(action: "list")
    99         }
    100     }
    101 
    102     def delete = {
    103         def assayInstance = Assay.get(params.id)
    104         if (assayInstance) {
    105             try {
    106                 assayInstance.delete(flush: true)
    107                 flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
    108                 redirect(action: "list")
    109             }
    110             catch (org.springframework.dao.DataIntegrityViolationException e) {
    111                 flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
    112                 redirect(action: "show", id: params.id)
    113             }
    114         }
    115         else {
    116             flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
    117             redirect(action: "list")
    118         }
    119     }
    120 
    121     def excelExportFlow = {
    122         entry {
    123             action{
    124                 def user            = authenticationService.getLoggedInUser()
    125                 flow.userStudies    = Study.giveReadableStudies(user)
    126             }
    127             on("success").to "selectAssay"
    128         }
    129 
    130         selectAssay {
    131             on ("submit"){
    132                 flow.assay = Assay.get(params.assayId)
    133 
    134                 // check if assay exists
    135                 if (!flow.assay) throw new Exception("No assay found with id: ${flow.assay.id}")
    136 
    137                 // obtain fields for each category
    138                 flow.fieldMap = assayService.collectAssayTemplateFields(flow.assay)
    139 
    140                 flow.measurementTokens = flow.fieldMap.remove('Module Measurement Data')
    141             }.to "selectFields"
    142 
    143             on(Exception).to "handleError"
    144         }
    145 
    146         selectFields {
    147             on ("submit"){
    148                 def fieldMapSelection = [:]
    149 
    150                 flow.fieldMap.eachWithIndex { cat, cat_i ->
    151 
    152                     if (params."cat_$cat_i" == 'on') {
    153                         fieldMapSelection[cat.key] = []
    154 
    155                         cat.value.eachWithIndex { field, field_i ->
    156 
    157                             if (params."cat_${cat_i}_${field_i}" == 'on')
    158                                 fieldMapSelection[cat.key] += field
    159                         }
    160 
    161                         if (fieldMapSelection[cat.key] == [])
    162                             fieldMapSelection.remove(cat.key)
    163                     }
    164                 }
    165 
    166                 def measurementTokensSelection = []
    167 
    168                 if (params."cat_4" == 'on') {
    169 
    170                     def measurementToken = params.measurementToken
    171 
    172                     if (measurementToken)
    173                         if (measurementToken instanceof String)
    174                             measurementTokensSelection = [[name: measurementToken]]
    175                         else
    176                             measurementTokensSelection = measurementToken.collect{[name: it]}
    177                 }
    178 
    179                 def assayData           = assayService.collectAssayData(flow.assay, fieldMapSelection, measurementTokensSelection)
    180                 flow.rowData            = assayService.convertColumnToRowStructure(assayData)
    181                 flow.assayDataPreview   = flow.rowData[0..4].collect{ it[0..4] as ArrayList }
    182 
    183             }.to "compileExportData"
    184 
    185             on(Exception).to "handleError"
    186         }
    187 
    188         compileExportData {
    189             on ("ok"){session.rowData = flow.rowData}.to "export"
    190             on ("cancel").to "selectAssay"
    191         }
    192 
    193         export {
    194             redirect(action: 'doExport')
    195         }
    196 
    197         handleError() {
    198             render(view: 'errorPage')
    199         }
    200     }
    201 
    202     def doExport = {
    203 
    204         def filename = 'export.xlsx'
    205         response.setHeader("Content-disposition", "attachment;filename=\"${filename}\"")
    206         response.setContentType("application/octet-stream")
    207         try {
    208 
    209             assayService.exportRowWiseDataToExcelFile(session.rowData, response.outputStream)
    210             response.outputStream.flush()
    211 
    212         } catch (Exception e) {
    213 
    214             flash.errorMessage = e.message
    215             redirect action: 'errorPage'
    216 
    217         }
    218     }
    219 
    220     def errorPage = {
    221         render(view: 'excelExport/errorPage')
    222     }
     54                def assayInstance = Assay.findByAssayUUID(params.id)
     55                if (!assayInstance) {
     56                        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
     57                        redirect(action: "list")
     58                }
     59                else {
     60                        redirect(action: "show", id: assayInstance.id)
     61                }
     62        }
     63
     64        def edit = {
     65                def assayInstance = Assay.get(params.id)
     66                if (!assayInstance) {
     67                        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
     68                        redirect(action: "list")
     69                }
     70                else {
     71                        return [assayInstance: assayInstance]
     72                }
     73        }
     74
     75        def update = {
     76                def assayInstance = Assay.get(params.id)
     77                if (assayInstance) {
     78                        if (params.version) {
     79                                def version = params.version.toLong()
     80                                if (assayInstance.version > version) {
     81
     82                                        assayInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'assay.label', default: 'Assay')] as Object[], "Another user has updated this Assay while you were editing")
     83                                        render(view: "edit", model: [assayInstance: assayInstance])
     84                                        return
     85                                }
     86                        }
     87                        assayInstance.properties = params
     88                        if (!assayInstance.hasErrors() && assayInstance.save(flush: true)) {
     89                                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'assay.label', default: 'Assay'), assayInstance.id])}"
     90                                redirect(action: "show", id: assayInstance.id)
     91                        }
     92                        else {
     93                                render(view: "edit", model: [assayInstance: assayInstance])
     94                        }
     95                }
     96                else {
     97                        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
     98                        redirect(action: "list")
     99                }
     100        }
     101
     102        def delete = {
     103                def assayInstance = Assay.get(params.id)
     104                if (assayInstance) {
     105                        try {
     106                                assayInstance.delete(flush: true)
     107                                flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
     108                                redirect(action: "list")
     109                        }
     110                        catch (org.springframework.dao.DataIntegrityViolationException e) {
     111                                flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
     112                                redirect(action: "show", id: params.id)
     113                        }
     114                }
     115                else {
     116                        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'assay.label', default: 'Assay'), params.id])}"
     117                        redirect(action: "list")
     118                }
     119        }
     120
     121        def excelExportFlow = {
     122                entry {
     123                        action{
     124                                def user            = authenticationService.getLoggedInUser()
     125                                flow.userStudies    = Study.giveReadableStudies(user)
     126                        }
     127                        on("success").to "selectAssay"
     128                }
     129
     130                selectAssay {
     131                        on ("submit"){
     132                                flow.assay = Assay.get(params.assayId)
     133
     134                                // check if assay exists
     135                                if (!flow.assay) throw new Exception("No assay found with id: ${flow.assay.id}")
     136
     137                                // obtain fields for each category
     138                                flow.fieldMap = assayService.collectAssayTemplateFields(flow.assay)
     139
     140                                flow.measurementTokens = flow.fieldMap.remove('Module Measurement Data')
     141                        }.to "selectFields"
     142
     143                        on(Exception).to "handleError"
     144                }
     145
     146                selectFields {
     147                        on ("submit"){
     148                                def fieldMapSelection = [:]
     149
     150                                flow.fieldMap.eachWithIndex { cat, cat_i ->
     151
     152                                        if (params."cat_$cat_i" == 'on') {
     153                                                fieldMapSelection[cat.key] = []
     154
     155                                                cat.value.eachWithIndex { field, field_i ->
     156
     157                                                        if (params."cat_${cat_i}_${field_i}" == 'on')
     158                                                                fieldMapSelection[cat.key] += field
     159                                                }
     160
     161                                                if (fieldMapSelection[cat.key] == [])
     162                                                        fieldMapSelection.remove(cat.key)
     163                                        }
     164                                }
     165
     166                                def measurementTokens = []
     167
     168                                if (params."cat_4" == 'on') {
     169                                        measurementTokens = params.list( "measurementToken" )
     170                                }
     171
     172                                def assayData           = assayService.collectAssayData(flow.assay, fieldMapSelection, measurementTokens)
     173                                flow.rowData            = assayService.convertColumnToRowStructure(assayData)
     174                                flow.assayDataPreview   = flow.rowData[0..4].collect{ it[0..4] as ArrayList }
     175
     176                        }.to "compileExportData"
     177
     178                        on(Exception).to "handleError"
     179                }
     180
     181                compileExportData {
     182                        on ("ok"){session.rowData = flow.rowData}.to "export"
     183                        on ("cancel").to "selectAssay"
     184                }
     185
     186                export {
     187                        redirect(action: 'doExport')
     188                }
     189
     190                handleError() {
     191                        render(view: 'errorPage')
     192                }
     193        }
     194
     195        def doExport = {
     196
     197                def filename = 'export.xlsx'
     198                response.setHeader("Content-disposition", "attachment;filename=\"${filename}\"")
     199                response.setContentType("application/octet-stream")
     200                try {
     201
     202                        assayService.exportRowWiseDataToExcelFile(session.rowData, response.outputStream)
     203                        response.outputStream.flush()
     204
     205                } catch (Exception e) {
     206
     207                        flash.errorMessage = e.message
     208                        redirect action: 'errorPage'
     209
     210                }
     211        }
     212
     213        /**
     214         * Method to export one or more assays to excel in separate sheets.
     215         *
     216         * @param       params.ids              One or more assay IDs to export
     217         * @param       params.format   "list" in order to export all assays in one big excel sheet
     218         *                                                      "sheets" in order to export every assay on its own sheet (default)
     219         */
     220        def exportToExcel = {
     221                def format = params.get( 'format', 'sheets' );
     222                if( format == 'list' ) {
     223                        exportToExcelAsList( params );
     224                } else {
     225                        exportToExcelAsSheets( params );
     226                }
     227        }
     228
     229        /**
     230         * Method to export one or more assays to excel in separate sheets.
     231         *
     232         * @param       params.ids              One or more assay IDs to export
     233         */
     234        def exportToExcelAsSheets = {
     235                def ids = params.list( 'ids' ).findAll { it.isLong() }.collect { Long.valueOf( it ) };
     236
     237                if( !ids ) {
     238                        flash.errorMessage = "No assay ids given";
     239                        redirect( action: "errorPage" );
     240                        return;
     241                }
     242
     243                // Find all assays for the given ids
     244                def assays = ids.unique().collect { id -> Assay.get( id ) }.findAll { it }
     245
     246                // Send headers to the browser so the user can download the file
     247                def filename = 'export.xlsx'
     248                response.setHeader("Content-disposition", "attachment;filename=\"${filename}\"")
     249                response.setContentType("application/octet-stream")
     250
     251                try {
     252                        // Loop through all assays to collect the data
     253                        def rowWiseAssayData = [];
     254
     255                        assays.each { assay ->
     256                                // Determine which fields should be exported for this assay
     257                                def fieldMap = assayService.collectAssayTemplateFields(assay)
     258                                def measurementTokens = fieldMap.remove('Module Measurement Data')
     259
     260                                // Retrieve row based data for this assay
     261                                def assayData = assayService.collectAssayData( assay, fieldMap, measurementTokens );
     262                                def rowData   = assayService.convertColumnToRowStructure(assayData)
     263
     264                                // Put each assay on another sheet
     265                                rowWiseAssayData << rowData;
     266                        }
     267
     268                        assayService.exportRowWiseDataForMultipleAssaysToExcelFile( rowWiseAssayData, response.getOutputStream() )
     269
     270                        response.outputStream.flush()
     271
     272                } catch (Exception e) {
     273                        throw e;
     274                }
     275        }
     276
     277        /**
     278         * Method to export one or more assays to excel.
     279         *
     280         * @param       params.ids              One or more assay IDs to export
     281         */
     282        def exportToExcelAsList = {
     283                def ids = params.list( 'ids' ).findAll { it.isLong() }.collect { Long.valueOf( it ) };
     284
     285                if( !ids ) {
     286                        flash.errorMessage = "No assay ids given";
     287                        redirect( action: "errorPage" );
     288                        return;
     289                }
     290
     291                // If only 1 assay is asked for, don't bother with merging multiple assays.
     292                // In that case just use the export method to export one assay per sheet
     293                if( ids.size() == 1 )
     294                        return exportToExcelAsSheets( params );
     295
     296                // Find all assays for the given ids
     297                def assays = ids.unique().collect { id -> Assay.get( id ) }.findAll { it }
     298
     299                // Send headers to the browser so the user can download the file
     300                def filename = 'export.xlsx'
     301                response.setHeader("Content-disposition", "attachment;filename=\"${filename}\"")
     302                response.setContentType("application/octet-stream")
     303
     304                try {
     305                        // Loop through all assays to collect the data
     306                        def columnWiseAssayData = [];
     307
     308                        assays.each { assay ->
     309                                // Determine which fields should be exported for this assay
     310                                def fieldMap = assayService.collectAssayTemplateFields(assay)
     311                                def measurementTokens = fieldMap.remove('Module Measurement Data')
     312
     313                                // Retrieve row based data for this assay
     314                                def assayData = assayService.collectAssayData( assay, fieldMap, measurementTokens );
     315                               
     316                                // Prepend study and assay data to the list
     317                                assayData = assayService.prependAssayData( assayData, assay, assay.samples?.size() )
     318                                assayData = assayService.prependStudyData( assayData, assay, assay.samples?.size() )
     319                               
     320                                // Put each assay on another sheet
     321                                columnWiseAssayData << assayData;
     322                        }
     323                       
     324                        // Merge data from all assays
     325                        def mergedColumnWiseData = assayService.mergeColumnWiseDataOfMultipleStudies( columnWiseAssayData );
     326
     327                        def rowData   = assayService.convertColumnToRowStructure(mergedColumnWiseData)
     328                        assayService.exportRowWiseDataToExcelFile( rowData, response.getOutputStream() )
     329
     330                        response.outputStream.flush()
     331
     332                } catch (Exception e) {
     333                        throw e;
     334                }
     335        }
     336
     337
     338        def errorPage = {
     339                render(view: 'excelExport/errorPage')
     340        }
    223341}
Note: See TracChangeset for help on using the changeset viewer.