class InventoryMovementService {

    boolean transactional = false

    def reverseMove(params) {
        InventoryMovement.withTransaction { status ->
            def result = [:]
            def inventoryMovementInstance = InventoryMovement.lock(params.id)
            if(inventoryMovementInstance) {
                def inventoryItem = InventoryItem.lock(inventoryMovementInstance.inventoryItem.id)
                result.taskId = inventoryMovementInstance.task.id

                if(!inventoryItem) {
                        status.setRollbackOnly()
                        inventoryMovementInstance.errors.rejectValue('inventoryItem', "inventoryMovement.inventoryItem.notFound")
                        result.inventoryMovementInstance = inventoryMovementInstance
                        result.error = true
                        return result
                }

                // Reverse the movement of inventory.
                if(!inventoryMovementInstance.inventoryMovementType.incrementsInventory) {
                    inventoryItem.unitsInStock += inventoryMovementInstance.quantity
                }
                else {
                    if(inventoryItem.unitsInStock >= inventoryMovementInstance.quantity) {
                        inventoryItem.unitsInStock -= inventoryMovementInstance.quantity
                    }
                    else {
                        status.setRollbackOnly()
                        inventoryMovementInstance.errors.rejectValue('quantity', "inventoryMovement.quantity.insufficientItemsInStock")
                        result.inventoryMovementInstance = inventoryMovementInstance
                        result.error = true
                        return result
                    }
                }

                if(inventoryItem.save() ) {
                    inventoryMovementInstance.delete()
                    return result
                }
                else {
                    status.setRollbackOnly()
                    result.error = true
                    return result
                }

            }
            else {
                result.error = true
                return result
            }

        } // end withTransaction
    } //end reverseMove()

    def move(params) {
        InventoryMovement.withTransaction { status ->
            def result = [:]
            def inventoryMovementInstance = new InventoryMovement(params)

            if(inventoryMovementInstance.validate()) {
                def inventoryItem = InventoryItem.lock(inventoryMovementInstance.inventoryItem.id)
                result.taskId = inventoryMovementInstance.task.id

                if(!inventoryItem) {
                        status.setRollbackOnly()
                        inventoryMovementInstance.errors.rejectValue('inventoryItem', "inventoryMovement.inventoryItem.notFound")
                        result.inventoryMovementInstance = inventoryMovementInstance
                        result.error = true
                        return result
                }

                // Perform the movement of inventory.
                if(inventoryMovementInstance.inventoryMovementType.incrementsInventory) {
                    inventoryItem.unitsInStock += inventoryMovementInstance.quantity
                }
                else {
                    if(inventoryItem.unitsInStock >= inventoryMovementInstance.quantity) {
                        inventoryItem.unitsInStock -= inventoryMovementInstance.quantity
                    }
                    else {
                        status.setRollbackOnly()
                        inventoryMovementInstance.errors.rejectValue('quantity', "inventoryMovement.quantity.insufficientItemsInStock")
                        result.inventoryMovementInstance = inventoryMovementInstance
                        result.error = true
                        return result
                    }
                }

                if(inventoryItem.save() && inventoryMovementInstance.save()) {
                    result.inventoryMovementInstance = inventoryMovementInstance
                    return result
                }
                else {
                    status.setRollbackOnly()
                    result.inventoryMovementInstance = inventoryMovementInstance
                    result.error = true
                    return result
                }

            }
            else {
                result.inventoryMovementInstance = inventoryMovementInstance
                result.error = true
                return result
            }

        } // end withTransaction
    } // end move()

} // end class
