Index: main/waeup.sirp/trunk/src/waeup/sirp/accesscodes/accesscodes.py
===================================================================
--- main/waeup.sirp/trunk/src/waeup/sirp/accesscodes/accesscodes.py	(revision 6378)
+++ main/waeup.sirp/trunk/src/waeup/sirp/accesscodes/accesscodes.py	(revision 6379)
@@ -448,12 +448,54 @@
     return code
 
-def _fire_transition(info, arg, toward=False):
+def fire_transition(access_code, arg, toward=False):
+    """Fire workflow transition for access code.
+
+    The access code instance is looked up via `access_code` (a string
+    like ``APP-1-12345678``).
+
+    `arg` tells what kind of transition to trigger. This will be a
+    transition id like ``'use'`` or ``'init'``, or some transition
+    target like :var:`waeup.sirp.accesscodes.workflow.INITIALIZED`.
+
+    If `toward` is ``False`` (the default) you have to pass a
+    transition id as `arg`, otherwise you must give a transition
+    target.
+
+    :func:`fire_transition` might raise exceptions depending on the
+    reason why the requested transition cannot be performed.
+
+    The following exceptions can occur during processing:
+
+    :exc:`KeyError`:
+      signals not existent access code, batch or site.
+
+    :exc:`ValueError`:
+      signals illegal format of `access_code` string. The regular format is
+      ``APP-N-XXXXXXXX``.
+
+    :exc:`hurry.workflow.interfaces.InvalidTransitionError`:
+      the transition requested cannot be performed because the workflow
+      rules forbid it.
+
+    :exc:`Unauthorized`:
+      the current user is not allowed to perform the requested transition.
+
+    """
     try:
-        if toward:
-            info.fireTransitionToward(arg)
-        else:
-            info.fireTransition(arg)
-    except InvalidTransitionError:
-        return False
+        batch_id, ac_id = access_code.rsplit('-', 1)
+    except ValueError:
+        raise ValueError(
+            'Invalid access code format: %s (use: APP-N-XXXXXXXX)' % (
+                access_code,))
+    try:
+        ac = grok.getSite()['accesscodes'][batch_id].getAccessCode(access_code)
+    except TypeError:
+        raise KeyError(
+            'No site available for looking up accesscodes')
+    info = IWorkflowInfo(ac)
+    if toward:
+        info.fireTransitionToward(arg)
+    else:
+        info.fireTransition(arg)
     return True
 
@@ -461,37 +503,28 @@
     """Invalidate AccessCode denoted by string ``access_code``.
 
-    The access code that belongs to the passed string must exist.
-
     Fires an appropriate transition to perform the task.
 
-    Returns ``True`` if the ac was invalidated, ``False`` else.
+    See :func:`fire_transition` for possible exceptions and their
+    meanings.
     """
-    ac = get_access_code(access_code)
-    info = IWorkflowInfo(ac)
-    return _fire_transition(info, 'use')
+    return fire_transition(access_code, 'use')
 
 def disable_accesscode(access_code):
     """Disable AccessCode denoted by string ``access_code``.
 
-    The access code that belongs to the passed string must exist.
-
     Fires an appropriate transition to perform the task.
 
-    Returns ``True`` if the ac was disabled, ``False`` else.
+    See :func:`fire_transition` for possible exceptions and their
+    meanings.
     """
-    ac = get_access_code(access_code)
-    info = IWorkflowInfo(ac)
-    return _fire_transition(info, DISABLED, toward=True)
+    return fire_transition(access_code, DISABLED, toward=True)
 
 def reenable_accesscode(access_code):
     """Reenable AccessCode denoted by string ``access_code``.
 
-    The access code that belongs to the passed string must exist.
-
     Fires an appropriate transition to perform the task.
 
-    Returns ``True`` if the ac was reenabled, ``False`` else.
+    See :func:`fire_transition` for possible exceptions and their
+    meanings.
     """
-    ac = get_access_code(access_code)
-    info = IWorkflowInfo(ac)
-    return _fire_transition(info, 'reenable')
+    return fire_transition(access_code, 'reenable')
