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

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

Sort MaintenanceActions at create and update time.

File size: 9.8 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            // Sort MaintenanceActions.
81            result.taskProcedureInstance.maintenanceActions.sort { p1, p2 -> p1.procedureStepNumber <=> p2.procedureStepNumber }
82
83            def r = createRevision(result.taskProcedureInstance)
84            if(r.error)
85                return fail(field:'id', code:"default.create.revision.failure")
86
87            // Also sets: taskInstance.taskProcedureRevision = taskProcedureRevision
88            r.taskProcedureRevision.addToTasks(result.taskProcedureInstance.linkedTask)
89
90            // Update tasks that are using previousRevision.
91            // Only those that are not started and due to be started today or in the future.
92            def previousRevision = result.taskProcedureInstance.getRevision(r.taskProcedureRevision.revision - 1)
93            if(previousRevision) {
94                Task.withCriteria {
95                    eq("taskProcedureRevision", previousRevision)
96                    ge("targetStartDate", dateUtilService.today)
97                    taskStatus {
98                        idEq(1L) // Not Started.
99                    }
100                    maxResults(10000)
101                }.each {
102                    it.taskProcedureRevision = r.taskProcedureRevision
103                }
104            }
105
106            // Success.
107            return result
108
109        } // end withTransaction
110    }  // end update()
111
112    /**
113    * Creates a new taskProcedure with the given params.
114    * @param params The params to use when creating the new taskProcedure.
115    * @returns A map containing result.error (if any error) and result.taskProcedure.
116    */
117    def save(params) {
118        def result = [:]
119        TaskProcedure.withTransaction { status ->
120            def fail = { Map m ->
121                status.setRollbackOnly()
122                if(result.taskProcedureInstance && m.field)
123                    result.taskProcedureInstance.errors.rejectValue(m.field, m.code)
124                result.error = [ code: m.code, args: ["TaskProcedure", params.id] ]
125                // Fetch to prevent lazy initialization error.
126                result.taskProcedureInstance.linkedTask.primaryAsset
127                return result
128            }
129
130            result.taskProcedureInstance = new TaskProcedure(params)
131
132            // Optimistic locking check on linkedTask.
133            if(result.taskProcedureInstance.linkedTask.taskProcedureRevision)
134                    return fail(field:"version", code:"default.optimistic.locking.failure")
135
136            // Gaps in the html index's can be created by adding 2 items and removing the first one.
137            // This creates a gap at the missing index where LazyList will return a null.
138            def nullMaintenanceActions = result.taskProcedureInstance.maintenanceActions.findAll {!it}
139            if (nullMaintenanceActions) {
140                result.taskProcedureInstance.maintenanceActions.removeAll(nullMaintenanceActions)
141            }
142            def nullDocumentReferences = result.taskProcedureInstance.documentReferences.findAll {!it}
143            if (nullDocumentReferences) {
144                result.taskProcedureInstance.documentReferences.removeAll(nullDocumentReferences)
145            }
146
147            if(result.taskProcedureInstance.hasErrors() || !result.taskProcedureInstance.save()) {
148                // Populate collection errors for display.
149                result.taskProcedureInstance.maintenanceActions.each { it.validate() }
150                result.taskProcedureInstance.documentReferences.each { it.validate() }
151                return fail(code:"default.create.failure")
152            }
153
154            // Sort MaintenanceActions.
155            result.taskProcedureInstance.maintenanceActions.sort { p1, p2 -> p1.procedureStepNumber <=> p2.procedureStepNumber }
156
157            def r = createRevision(result.taskProcedureInstance)
158            if(r.error)
159                return fail(field:'id', code:"default.create.revision.failure")
160
161            // Also sets: taskInstance.taskProcedureRevision = taskProcedureRevision
162            r.taskProcedureRevision.addToTasks(result.taskProcedureInstance.linkedTask)
163
164        } // end withTransaction
165
166        // Success.
167        return result
168    }  // end save()
169
170    /**
171    * Creates a new taskProcedureRevision.
172    * @param taskProcedureInstance The taskProcedure to create the revision for.
173    * @returns A map containing result.error (if any error) and result.taskProcedureRevision.
174    */
175    def createRevision(taskProcedureInstance) {
176        def result = [:]
177        TaskProcedureRevision.withTransaction { status ->
178            def fail = { Map m ->
179                status.setRollbackOnly()
180                if(result.taskProcedureRevision && m.field)
181                    result.taskProcedureRevision.errors.rejectValue(m.field, m.code)
182                result.error = [ code: m.code, args: ["TaskProcedureRevision"] ]
183                return result
184            }
185
186            result.taskProcedureRevision = new TaskProcedureRevision()
187            taskProcedureInstance.addToRevisions(result.taskProcedureRevision)
188
189            result.taskProcedureRevision.taskProcedure = taskProcedureInstance
190            result.taskProcedureRevision.linkedTask = taskProcedureInstance.linkedTask
191            result.taskProcedureRevision.createdBy =  authService.currentUser
192            result.taskProcedureRevision.revision = 0 // init to prevent DataIntegrityViolationException
193            result.taskProcedureRevision.revision = taskProcedureInstance.revision
194            taskProcedureInstance.maintenanceActions.each {
195                result.taskProcedureRevision.addToMaintenanceActions(new MaintenanceAction(it.properties))
196            }
197            taskProcedureInstance.documentReferences.each {
198                result.taskProcedureRevision.addToDocumentReferences(new DocumentReference(it.properties))
199            }
200
201            if(result.taskProcedureRevision.hasErrors() || !result.taskProcedureRevision.save()) {
202                log.error result.taskProcedureRevision.errors
203                return fail(code:"default.create.failure")
204            }
205
206        } // end withTransaction
207
208        // Success.
209        return result
210    } // end createRevision()
211
212} // end class
Note: See TracBrowser for help on using the repository browser.