source: trunk/grails-app/controllers/dbnp/studycapturing/EventController.groovy @ 372

Last change on this file since 372 was 359, checked in by duh, 13 years ago
  • set keyword expansion
  • Property svn:keywords set to Date Author Rev
File size: 18.3 KB
Line 
1package dbnp.studycapturing
2import java.text.SimpleDateFormat
3import dbnp.data.Term
4import dbnp.data.Ontology
5
6class EventController {
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        [eventInstanceList: Event.list(params), eventInstanceTotal: Event.count()]
17    }
18
19
20    /*def createForEventDescription = {
21        if( params["id"]==null)
22        {
23            def eventInstance = new Event()
24            def sDate = new Date( params["startTime"])
25            def eDate = new Date( params["endTime"])
26            def description = EventDescription.findById((params["eventDescription"])["id"])
27            return [testo:params.clone(), sDate:sDate, eDate:eDate, description:description ]
28        }
29        else
30        {
31            def eventInstance = Event.get(params.id)
32            if (!eventInstance) {
33                flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
34                redirect(action: "list")
35            }
36            return [testo:params.clone(), sDate:eventInstance.startTime, eDate:eventInstance.endTime, description:eventInstance.eventDescription]
37        }
38    }*/
39
40
41    // Convert date strings to date strings grails can deal with.
42    // Input format:  "01/20/2010 08:45 am"
43    // Output format: "01/20/2010 20:45"
44    // Note: the "am" amd "pm" suffixes are removed.
45    def parseDate = {  st ->
46            def subst = st.substring(0,16)
47            def ampm =  st.substring(17,19)
48            if(ampm=="pm")
49            {
50                 def hours=st.substring(11,13)
51                 hours = hours.toInteger() + 12
52                 st = st.substring(0,11) + hours + st.substring(13,16)
53            }
54            else { st = st.substring(0,16) }
55
56            def sdfh = new SimpleDateFormat("MM/DD/yyyy hh:mm")
57            return sdfh.parse(st)
58    }
59
60
61
62
63    // helper function for save()
64    // parses the params from the edit view
65    // and saves paramters as new entries in the events value lists
66    def parseParamsForParameterValues( params, event ) {
67
68            params.each{ key,value ->
69                 def pattern =/(parameterValue\.)([\d]+)/
70                 def matcher = key=~pattern
71                 if(matcher) {
72                      def id = key.replaceAll(pattern,'$2')
73                      def parameter = ProtocolParameter.get(id)
74
75                      switch(parameter.type)
76                      {
77                            case dbnp.studycapturing.ProtocolParameterType.STRING:
78                                 event.parameterStringValues[parameter.name]=value
79                                 break
80                            case dbnp.studycapturing.ProtocolParameterType.FLOAT:
81                                 event.parameterFloatValues[parameter.name]=value.toFloat()
82                                 break
83                            case dbnp.studycapturing.ProtocolParameterType.INTEGER:
84                                 event.parameterFloatValues[parameter.name]=value.toInteger()
85                                 break
86                            case dbnp.studycapturing.ProtocolParameterType.STRINGLIST:
87                                 def item = ParameterStringListItem.get(value)
88                                 event.parameterStringListValues[''+parameter.id]=item
89                      }
90                 }
91            }
92    }
93
94
95
96    // assuming that an event has a sample
97    // return the first sample's subject
98    def getSubjectForEvent( event ) {
99        def samples =  Sample.getSamplesFor(event)
100        return samples[0].parentSubject
101    }
102
103
104
105
106    // helper function for save()
107    // parse params from the edit view
108    // and save all samples returned as a list
109    def parseParamsForNewSamples( params, event ) {
110
111        def subject = getSubjectForEvent( event )
112
113        def samples=[]
114            params.each{ k,v ->
115                 def pattern = /^(sampleName)([\d]+)/
116                 def matcher =  k=~pattern
117                 if(matcher) {
118                     def id = k.replaceAll(pattern,'$2')
119                     def sample = new Sample()
120                     sample.parentEvent = event
121                     sample.parentSubject = subject
122                     sample.name = v
123                     sample.material= Term.getTerm( params['sampleMaterial'+id] )
124                     saveSample(sample)
125                     samples.push(sample)
126                 }
127            }
128        return samples
129    }
130
131
132
133    // save a samle or handle errors
134    def saveSample(sample) {
135           if (sample.save(flush: true)) {
136                       flash.message = "${message(code: 'default.created.message', args: [message(code: 'event.label', default: 'Sample'), sample.id])}"
137            }
138            else {
139                    sample.errors.each{ println it }
140            }
141    }
142
143
144    // helper function for save()
145    // parse params from the edit view and save changes.
146    // Return all updated samples as a list
147    def parseParamsForOldSamples( params ) {
148        def samples=[]
149            params.each{ k,v ->
150                 def pattern = /^(sampleName_existing_)([\d]+)/
151                 def matcher =  k=~pattern
152                 if(matcher) {
153                     def id = k.replaceAll(pattern,'$2')
154                     def sample = Sample.get(id)
155                     sample.name = v
156                     sample.material= Term.getTerm( params['sampleMaterial_existing_'+id] )
157                     samples.push(sample)
158                     saveSample(sample)
159                 }
160            }
161        return samples
162    }
163
164
165    // helper function for save()
166    // delete a sample removed by the user
167    // Note: we completely delete this sample! It is also removed from the Study and the Assay!
168    def deleteSampelsRemovedByUser( originalSamples, remainingSamples) {
169
170        def toDelete = []
171        originalSamples.each { original ->
172            if( !remainingSamples.contains(original) ) 
173            { 
174                toDelete.push( original )
175            }
176        }
177
178        toDelete.each { 
179            Assay.list().each{ assay ->
180                if( assay.samples.contains((Sample)it) )
181                {
182                    assay.removeFromSamples(it)
183                }
184            }
185            Study.list().each{ study ->
186                if( study.samples.contains((Sample)it) )
187                {
188                    study.removeFromSamples(it)
189                }
190            }
191            ((Sample)it).delete()
192        }
193    }
194
195
196
197
198
199
200    def save = {
201
202        // create a new event from scratch
203
204        if( !(params['id']=~/^[\d]+$/) ) {
205
206            /* Not needed anymore: replace by template check?
207
208            def description = new EventDescription()
209            description.name = (params['name']==null || params['name'].replaceAll(/\S/,'').size()==0 ) ? '[no Name]' : params['name']
210            description.description = (params['description']==null || params['description'].replaceAll(/\w/,'').size()==0 ) ? '[no description]' : params['description']
211            description.protocol = Protocol.get( params['protocol'] )
212            description.isSamplingEvent = params['isSamplingEvent']=='on' ? true : false
213
214            if (description.save(flush: true)) {
215                flash.message = "${message(code: 'default.created.message', args: [message(code: 'description.label', default: 'Event'), description.id])}"
216            }
217            else {
218                description.errors.each{ println it }
219            }*/
220
221            def event = description.isSamplingEvent ? new SamplingEvent() : new Event();
222
223            event.startTime = new Date(params["startTime"])                   // parse the date strings
224            event.endTime = new Date(params["endTime"])                       // parse the date strings
225            event.parameterStringValues = new HashMap()
226            event.parameterFloatValues = new HashMap()
227            event.parameterIntegerValues = new HashMap()
228            event.parameterStringListValues = new HashMap()
229            event.eventDescription = description
230
231
232            if (event.save(flush:true, validate:false)) {
233                flash.message = "${message(code: 'default.created.message', args: [message(code: 'event.label', default: 'Event'), event.id])}"
234            }
235            else {
236                    event.errors.each{ println it }
237            }
238
239            // read params and add parameter values to event.
240            // (such as ParameterStringListValues, etc.
241            parseParamsForParameterValues( params, event )
242
243
244            if (event.save(flush: true)) {
245                flash.message = "${message(code: 'default.created.message', args: [message(code: 'event.label', default: 'Event'), event.id])}"
246            }
247            else {
248                    event.errors.each{ println it }
249            }
250
251
252        }
253
254
255        // modify an existing event
256
257        else { 
258
259            def event = Event.get(params['id'])
260
261            // save basic changes in event and event description
262
263            /* Not needed anymore: replace by template check?
264
265            def description = event.eventDescription
266            def oldProtocol = description.protocol
267
268            def name = params['name']
269            description.name = ( name==null || name.replaceAll(/\S/,'').size()==0 ) ? '[no Name]' : name
270            description.description = (params['description']==null || params['description'].replaceAll(/\w/,'').size()==0 ) ? '[no description]' : params['description']
271            description.isSamplingEvent = params['isSamplingEvent']=='on' ? true : false
272
273            */
274
275            event.startTime = new Date(params["startTime"])
276            event.endTime   = new Date(params["endTime"])
277
278
279            /* Not needed anymore: replace by template check?
280
281
282            // save changed parameters
283            description.protocol = Protocol.get( params['protocol'] )
284
285            // get the protocol
286            if(description.protocol!=oldProtocol)  {          // protocol changed
287
288                // remove all old parameter values
289
290                def removeAll = { values, memberName ->
291                    def list = values.getProperty(memberName)
292                }
293
294                removeAll(event, 'parameterStringValues' )
295                removeAll(event, 'parameterIntegerValues' )
296                removeAll(event, 'parameterFloatValues' )
297                removeAll(event, 'parameterStringListValues')
298
299
300                // add all new parameter values
301                parseParamsForParameterValues( params, event )
302
303
304            }
305
306            */
307
308
309            // update samples
310
311            if( event.isSamplingEvent() ) {
312
313                // remove deleted samples
314                // update existing samples
315
316                // add new samples
317
318                def originalSamples = Sample.getSamplesFor(event)               // samples that have been in this form before the edit
319
320                def newSamples = parseParamsForNewSamples( params, event )       //  get list of new samples as persistent sample objects
321                                                                                 //  also add all the samples to this event already
322                                                                                 //  by assigning event as parentEvent
323
324                def remainingSamples = parseParamsForOldSamples( params )        // samples, that have been in the form, and not deleted by the user
325                                                                                 // remainigSamples is subset of originalSamples
326
327                deleteSampelsRemovedByUser( originalSamples, remainingSamples)   // delete sample and remove it from parentSubject and the
328                                                                                 // associated study.
329
330            }
331
332            //((Event)event).eventDescription=description
333
334
335            if (event.save(flush: true)) {
336                 flash.message = "${message(code: 'default.created.message', args: [message(code: 'event.label', default: 'Event'), event.id])}"
337            }
338            else {
339                 event.errors.each{ println it }
340            }
341
342        }
343
344
345        render(action: "list", total:Event.count() )
346    }
347
348
349
350
351    def show = {
352        def eventInstance = Event.get(params.id)
353        if (!eventInstance) {
354            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
355            redirect(action: "list")
356        }
357        else {
358            [eventInstance: eventInstance]
359        }
360    }
361
362
363
364
365
366    def partial = {
367        println "In action: partial"
368        println params
369        def eventDescription = EventDescription.get(params.id)
370        if (!eventDescription) {
371            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
372            redirect(action: "list")
373        }
374        else {
375            [eventDescription: event]
376        }
377        redirect(view: 'partial')
378    }
379
380
381
382
383
384    // This action is not complete yet.
385    // (1) Need to include SamplingEvents.
386    // (2) This probably causes orphened PrtocolPrameters that have to be delt with.
387    //     The orphanes have to be managed centrally with the Protocols.
388    // (3) Parts of this might have to be moved into the Domain object's save() method.
389    // (4) The correspoding view's params are bloated and contain redundancy.
390    // (5) The whole thing should be moved to update.
391    // (6) A "create" should be added.
392
393    def edit = {
394
395        // create entirely new Event
396
397        if( params["id"]==null || params['id']=='' )
398        {
399            // New events cannot deal with Samples because there is not subject
400            // to assign samples to. Therefore, samples cannot be added to the a new
401            // Event, event if the user makes it a SamplingEvent by ticking a box.
402            // Therefore, showSample is set to false.
403
404            def eventInstance = new Event()
405            def sDate = new Date()
406            def eDate = new Date()
407            //def description = new EventDescription()
408            return [eventInstance:eventInstance, testo:params.clone(), sDate:sDate, eDate:eDate,
409                    //description:description,
410            showSample:false, samples:null, createNew:true ]
411        }
412
413
414        // edit an existing Event
415
416        else
417        {
418            def eventInstance = Event.get(params.id)
419            if (!eventInstance) {
420                flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
421                redirect(action: "list")
422            }
423            def samples = []
424            def showSample = false
425            if(eventInstance.isSamplingEvent() ) {
426                samples = ((SamplingEvent) eventInstance).getSamples()
427                if( samples.size() > 0 ) { showSample = true }
428                // later, also check of eventInstance's study contains any subjects, if so, show them as list to chose from
429            }
430
431            return [eventInstance:eventInstance, testo:params.clone(), sDate:eventInstance.startTime, eDate:eventInstance.endTime,
432                    // description:eventInstance.eventDescription,
433            showSample:showSample, samples:samples, createNew:false ]
434        }
435
436    }
437
438
439    def create = {
440        redirect(action:"edit", id:'')
441    }
442
443
444
445
446    def update = {
447        def eventInstance = Event.get(params.id)
448        if (eventInstance) {
449            if (params.version) {
450                def version = params.version.toLong()
451                if (eventInstance.version > version) {
452                   
453                    eventInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'event.label', default: 'Event')] as Object[], "Another user has updated this Event while you were editing")
454                    render(view: "edit", model: [eventInstance: eventInstance])
455                    return
456                }
457            }
458            eventInstance.properties = params
459            if (!eventInstance.hasErrors() && eventInstance.save(flush: true)) {
460                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'event.label', default: 'Event'), eventInstance.id])}"
461                redirect(action: "show", id: eventInstance.id)
462            }
463            else {
464                render(view: "edit", model: [eventInstance: eventInstance])
465            }
466        }
467        else {
468            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
469            redirect(action: "list")
470        }
471    }
472
473
474    def delete = {
475        def eventInstance = Event.get(params.id)
476        if (eventInstance) {
477            try {
478                eventInstance.delete(flush: true)
479                flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
480                redirect(action: "list")
481            }
482            catch (org.springframework.dao.DataIntegrityViolationException e) {
483                flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
484                redirect(action: "show", id: params.id)
485            }
486        }
487        else {
488            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
489            redirect(action: "list")
490        }
491    }
492
493
494
495    def showSample = {
496
497          println params
498          println "\n\nin showSample"
499          params.each{ x -> println x}
500          def samples = null
501          def event = Event.get(params.id)
502          if(event!=null)
503          {
504          def wantSample = params['wantSample']
505                                              // user wants this Event to be a SamplingEvent?
506          if( wantSample==null  &&  event.isSamplingEvent() )
507          {
508                println "want sample is null"
509                wantSample = true
510          }     
511          else {  println "want sample is " + params['wantSample']
512                  wantSample = params.wantSample <=>'no'?true:false }
513
514
515
516          if( event.isSamplingEvent() ) {
517              samples = Sample.findAll("from Sample as s where s.parentEvent.id = ${event.id}" )
518              samples.each{ println it.class }
519              samples.collect{ it.name }
520              println "yes ${event.id}"
521          }
522          else    println "no ${event.id}"
523
524
525          render( view:"showSample", model:[samples:samples,wantSample:wantSample,id:event.id] )
526          }
527    }
528
529
530   def deleteSample = {
531          // saves the samples from the page, then repaint the samples
532          println "in deleteSample"
533          println params
534
535          def event = Event.get(params['id'])
536
537          redirect( action:showSample, samples:newSample, wantSample:true,id:params['id'] )
538   }
539
540
541   def showEventDescription = {
542         def event = Event.get( params['id'] )
543         def description = EventDescription.get( params['eventDescriptionId'] )
544         render( view:"showEventDescription", model:[description:description] )
545   }
546
547
548   def deleteAllSamples = {
549        println "in deleteSamples"
550        println params
551        def event = Event.get(params['id'])
552        event.samples.each{ 
553            event.removeFromSamples(it)
554            it.delete(flush:true)
555        }
556
557        redirect( action:showSample, id:params['id'] )
558   }
559
560
561
562   def combobox = {
563        def event = Event.get(1)
564        def parameters = event.parameterStringValues
565        render( view:"combobox", model:[event:event,parameters:parameters] )
566   }
567}
Note: See TracBrowser for help on using the repository browser.