"""
byceps.services.shop.order.action_service
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2017 Jochen Kupperschmidt
:License: Modified BSD, see LICENSE for details.
"""

from typing import Any, Callable, Dict, Optional

from ....database import db

from ..article.models.article import ArticleNumber

from .actions.award_badge import award_badge
from .actions.create_tickets import create_tickets
from .models.order import OrderID, OrderTuple
from .models.order_action import OrderAction
from . import service as order_service


Parameters = Dict[str, Any]

OrderActionType = Callable[[OrderTuple, ArticleNumber, Parameters], None]


PROCEDURES_BY_NAME = {
    'award_badge': award_badge,
    'create_tickets': create_tickets,
}  # type: Dict[str, OrderActionType]


def create_order_action(article_number: ArticleNumber, procedure: str,
                        parameters: Dict[str, Any]) -> None:
    """Create an order action."""
    action = OrderAction(article_number, procedure, parameters)

    db.session.add(action)
    db.session.commit()


def execute_order_actions(order_id: OrderID) -> None:
    """Execute relevant actions for order."""
    order = order_service.find_order_with_details(order_id)

    article_numbers = {item.article_number for item in order.items}

    if not article_numbers:
        return

    actions = OrderAction.query \
        .filter(OrderAction.article_number.in_(article_numbers)) \
        .all()

    for action in actions:
        article_number = action.article_number
        procedure_name = action.procedure
        params = action.parameters

        procedure = find_procedure(procedure_name)

        if procedure is None:
            raise Exception(
                "Unknown procedure '{}' configured for article number '{}'."
                    .format(procedure_name, article_number))

        procedure(order, article_number, params)


def find_procedure(name: str) -> Optional[OrderActionType]:
    return PROCEDURES_BY_NAME.get(name)

@@ -221,18 +221,8 @@
 Dict
-, Optional
 %0A%0Afr
@@ -1613,20 +1613,20 @@
 edure = 
-find
+_get
 _procedu
@@ -1657,57 +1657,162 @@
     
-if procedure is None:%0A           
+procedure(order, article_number, params)%0A%0A%0Adef _get_procedure(name: str) -%3E OrderActionType:%0A    %22%22%22Return procedure with that name, or
  raise 
-E
+an e
 xception
 (%0A  
@@ -1811,14 +1811,148 @@
 tion
-(%0A    
+ if the%0A    name is not registerd.%0A    %22%22%22%0A    procedure = PROCEDURES_BY_NAME.get(name)%0A%0A    if procedure is None:%0A        raise Exception(%0A
     
@@ -2036,20 +2036,16 @@
         
-    
 .format(
@@ -2086,151 +2086,21 @@
     
-    procedure(order, article_number, params)%0A%0A%0Adef find_procedure(name: str) -%3E Optional%5BOrderActionType%5D:%0A    return PROCEDURES_BY_NAME.get(name)
+return procedure
 %0A

Move order action procedure name verification to lookup function