package dbnp.studycapturing import dbnp.authentication.SecUser /** * Domain class describing the basic entity in the study capture part: the Study class. * * Revision information: * $Rev: 1357 $ * $Author: robert@isdat.nl $ * $Date: 2011-01-10 15:44:44 +0000 (ma, 10 jan 2011) $ */ class Study extends TemplateEntity { static searchable = true def synchronizationService SecUser owner // The owner of the study. A new study is automatically owned by its creator. String title // The title of the study String description // A brief synopsis of what the study is about String code // currently used as the external study ID, e.g. to reference a study in a SAM module Date dateCreated Date lastUpdated Date startDate List subjects List events List samplingEvents List eventGroups List samples List assays boolean published = false // Determines whether a study is private (only accessable by the owner and writers) or published (also visible to readers) boolean publicstudy = false // Determines whether anonymous users are allowed to see this study. This has only effect when published = true static hasMany = [ subjects: Subject, samplingEvents: SamplingEvent, events: Event, eventGroups: EventGroup, samples: Sample, assays: Assay, persons: StudyPerson, publications: Publication, readers: SecUser, writers: SecUser ] static constraints = { owner(nullable: true, blank: true) code(nullable: false, blank: true, unique: true) // TODO: add custom validator for 'published' to assess whether the study meets all quality criteria for publication // tested by SampleTests.testStudyPublish } static mapping = { autoTimestamp true sort "title" // Make sure the TEXT field description is persisted with a TEXT field in the database description type: 'text' // Workaround for bug http://jira.codehaus.org/browse/GRAILS-6754 templateTextFields type: 'text' } // The external identifier (studyToken) is currently the code of the study. // It is used from within dbNP submodules to refer to particular study in this GSCF instance. def getToken() { code } /** * return the domain fields for this domain class * @return List */ static List giveDomainFields() { return Study.domainFields } static final List domainFields = [ new TemplateField( name: 'title', type: TemplateFieldType.STRING, required: true), new TemplateField( name: 'description', type: TemplateFieldType.TEXT, comment:'Give a brief synopsis of what your study is about', required: true), new TemplateField( name: 'code', type: TemplateFieldType.STRING, preferredIdentifier: true, comment: 'Fill out the code by which many people will recognize your study', required: true), new TemplateField( name: 'startDate', type: TemplateFieldType.DATE, comment: 'Fill out the official start date or date of first action', required: true), new TemplateField( name: 'published', type: TemplateFieldType.BOOLEAN, comment: 'Determines whether this study is published (accessible for the study readers and, if the study is public, for anonymous users). A study can only be published if it meets certain quality criteria, which will be checked upon save.', required: false) ] /** * return the title of this study */ def String toString() { return title } /** * returns all events and sampling events that do not belong to a group */ def List getOrphanEvents() { def orphans = events.findAll { event -> !event.belongsToGroup(eventGroups) } + samplingEvents.findAll { event -> !event.belongsToGroup(eventGroups) } return orphans } /** * Return the unique Subject templates that are used in this study */ def List