source: trunk/grails-app/services/TaskProcedureService.groovy @ 809

Last change on this file since 809 was 809, checked in by gav, 9 years ago

Domain change, first draft of TaskProcedureRevisions.

File size: 9.5 KB
Line 
1/**
2* Provides a service class for the TaskProcedure domain class.
3*/
4class TaskProcedureService {
5
6    boolean transactional = false
7
8    def authService
9    def dateUtilService
10
11    /**
12    * Updates an existing taskProcedure.
13    * @param params The params to update for taskProcedure with id of params.id.
14    * @returns A map containing result.error (if any error) and result.taskProcedureInstance (if available).
15    */
16    def update(params) {
17        TaskProcedure.withTransaction { status ->
18            def result = [:]
19
20            def fail = { Map m ->
21                status.setRollbackOnly()
22                if(result.taskProcedureInstance && m.field)
23                    result.taskProcedureInstance.errors.rejectValue(m.field, m.code)
24                result.error = [ code: m.code, args: ["TaskProcedure", params.id] ]
25                // Fetch to prevent lazy initialization error.
26                result.taskProcedureInstance.revisions.each {it.createdBy.toString()}
27                return result
28            }
29
30            result.taskProcedureInstance = TaskProcedure.get(params.id)
31
32            if(!result.taskProcedureInstance)
33                return fail(code:"default.not.found")
34
35            // Optimistic locking check.
36            if(params.version) {
37                if(result.taskProcedureInstance.version > params.version.toLong())
38                    return fail(field:"version", code:"default.optimistic.locking.failure")
39            }
40
41            result.taskProcedureInstance.properties = params
42
43            // Gaps in the html index's can be created by adding 2 items and removing the first one.
44            // This creates a gap at the missing index where LazyList will return a null.
45            def nullMaintenanceActions = result.taskProcedureInstance.maintenanceActions.findAll {!it}
46            if (nullMaintenanceActions) {
47                result.taskProcedureInstance.maintenanceActions.removeAll(nullMaintenanceActions)
48            }
49            def nullDocumentReferences = result.taskProcedureInstance.documentReferences.findAll {!it}
50            if (nullDocumentReferences) {
51                result.taskProcedureInstance.documentReferences.removeAll(nullDocumentReferences)
52            }
53
54            // Save for restoration if validation fails.
55            def savedMaintenanceActions = new ArrayList(result.taskProcedureInstance.maintenanceActions)
56            def savedDocumentReferences = new ArrayList(result.taskProcedureInstance.documentReferences)
57
58            // Remove toBeDeleted before validation.
59            def ma_toBeDeleted = result.taskProcedureInstance.maintenanceActions.findAll {it.toBeDeleted}
60            if (ma_toBeDeleted) {
61                result.taskProcedureInstance.maintenanceActions.removeAll(ma_toBeDeleted)
62            }
63            def docRef_toBeDeleted = result.taskProcedureInstance.documentReferences.findAll {it.toBeDeleted}
64            if (docRef_toBeDeleted) {
65                result.taskProcedureInstance.documentReferences.removeAll(docRef_toBeDeleted)
66            }
67
68            if(result.taskProcedureInstance.hasErrors() || !result.taskProcedureInstance.save()) {
69                // Restore the saved items, some of which contain toBeDeleted flags but
70                // have not been deleted yet since validation failed.
71                // The toBeDeleted items are hidden in the view.
72                result.taskProcedureInstance.maintenanceActions = savedMaintenanceActions
73                result.taskProcedureInstance.documentReferences = savedDocumentReferences
74                // Populate collection errors for display.
75                result.taskProcedureInstance.maintenanceActions.each { it.validate() }
76                result.taskProcedureInstance.documentReferences.each { it.validate() }
77                return fail(code:"default.update.failure")
78            }
79
80            def r = createRevision(result.taskProcedureInstance)
81            if(r.error)
82                return fail(field:'id', code:"default.create.revision.failure")
83
84            // Also sets: taskInstance.taskProcedureRevision = taskProcedureRevision
85            r.taskProcedureRevision.addToTasks(result.taskProcedureInstance.linkedTask)
86
87            // Update tasks that are using previousRevision.
88            // Only those that are not started and due to be started today or in the future.
89            def previousRevision = result.taskProcedureInstance.getRevision(r.taskProcedureRevision.revision - 1)
90            if(previousRevision) {
91                Task.withCriteria {
92                    eq("taskProcedureRevision", previousRevision)
93                    ge("targetStartDate", dateUtilService.today)
94                    taskStatus {
95                        idEq(1L) // Not Started.
96                    }
97                    maxResults(10000)
98                }.each {
99                    it.taskProcedureRevision = r.taskProcedureRevision
100                }
101            }
102
103            // Success.
104            return result
105
106        } // end withTransaction
107    }  // end update()
108
109    /**
110    * Creates a new taskProcedure with the given params.
111    * @param params The params to use when creating the new taskProcedure.
112    * @returns A map containing result.error (if any error) and result.taskProcedure.
113    */
114    def save(params) {
115        def result = [:]
116        TaskProcedure.withTransaction { status ->
117            def fail = { Map m ->
118                status.setRollbackOnly()
119                if(result.taskProcedureInstance && m.field)
120                    result.taskProcedureInstance.errors.rejectValue(m.field, m.code)
121                result.error = [ code: m.code, args: ["TaskProcedure", params.id] ]
122                // Fetch to prevent lazy initialization error.
123                result.taskProcedureInstance.linkedTask.primaryAsset
124                return result
125            }
126
127            result.taskProcedureInstance = new TaskProcedure(params)
128
129            // Optimistic locking check on linkedTask.
130            if(result.taskProcedureInstance.linkedTask.taskProcedureRevision)
131                    return fail(field:"version", code:"default.optimistic.locking.failure")
132
133            // Gaps in the html index's can be created by adding 2 items and removing the first one.
134            // This creates a gap at the missing index where LazyList will return a null.
135            def nullMaintenanceActions = result.taskProcedureInstance.maintenanceActions.findAll {!it}
136            if (nullMaintenanceActions) {
137                result.taskProcedureInstance.maintenanceActions.removeAll(nullMaintenanceActions)
138            }
139            def nullDocumentReferences = result.taskProcedureInstance.documentReferences.findAll {!it}
140            if (nullDocumentReferences) {
141                result.taskProcedureInstance.documentReferences.removeAll(nullDocumentReferences)
142            }
143
144            if(result.taskProcedureInstance.hasErrors() || !result.taskProcedureInstance.save()) {
145                // Populate collection errors for display.
146                result.taskProcedureInstance.maintenanceActions.each { it.validate() }
147                result.taskProcedureInstance.documentReferences.each { it.validate() }
148                return fail(code:"default.create.failure")
149            }
150
151            def r = createRevision(result.taskProcedureInstance)
152            if(r.error)
153                return fail(field:'id', code:"default.create.revision.failure")
154
155            // Also sets: taskInstance.taskProcedureRevision = taskProcedureRevision
156            r.taskProcedureRevision.addToTasks(result.taskProcedureInstance.linkedTask)
157
158        } // end withTransaction
159
160        // Success.
161        return result
162    }  // end save()
163
164    /**
165    * Creates a new taskProcedureRevision.
166    * @param taskProcedureInstance The taskProcedure to create the revision for.
167    * @returns A map containing result.error (if any error) and result.taskProcedureRevision.
168    */
169    def createRevision(taskProcedureInstance) {
170        def result = [:]
171        TaskProcedureRevision.withTransaction { status ->
172            def fail = { Map m ->
173                status.setRollbackOnly()
174                if(result.taskProcedureRevision && m.field)
175                    result.taskProcedureRevision.errors.rejectValue(m.field, m.code)
176                result.error = [ code: m.code, args: ["TaskProcedureRevision"] ]
177                return result
178            }
179
180            result.taskProcedureRevision = new TaskProcedureRevision()
181            taskProcedureInstance.addToRevisions(result.taskProcedureRevision)
182
183            result.taskProcedureRevision.taskProcedure = taskProcedureInstance
184            result.taskProcedureRevision.linkedTask = taskProcedureInstance.linkedTask
185            result.taskProcedureRevision.createdBy =  authService.currentUser
186            result.taskProcedureRevision.revision = 0 // init to prevent DataIntegrityViolationException
187            result.taskProcedureRevision.revision = taskProcedureInstance.revision
188            taskProcedureInstance.maintenanceActions.each {
189                result.taskProcedureRevision.addToMaintenanceActions(new MaintenanceAction(it.properties))
190            }
191            taskProcedureInstance.documentReferences.each {
192                result.taskProcedureRevision.addToDocumentReferences(new DocumentReference(it.properties))
193            }
194
195            if(result.taskProcedureRevision.hasErrors() || !result.taskProcedureRevision.save()) {
196                log.error result.taskProcedureRevision.errors
197                return fail(code:"default.create.failure")
198            }
199
200        } // end withTransaction
201
202        // Success.
203        return result
204    } // end createRevision()
205
206} // end class
Note: See TracBrowser for help on using the repository browser.