77 lines
2.1 KiB
Python
77 lines
2.1 KiB
Python
from datetime import date
|
|
from decimal import Decimal
|
|
from enum import Enum
|
|
from http import HTTPStatus
|
|
from typing import Annotated
|
|
|
|
from aws_lambda_powertools.event_handler.api_gateway import Router
|
|
from aws_lambda_powertools.event_handler.exceptions import NotFoundError
|
|
from aws_lambda_powertools.event_handler.openapi.params import Body, Query
|
|
from layercake.dateutils import now
|
|
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
|
|
|
from api_gateway import JSONResponse
|
|
from boto3clients import dynamodb_client
|
|
from config import ORDER_TABLE, USER_TABLE
|
|
from exceptions import OrgNotFoundError
|
|
|
|
router = Router()
|
|
dyn = DynamoDBPersistenceLayer(ORDER_TABLE, dynamodb_client)
|
|
|
|
|
|
class BillingNotFoundError(NotFoundError): ...
|
|
|
|
|
|
class PaymentMethod(str, Enum):
|
|
BANK_SLIP = 'BANK_SLIP'
|
|
MANUAL = 'MANUAL'
|
|
|
|
|
|
@router.get('/<org_id>/billing')
|
|
def billing(
|
|
org_id: str,
|
|
start_date: Annotated[date, Query()],
|
|
end_date: Annotated[date, Query()],
|
|
):
|
|
pk = f'BILLING#ORG#{org_id}'
|
|
sk = f'START#{start_date}#END#{end_date}'
|
|
billing = dyn.collection.get_item(
|
|
KeyPair(pk, sk),
|
|
exc_cls=BillingNotFoundError,
|
|
)
|
|
|
|
return billing | dyn.collection.query(
|
|
KeyPair(
|
|
pk=pk,
|
|
sk=f'{sk}#ENROLLMENT',
|
|
),
|
|
limit=150,
|
|
)
|
|
|
|
|
|
@router.put('/<org_id>/billing')
|
|
def update(
|
|
org_id: str,
|
|
due_days: Annotated[Decimal, Body(embed=True, ge=1, le=90)],
|
|
payment_method: Annotated[PaymentMethod, Body(embed=True)],
|
|
):
|
|
with dyn.transact_writer() as transact:
|
|
transact.condition(
|
|
key=KeyPair(org_id, '0'),
|
|
cond_expr='attribute_exists(sk)',
|
|
exc_cls=OrgNotFoundError,
|
|
table_name=USER_TABLE,
|
|
)
|
|
transact.put(
|
|
item={
|
|
'id': org_id,
|
|
'sk': 'METADATA#BILLING',
|
|
'due_days': due_days,
|
|
'payment_method': payment_method.value,
|
|
'created_at': now(),
|
|
},
|
|
table_name=USER_TABLE,
|
|
)
|
|
|
|
return JSONResponse(status_code=HTTPStatus.NO_CONTENT)
|