wip checkout
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
from aws_lambda_powertools.event_handler.api_gateway import Router
|
||||
from aws_lambda_powertools.event_handler.exceptions import (
|
||||
NotFoundError,
|
||||
from layercake.dynamodb import (
|
||||
DynamoDBPersistenceLayer,
|
||||
SortKey,
|
||||
TransactKey,
|
||||
)
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||
|
||||
from boto3clients import dynamodb_client
|
||||
from config import ORDER_TABLE
|
||||
@@ -17,7 +18,12 @@ dyn = DynamoDBPersistenceLayer(ORDER_TABLE, dynamodb_client)
|
||||
|
||||
@router.get('/<order_id>')
|
||||
def get_order(order_id: str):
|
||||
return dyn.collection.get_item(
|
||||
KeyPair(order_id, '0'),
|
||||
exc_cls=NotFoundError,
|
||||
return dyn.collection.get_items(
|
||||
TransactKey(order_id)
|
||||
+ SortKey('0')
|
||||
+ SortKey('ITEMS')
|
||||
+ SortKey('ADDRESS')
|
||||
+ SortKey('PIX')
|
||||
+ SortKey('NFSE')
|
||||
+ SortKey('FEE'),
|
||||
)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import re
|
||||
from datetime import date, datetime, timedelta
|
||||
from decimal import Decimal
|
||||
from enum import Enum
|
||||
from functools import reduce
|
||||
from http import HTTPStatus
|
||||
from typing import Any, Literal
|
||||
@@ -34,6 +36,13 @@ dyn = DynamoDBPersistenceLayer(ORDER_TABLE, dynamodb_client)
|
||||
class CouponNotFoundError(NotFoundError): ...
|
||||
|
||||
|
||||
class PaymentMethod(str, Enum):
|
||||
PIX = 'PIX'
|
||||
CREDIT_CARD = 'CREDIT_CARD'
|
||||
BANK_SLIP = 'BANK_SLIP'
|
||||
MANUAL = 'MANUAL'
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
id: UUID4 | str
|
||||
name: NameStr
|
||||
@@ -69,13 +78,16 @@ class Coupon(BaseModel):
|
||||
|
||||
|
||||
class Checkout(BaseModel):
|
||||
model_config = ConfigDict(str_strip_whitespace=True)
|
||||
model_config = ConfigDict(
|
||||
str_strip_whitespace=True,
|
||||
use_enum_values=True,
|
||||
)
|
||||
|
||||
id: UUID4 = Field(default_factory=uuid4)
|
||||
name: str
|
||||
email: EmailStr
|
||||
address: Address
|
||||
payment_method: Literal['PIX', 'CREDIT_CARD', 'BANK_SLIP', 'MANUAL']
|
||||
payment_method: PaymentMethod
|
||||
items: tuple[Item, ...]
|
||||
enrollments: tuple[Enrollment, ...] = tuple()
|
||||
coupon: Coupon | None = None
|
||||
@@ -129,6 +141,12 @@ def checkout(payload: Checkout):
|
||||
enrollments = payload.enrollments
|
||||
coupon = payload.coupon
|
||||
subtotal = _sum_items(items)
|
||||
payment_method = payload.payment_method
|
||||
due_date = (
|
||||
_calc_due_date(now_, 3)
|
||||
if payment_method == 'BANK_SLIP'
|
||||
else now_ + timedelta(hours=1)
|
||||
)
|
||||
discount = (
|
||||
_apply_discount(subtotal, coupon.amount, coupon.type) * -1
|
||||
if coupon
|
||||
@@ -145,9 +163,9 @@ def checkout(payload: Checkout):
|
||||
'subtotal': subtotal,
|
||||
'total': total,
|
||||
'discount': discount,
|
||||
'due_date': due_date,
|
||||
# Post-migration (orders): rename `create_date` to `created_at`
|
||||
'create_date': now_,
|
||||
'due_date': '',
|
||||
}
|
||||
| ({'coupon': coupon.code} if coupon else {})
|
||||
| ({'installments': payload.installments} if payload.installments else {})
|
||||
@@ -176,6 +194,15 @@ def checkout(payload: Checkout):
|
||||
item={
|
||||
'id': order_id,
|
||||
'sk': 'CREDIT_CARD',
|
||||
'brand': credit_card.brand,
|
||||
'last4': credit_card.last4,
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': 'TRANSACTION',
|
||||
'sk': order_id,
|
||||
'ttl': ttl(start_dt=now_, minutes=5),
|
||||
'created_at': now_,
|
||||
}
|
||||
@@ -208,13 +235,16 @@ def checkout(payload: Checkout):
|
||||
item={
|
||||
'id': order_id,
|
||||
'sk': f'ENROLLMENT#{enrollment.id}',
|
||||
'status': 'UNPROCESSED',
|
||||
'status': 'PENDING',
|
||||
'created_at': now_,
|
||||
}
|
||||
| enrollment.model_dump(exclude={'id'})
|
||||
)
|
||||
|
||||
return JSONResponse(body={'id': order_id}, status_code=HTTPStatus.CREATED)
|
||||
return JSONResponse(
|
||||
body={'id': order_id},
|
||||
status_code=HTTPStatus.CREATED,
|
||||
)
|
||||
|
||||
|
||||
def _sum_items(items: tuple[Item, ...]):
|
||||
@@ -246,3 +276,20 @@ def _apply_discount(
|
||||
)
|
||||
|
||||
return min(amount, subtotal)
|
||||
|
||||
|
||||
def _calc_due_date(
|
||||
start_date: datetime,
|
||||
business_days: int,
|
||||
holidays: set[date] | None = None,
|
||||
) -> datetime:
|
||||
holidays = holidays or set()
|
||||
current_dt = start_date
|
||||
|
||||
while business_days > 0:
|
||||
current_dt += timedelta(days=1)
|
||||
|
||||
if current_dt.weekday() < 5 and current_dt.date() not in holidays:
|
||||
business_days -= 1
|
||||
|
||||
return current_dt
|
||||
|
||||
Reference in New Issue
Block a user