wip reenroll
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
from dataclasses import asdict, dataclass
|
||||
from typing import Self, TypedDict
|
||||
from typing import NotRequired, Self, TypedDict
|
||||
|
||||
from layercake.dateutils import now, ttl
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||
@@ -8,8 +7,16 @@ from layercake.strutils import md5_hash
|
||||
from schemas import Enrollment
|
||||
|
||||
Tenant = TypedDict('Tenant', {'id': str, 'name': str})
|
||||
Author = TypedDict('Author', {'id': str, 'name': str})
|
||||
CreatedBy = TypedDict('CreatedBy', {'id': str, 'name': str})
|
||||
DeduplicationWindow = TypedDict('DeduplicationWindow', {'offset_days': int})
|
||||
Subscription = TypedDict(
|
||||
'Subscription',
|
||||
{
|
||||
'org_id': str,
|
||||
'billing_day': int,
|
||||
'billing_period': NotRequired[str],
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class LinkedEntity(str):
|
||||
@@ -23,32 +30,16 @@ class LinkedEntity(str):
|
||||
self.type = type
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Slot:
|
||||
id: str
|
||||
sk: str
|
||||
|
||||
@property
|
||||
def order_id(self) -> LinkedEntity:
|
||||
idx, _ = self.sk.split('#')
|
||||
return LinkedEntity(idx, 'ORDER')
|
||||
|
||||
|
||||
class DeduplicationConflictError(Exception):
|
||||
def __init__(self, *args):
|
||||
super().__init__('Enrollment already exists')
|
||||
|
||||
|
||||
class SlotDoesNotExistError(Exception):
|
||||
def __init__(self, *args):
|
||||
super().__init__('Slot does not exist')
|
||||
|
||||
|
||||
def enroll(
|
||||
enrollment: Enrollment,
|
||||
*,
|
||||
slot: Slot | None = None,
|
||||
author: Author | None = None,
|
||||
created_by: CreatedBy | None = None,
|
||||
subscription: Subscription | None = None,
|
||||
linked_entities: frozenset[LinkedEntity] = frozenset(),
|
||||
deduplication_window: DeduplicationWindow | None = None,
|
||||
persistence_layer: DynamoDBPersistenceLayer,
|
||||
@@ -60,9 +51,6 @@ def enroll(
|
||||
lock_hash = md5_hash('%s%s' % (user.id, course.id))
|
||||
|
||||
with persistence_layer.transact_writer() as transact:
|
||||
if slot:
|
||||
linked_entities = frozenset({slot.order_id}) | linked_entities
|
||||
|
||||
transact.put(
|
||||
item={
|
||||
'sk': '0',
|
||||
@@ -90,46 +78,33 @@ def enroll(
|
||||
}
|
||||
)
|
||||
|
||||
if slot:
|
||||
transact.put(
|
||||
item={
|
||||
'id': enrollment.id,
|
||||
# Post-migration: uncomment the following line
|
||||
# 'sk': 'METADATA#SOURCE_SLOT',
|
||||
'sk': 'parent_vacancy',
|
||||
'vacancy': asdict(slot),
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
|
||||
transact.delete(
|
||||
key=KeyPair(slot.id, slot.sk),
|
||||
cond_expr='attribute_exists(sk)',
|
||||
exc_cls=SlotDoesNotExistError,
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': enrollment.id,
|
||||
'sk': 'CANCEL_POLICY',
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
|
||||
if author:
|
||||
if created_by:
|
||||
transact.put(
|
||||
item={
|
||||
'id': enrollment.id,
|
||||
'sk': 'author',
|
||||
'user_id': author['id'],
|
||||
'name': author['name'],
|
||||
# Post-migration: uncomment the following line
|
||||
# 'sk': 'created_by',
|
||||
'user_id': created_by['id'],
|
||||
'name': created_by['name'],
|
||||
'created_at': now_,
|
||||
},
|
||||
)
|
||||
|
||||
if subscription:
|
||||
transact.put(
|
||||
item={
|
||||
'id': enrollment.id,
|
||||
'sk': 'METADATA#SUBSCRIPTION_COVERED',
|
||||
'created_at': now_,
|
||||
}
|
||||
| subscription,
|
||||
)
|
||||
|
||||
# Prevents the user from enrolling in the same course again until
|
||||
# the deduplication window expires or is removed.
|
||||
if deduplication_window:
|
||||
offset_days = deduplication_window['offset_days']
|
||||
offset_days = int(deduplication_window['offset_days'])
|
||||
ttl_ = ttl(
|
||||
start_dt=now_,
|
||||
days=course.access_period - offset_days,
|
||||
|
||||
Reference in New Issue
Block a user