Files
saladeaula.digital/api.saladeaula.digital/app/routes/orders/__init__.py

99 lines
3.1 KiB
Python

from http import HTTPStatus
from typing import Annotated
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.openapi.params import Body
from layercake.dateutils import now
from layercake.dynamodb import (
DynamoDBPersistenceLayer,
KeyPair,
SortKey,
TransactKey,
)
from pydantic import UUID4
from api_gateway import JSONResponse
from boto3clients import dynamodb_client
from config import ORDER_TABLE
from exceptions import ConflictError, OrderConflictError, OrderNotFoundError
from middlewares.authentication_middleware import User as Authenticated
from .checkout import router as checkout
from .payment_retries import router as payment_retries
__all__ = ['checkout', 'payment_retries']
router = Router()
dyn = DynamoDBPersistenceLayer(ORDER_TABLE, dynamodb_client)
class FulfillmentConflictError(ConflictError): ...
@router.get('/<order_id>')
def get_order(order_id: str):
order = dyn.collection.get_items(
TransactKey(order_id)
+ SortKey('0')
+ SortKey('ITEMS', rename_key='items', path_spec='items')
+ SortKey('CREATED_BY', rename_key='created_by')
+ SortKey('ADDRESS', rename_key='address')
+ SortKey('CREDIT_CARD', rename_key='credit_card')
+ SortKey('INVOICE', rename_key='invoice')
+ SortKey('FEE', rename_key='fee')
+ SortKey('TRANSACTION#STATS', rename_key='stats')
+ SortKey('FULFILLMENT', rename_key='fulfillment'),
)
if not order:
raise OrderNotFoundError('Order not found')
attempts = dyn.collection.query(KeyPair(order_id, 'TRANSACTION#ATTEMPT#'))
enrollments = dyn.collection.query(KeyPair(order_id, 'ENROLLMENT#'))
return (
order
| {
'payment_attempts': attempts['items'],
'enrollments': enrollments['items'],
}
# Post-migration (orders): remove the following lines
| ({'created_at': order['create_date']} if 'create_date' in order else {})
| ({'paid_at': order['payment_date']} if 'payment_date' in order else {})
)
@router.post('/<order_id>/fulfillment')
def fulfillment(
order_id: str,
org_id: Annotated[str | UUID4, Body(embed=True)],
):
created_by: Authenticated = router.context['user']
with dyn.transact_writer() as transact:
transact.condition(
key=KeyPair(order_id, '0'),
cond_expr='attribute_exists(sk) AND org_id = :org_id',
expr_attr_values={
':org_id': org_id,
},
exc_cls=OrderConflictError,
)
transact.put(
item={
'id': order_id,
'sk': 'FULFILLMENT',
'status': 'IN_PROGRESS',
'org_id': org_id,
'created_by': {
'id': created_by.id,
'name': created_by.name,
},
'created_at': now(),
},
cond_expr='attribute_not_exists(sk)',
exc_cls=FulfillmentConflictError,
)
return JSONResponse(status_code=HTTPStatus.NO_CONTENT)