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

Last change on this file since 967 was 964, checked in by gav, 12 years ago

Fix for ticket #105 - InventoryItemPurchase?'s can't be deleted when order quantity = 0 and allows the order to be deleted.

File size: 6.3 KB
Line 
1class InventoryMovementService {
2
3    boolean transactional = false
4
5    def authService
6    def authenticateService
7
8    def reverseMove(params) {
9        InventoryMovement.withTransaction { status ->
10            def result = [:]
11            params =  params ?: [:]
12
13            def fail = { Map m ->
14                status.setRollbackOnly()
15                if(result.inventoryMovementInstance && m.field)
16                    result.inventoryMovementInstance.errors.rejectValue(m.field, m.code)
17                result.error = [ code: m.code, args: ["InventoryMovement", params.id] ]
18                return result
19            }
20
21            result.inventoryMovementInstance = InventoryMovement.lock(params.id)
22
23            if(!result.inventoryMovementInstance)
24                fail(code:"default.not.found")
25
26            // Fetch to prevent lazy initialization error.
27            result.inventoryMovementInstance.inventoryItem.unitOfMeasure
28
29            // Used type must have a task that is not complete or in the trash
30            if(result.inventoryMovementInstance.inventoryMovementType.id == 1)  {
31
32                // Unlike move, if the task does not exist at all then deletion is still allowed.
33                if(result.inventoryMovementInstance.task?.trash)
34                    return fail(field:"task", code:"task.operationNotPermittedOnTaskInTrash")
35
36                if(result.inventoryMovementInstance.task?.taskStatus?.id == 3)
37                    return fail(field:"task", code:"task.operationNotPermittedOnCompleteTask")
38
39                // Check for authorisation on recurring tasks.
40                if(result.inventoryMovementInstance.task?.taskRecurringSchedule) {
41                    if(!authenticateService.ifAnyGranted('ROLE_AppAdmin,ROLE_Manager,ROLE_TaskManager,ROLE_InventoryManager'))
42                        return fail(field:"task", code:"task.operationNotPermittedOnRecurringTaskWithoutAuth")
43                }
44
45            }
46
47            result.inventoryItemInstance = InventoryItem.lock(result.inventoryMovementInstance.inventoryItem.id)
48            result.taskId = result.inventoryMovementInstance.task?.id
49
50            if(!result.inventoryItemInstance)
51                return fail(field:"inventoryItem", code:"inventoryMovement.inventoryItem.notFound")
52
53            // Reverse the movement of inventory.
54            if(!result.inventoryMovementInstance.inventoryMovementType.incrementsInventory) {
55                result.inventoryItemInstance.unitsInStock += result.inventoryMovementInstance.quantity
56            }
57            else {
58                if(result.inventoryItemInstance.unitsInStock >= result.inventoryMovementInstance.quantity) {
59                    result.inventoryItemInstance.unitsInStock -= result.inventoryMovementInstance.quantity
60                }
61                else {
62                    return fail(field:"quantity", code:"inventoryMovement.quantity.insufficientItemsInStock")
63                }
64            }
65
66            if(!result.inventoryItemInstance.save())
67                return fail(code: "default.delete.failure")
68
69            // Success..
70            result.inventoryMovementInstance.delete()
71            return result
72
73        } // end withTransaction
74    } //end reverseMove()
75
76    def move(params) {
77        InventoryMovement.withTransaction { status ->
78            def result = [:]
79
80            def fail = { Map m ->
81                status.setRollbackOnly()
82                if(result.inventoryMovementInstance && m.field)
83                    result.inventoryMovementInstance.errors.rejectValue(m.field, m.code)
84                result.error = [ code: m.code, args: ["InventoryMovement", params.id] ]
85                return result
86            }
87
88            result.inventoryMovementInstance = new InventoryMovement(params)
89
90            result.inventoryMovementInstance.person = authService.currentUser
91
92            // Fetch to prevent lazy initialization error.
93            result.inventoryMovementInstance.inventoryItem.unitOfMeasure
94
95            // Used type must have a task that is not complete or in the trash
96            if(result.inventoryMovementInstance.inventoryMovementType.id == 1)  {
97
98                if(!result.inventoryMovementInstance.task)
99                    return fail(field:"task", code:"task.notFound")
100
101                if(result.inventoryMovementInstance.task.trash)
102                    return fail(field:"task", code:"task.operationNotPermittedOnTaskInTrash")
103
104                if(result.inventoryMovementInstance.task.taskStatus.id == 3)
105                    return fail(field:"task", code:"task.operationNotPermittedOnCompleteTask")
106
107                // Check for authorisation on recurring tasks.
108                if(result.inventoryMovementInstance.task.taskRecurringSchedule) {
109                    if(!authenticateService.ifAnyGranted('ROLE_AppAdmin,ROLE_Manager,ROLE_TaskManager,ROLE_InventoryManager'))
110                        return fail(field:"task", code:"task.operationNotPermittedOnRecurringTaskWithoutAuth")
111                }
112            }
113
114            // Bail early if validation fails.
115            if(!result.inventoryMovementInstance.validate())
116                return fail(code:"default.create.failure")
117
118            def inventoryItem = InventoryItem.lock(result.inventoryMovementInstance.inventoryItem.id)
119            result.taskId = result.inventoryMovementInstance.task?.id
120
121            if(!inventoryItem)
122                return fail(field:"inventoryItem", code:"inventoryMovement.inventoryItem.notFound")
123
124            // Perform the movement of inventory.
125            if(result.inventoryMovementInstance.inventoryMovementType.incrementsInventory) {
126                inventoryItem.unitsInStock += result.inventoryMovementInstance.quantity
127            }
128            else {
129                if(inventoryItem.unitsInStock >= result.inventoryMovementInstance.quantity) {
130                    inventoryItem.unitsInStock -= result.inventoryMovementInstance.quantity
131                }
132                else {
133                    return fail(field:"quantity", code:"inventoryMovement.quantity.insufficientItemsInStock")
134                }
135            }
136
137            if(!inventoryItem.save() || !result.inventoryMovementInstance.save())
138                return fail(code:"default.create.failure")
139
140            // Success..
141            return result
142
143        } // end withTransaction
144    } // end move()
145
146} // end class
Note: See TracBrowser for help on using the repository browser.