def order_updated(_item):
        if _item.event_action != 'entity_updated':
            return

        order = json.loads(_item.event_data)
        if order['status'] != 'IN_STOCK':
            return

        rsp = send_message('read-model', 'get_entity', {
            'name': 'cart',
            'id': order['cart_id']
        })
        cart = rsp['result']
        if not cart:
            logging.error('could not find cart {} for order {}'.format(
                order['cart_id'], order['entity_id']))
            return

        rsp = send_message('read-model', 'get_entity', {
            'name': 'customer',
            'id': cart['customer_id']
        })
        customer = rsp['result']
        if not customer:
            logging.error('could not find customer {} for cart {}'.format(
                cart['customer_id'], cart['entity_id']))
            return

        rsp = send_message('read-model', 'get_entities', {
            'name': 'product',
            'ids': cart['product_ids']
        })
        products = rsp['result']
        if not all(products) and not len(products) == len(cart['product_ids']):
            logging.error('could not find all products for cart {}'.format(
                cart['entity_id']))
            return

        msg = """Dear {}!

Please transfer € {} with your favourite payment method.

Cheers""".format(customer['name'],
                 sum([int(product['price']) for product in products]))

        send_message_async('mail-service', 'send', {
            "to": customer['email'],
            "msg": msg
        })
    def customer_deleted(_item):
        if _item.event_action != 'entity_deleted':
            return

        customer = json.loads(_item.event_data)
        msg = """Dear {}!

Good bye, hope to see you soon again at Ordershop.

Cheers""".format(customer['name'])

        send_message_async('mail-service', 'send', {
            "to": customer['email'],
            "msg": msg
        })
    def customer_created(_item):
        if _item.event_action != 'entity_created':
            return

        customer = json.loads(_item.event_data)
        msg = """Dear {}!

Welcome to Ordershop.

Cheers""".format(customer['name'])

        send_message_async('mail-service', 'send', {
            "to": customer['email'],
            "msg": msg
        })
    def shipping_created(_item):
        if _item.event_action != 'entity_created':
            return

        shipping = json.loads(_item.event_data)

        rsp = send_message('read-model', 'get_entity', {
            'name': 'order',
            'id': shipping['order_id']
        })
        order = rsp['result']
        if not order:
            logging.error('could not find order {} for shipping {}'.format(
                shipping['order_id'], shipping['entity_id']))
            return

        rsp = send_message('read-model', 'get_entity', {
            'name': 'cart',
            'id': order['cart_id']
        })
        cart = rsp['result']
        if not cart:
            logging.error('could not find cart {} for order {}'.format(
                order['cart_id'], order['entity_id']))
            return

        rsp = send_message('read-model', 'get_entity', {
            'name': 'customer',
            'id': cart['customer_id']
        })
        customer = rsp['result']
        if not customer:
            logging.error('could not find customer {} for cart {}'.format(
                cart['customer_id'], cart['entity_id']))
            return

        msg = """Dear {}!

We've just shipped order {}. It will be soon delivered to you.

Cheers""".format(customer['name'], order['entity_id'])

        send_message_async('mail-service', 'send', {
            "to": customer['email'],
            "msg": msg
        })
    def billing_created(_item):
        if _item.event_action != 'entity_created':
            return

        billing = json.loads(_item.event_data)

        rsp = send_message('read-model', 'get_entity', {
            'name': 'order',
            'id': billing['order_id']
        })
        order = rsp['result']
        if not order:
            logging.error('could not find order {} for billing {}'.format(
                billing['order_id'], billing['entity_id']))
            return

        rsp = send_message('read-model', 'get_entity', {
            'name': 'cart',
            'id': order['cart_id']
        })
        cart = rsp['result']
        if not cart:
            logging.error('could not find cart {} for order {}'.format(
                order['cart_id'], order['entity_id']))
            return

        rsp = send_message('read-model', 'get_entity', {
            'name': 'customer',
            'id': cart['customer_id']
        })
        customer = rsp['result']
        if not customer:
            logging.error('could not find customer {} for cart {}'.format(
                cart['customer_id'], cart['entity_id']))
            return

        msg = """Dear {}!

We've just received € {} from you, thank you for your transfer.

Cheers""".format(customer['name'], billing['amount'])

        send_message_async('mail-service', 'send', {
            "to": customer['email'],
            "msg": msg
        })
def _send_message(_service_name, _func_name, _add_params=None, _async=False):
    """
    Helper function to send a message to a service.

    :param _service_name: The name of the service to call.
    :param _func_name: The name of the function to call.
    :param _add_params: A dict with optional additional parameters.
    :param _async: Boolean indicating asynchronous communication.
    :return: A dict with the result response, or a message ID if :param _async: is True.
    """
    params = {}
    if request.data:
        params = json.loads(request.data)

    if _add_params:
        params.update(_add_params)

    if _async:
        return {
            "result": send_message_async(_service_name, _func_name, params)
        }

    return send_message(_service_name, _func_name, params)