source: trunk/grails-app/controllers/dbnp/studycapturing/AssayController.groovy @ 1752

Last change on this file since 1752 was 1752, checked in by robert@…, 11 years ago

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)

  • Property svn:keywords set to Rev Author Date
File size: 10.0 KB
Line 
1package dbnp.studycapturing
2
3class AssayController {
4
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        }
52
53        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 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        }
341}
Note: See TracBrowser for help on using the repository browser.