fix interest
This commit is contained in:
@@ -9,7 +9,9 @@ COURSE_TABLE: str = os.getenv('COURSE_TABLE') # type: ignore
|
|||||||
|
|
||||||
BUCKET_NAME: str = os.getenv('BUCKET_NAME') # type: ignore
|
BUCKET_NAME: str = os.getenv('BUCKET_NAME') # type: ignore
|
||||||
|
|
||||||
|
DUE_DAYS = 3
|
||||||
DEDUP_WINDOW_OFFSET_DAYS = 90
|
DEDUP_WINDOW_OFFSET_DAYS = 90
|
||||||
|
|
||||||
|
|
||||||
PAPERFORGE_API = 'https://paperforge.saladeaula.digital'
|
PAPERFORGE_API = 'https://paperforge.saladeaula.digital'
|
||||||
INTERNAL_EMAIL_DOMAIN = 'users.noreply.saladeaula.digital'
|
INTERNAL_EMAIL_DOMAIN = 'users.noreply.saladeaula.digital'
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from aws_lambda_powertools.event_handler.exceptions import (
|
|||||||
NotFoundError,
|
NotFoundError,
|
||||||
)
|
)
|
||||||
from layercake.dateutils import now, ttl
|
from layercake.dateutils import now, ttl
|
||||||
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey
|
||||||
from layercake.extra_types import CnpjStr, CpfStr, CreditCard, NameStr
|
from layercake.extra_types import CnpjStr, CpfStr, CreditCard, NameStr
|
||||||
from pydantic import (
|
from pydantic import (
|
||||||
UUID4,
|
UUID4,
|
||||||
@@ -26,7 +26,7 @@ from pydantic import (
|
|||||||
|
|
||||||
from api_gateway import JSONResponse
|
from api_gateway import JSONResponse
|
||||||
from boto3clients import dynamodb_client
|
from boto3clients import dynamodb_client
|
||||||
from config import ORDER_TABLE
|
from config import DUE_DAYS, ORDER_TABLE
|
||||||
from routes.enrollments.enroll import Enrollment
|
from routes.enrollments.enroll import Enrollment
|
||||||
|
|
||||||
router = Router()
|
router = Router()
|
||||||
@@ -135,24 +135,29 @@ class Checkout(BaseModel):
|
|||||||
def checkout(payload: Checkout):
|
def checkout(payload: Checkout):
|
||||||
now_ = now()
|
now_ = now()
|
||||||
order_id = payload.id
|
order_id = payload.id
|
||||||
|
org_id = payload.org_id
|
||||||
address = payload.address
|
address = payload.address
|
||||||
credit_card = payload.credit_card
|
credit_card = payload.credit_card
|
||||||
items = payload.items
|
items = payload.items
|
||||||
enrollments = payload.enrollments
|
enrollments = payload.enrollments
|
||||||
coupon = payload.coupon
|
coupon = payload.coupon
|
||||||
subtotal = _sum_items(items)
|
|
||||||
payment_method = payload.payment_method
|
payment_method = payload.payment_method
|
||||||
|
installments = payload.installments
|
||||||
|
subtotal = _sum_items(items)
|
||||||
due_date = (
|
due_date = (
|
||||||
_calc_due_date(now_, 3)
|
_calc_due_date(now_, _get_due_days(org_id) if org_id else DUE_DAYS)
|
||||||
if payment_method == 'BANK_SLIP'
|
if payment_method == 'BANK_SLIP'
|
||||||
else now_ + timedelta(hours=1)
|
else now_ + timedelta(hours=1)
|
||||||
)
|
)
|
||||||
discount = (
|
discount = (
|
||||||
_apply_discount(subtotal, coupon.amount, coupon.type) * -1
|
_apply_discount(subtotal, coupon.amount, coupon.type) * -1 if coupon else 0
|
||||||
if coupon
|
)
|
||||||
else Decimal('0')
|
total = subtotal + discount if subtotal > 0 else 0
|
||||||
|
interest_amount = (
|
||||||
|
_calc_interest(total, installments) - total
|
||||||
|
if payment_method == 'CREDIT_CARD' and installments
|
||||||
|
else 0
|
||||||
)
|
)
|
||||||
total = subtotal + discount if subtotal > Decimal('0') else Decimal('0')
|
|
||||||
|
|
||||||
with dyn.transact_writer() as transact:
|
with dyn.transact_writer() as transact:
|
||||||
transact.put(
|
transact.put(
|
||||||
@@ -161,14 +166,21 @@ def checkout(payload: Checkout):
|
|||||||
'sk': '0',
|
'sk': '0',
|
||||||
'status': 'PENDING',
|
'status': 'PENDING',
|
||||||
'subtotal': subtotal,
|
'subtotal': subtotal,
|
||||||
'total': total,
|
'total': total + interest_amount,
|
||||||
'discount': discount,
|
'discount': discount,
|
||||||
'due_date': due_date,
|
'due_date': due_date,
|
||||||
# Post-migration (orders): rename `create_date` to `created_at`
|
# Post-migration (orders): rename `create_date` to `created_at`
|
||||||
'create_date': now_,
|
'create_date': now_,
|
||||||
}
|
}
|
||||||
| ({'coupon': coupon.code} if coupon else {})
|
| ({'coupon': coupon.code} if coupon else {})
|
||||||
| ({'installments': payload.installments} if payload.installments else {})
|
| (
|
||||||
|
{
|
||||||
|
'installments': payload.installments,
|
||||||
|
'interest_amount': interest_amount,
|
||||||
|
}
|
||||||
|
if payload.installments
|
||||||
|
else {}
|
||||||
|
)
|
||||||
| payload.model_dump()
|
| payload.model_dump()
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -293,3 +305,17 @@ def _calc_due_date(
|
|||||||
business_days -= 1
|
business_days -= 1
|
||||||
|
|
||||||
return current_dt
|
return current_dt
|
||||||
|
|
||||||
|
|
||||||
|
def _get_due_days(
|
||||||
|
org_id: str | UUID4,
|
||||||
|
default: int = DUE_DAYS,
|
||||||
|
) -> int:
|
||||||
|
return dyn.collection.get_item(
|
||||||
|
KeyPair(
|
||||||
|
pk=str(org_id),
|
||||||
|
sk=SortKey('METADATA#PAYMENT_POLICY', path_spec='due_days'),
|
||||||
|
),
|
||||||
|
raise_on_error=False,
|
||||||
|
default=default,
|
||||||
|
)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ def test_checkout_coupon(
|
|||||||
'name': 'Branco do Brasil',
|
'name': 'Branco do Brasil',
|
||||||
'email': 'bb@users.noreply.saladeaula.digital',
|
'email': 'bb@users.noreply.saladeaula.digital',
|
||||||
'payment_method': 'CREDIT_CARD',
|
'payment_method': 'CREDIT_CARD',
|
||||||
'installments': 12,
|
# 'installments': 2,
|
||||||
'credit_card': {
|
'credit_card': {
|
||||||
'holder_name': 'Sergio R Siqueira',
|
'holder_name': 'Sergio R Siqueira',
|
||||||
'number': '4111111111111111',
|
'number': '4111111111111111',
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
// Orgs
|
// Orgs
|
||||||
{"id": "2a8963fc-4694-4fe2-953a-316d1b10f1f5", "sk": "0", "name": "pytest", "cnpj": "04978826000180"}
|
{"id": "2a8963fc-4694-4fe2-953a-316d1b10f1f5", "sk": "0", "name": "pytest", "cnpj": "04978826000180"}
|
||||||
{"id": "2a8963fc-4694-4fe2-953a-316d1b10f1f5", "sk": "METADATA#SUBSCRIPTION", "billing_day": 6}
|
{"id": "2a8963fc-4694-4fe2-953a-316d1b10f1f5", "sk": "METADATA#SUBSCRIPTION", "billing_day": 6}
|
||||||
|
{"id": "2a8963fc-4694-4fe2-953a-316d1b10f1f5", "sk": "METADATA#PAYMENT_POLICY", "due_days": 30, "created_at": "2025-07-15T15:04:36.369323-03:00"}
|
||||||
{"id": "f6000f79-6e5c-49a0-952f-3bda330ef278", "sk": "0", "name": "Banco do Brasil", "cnpj": "00000000000191"}
|
{"id": "f6000f79-6e5c-49a0-952f-3bda330ef278", "sk": "0", "name": "Banco do Brasil", "cnpj": "00000000000191"}
|
||||||
|
|
||||||
// Org admins
|
// Org admins
|
||||||
{"id": "f6000f79-6e5c-49a0-952f-3bda330ef278", "sk": "admins#15bacf02-1535-4bee-9022-19d106fd7518", "name": "Chester Bennington", "email": "chester@linkinpark.com"}
|
{"id": "f6000f79-6e5c-49a0-952f-3bda330ef278", "sk": "admins#15bacf02-1535-4bee-9022-19d106fd7518", "name": "Chester Bennington", "email": "chester@linkinpark.com"}
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export type CreditCard = z.infer<typeof creditCard>
|
|||||||
export function Payment({}) {
|
export function Payment({}) {
|
||||||
const wizard = useWizard()
|
const wizard = useWizard()
|
||||||
const { update, summary, ...state } = useWizardStore()
|
const { update, summary, ...state } = useWizardStore()
|
||||||
const { total } = summary()
|
const { subtotal, discount } = summary()
|
||||||
const { control, handleSubmit } = useForm<Schema>({
|
const { control, handleSubmit } = useForm<Schema>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
payment_method: state.payment_method,
|
payment_method: state.payment_method,
|
||||||
@@ -156,7 +156,7 @@ export function Payment({}) {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{paymentMethod === 'CREDIT_CARD' ? (
|
{paymentMethod === 'CREDIT_CARD' ? (
|
||||||
<CreditCard control={control} total={total} />
|
<CreditCard control={control} total={subtotal + discount} />
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<Separator />
|
<Separator />
|
||||||
@@ -367,7 +367,9 @@ export function CreditCard({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const value =
|
const value =
|
||||||
calcInterest(total, installment) / installment
|
installment > 1
|
||||||
|
? calcInterest(total, installment) / installment
|
||||||
|
: total
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NativeSelectOption
|
<NativeSelectOption
|
||||||
|
|||||||
Reference in New Issue
Block a user