Skip to content

Commit

Permalink
added websocket support for debit and balance
Browse files Browse the repository at this point in the history
  • Loading branch information
jabelone committed Nov 14, 2023
1 parent 56f7f3a commit ae89a20
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 175 deletions.
157 changes: 153 additions & 4 deletions memberportal/api_access/consumers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
MemberbucksDevice,
AccessControlledDeviceAPIKey,
)
from profile.models import Profile, log_event
from memberbucks.models import MemberBucks
from profile.models import Profile, User
from constance import config
from django.core.exceptions import ObjectDoesNotExist
from django.utils import timezone

logger = logging.getLogger("app")

Expand Down Expand Up @@ -86,7 +89,7 @@ def receive_json(self, content=None, **kwargs):
Receive message from WebSocket.
"""
try:
logger.info(
logger.debug(
f"Got message from {self.device.type} ({self.device.serial_number}): {json.dumps(content)}",
)
self.last_seen = datetime.datetime.now()
Expand Down Expand Up @@ -411,10 +414,156 @@ class MemberbucksConsumer(AccessDeviceConsumer):

def __init__(self, *args, **kwargs):
super().__init__(args, kwargs)
self.DeviceClass = MemberbucksConsumer
self.DeviceClass = MemberbucksDevice

def handle_other_packet(self, content):
if content.get("command") == "balance":
card_id = content.get("card_id")

if card_id is None:
self.send_json(
{
"command": "balance",
"reason": "invalid_card_id",
"success": False,
}
)
return True

try:
profile = Profile.objects.get(rfid=card_id)
self.send_json(
{
"command": "balance",
"balance": int(profile.memberbucks_balance * 100),
}
)
return True

except ObjectDoesNotExist:
self.send_json(
{
"command": "balance",
"reason": "invalid_card_id",
"success": False,
}
)
return True

if content.get("command") == "debit":
pass # TODO: implement
card_id = content.get("card_id")
amount = int(content.get("amount") or 0)
description = content.get("description", f"{self.device.name} purchase.")

if card_id is None:
self.send_json(
{
"command": "debit",
"reason": "invalid_card_id",
"success": False,
}
)
return True

# stops us accidentally crediting an account if it's negative
if amount <= 0:
self.send_json(
{
"command": "debit",
"reason": "invalid_amount",
"success": False,
}
)
return True

try:
profile = Profile.objects.get(rfid=card_id)

except ObjectDoesNotExist:
self.send_json(
{
"command": "debit",
"reason": "invalid_card_id",
"success": False,
}
)
return True

if profile.memberbucks_balance >= amount:
time_dif = (
timezone.now() - profile.last_memberbucks_purchase
).total_seconds()

if time_dif > 5:
transaction = MemberBucks()
transaction.amount = amount * -1.0
transaction.user = profile.user
transaction.description = description
transaction.transaction_type = "card"
transaction.save()

profile.last_memberbucks_purchase = timezone.now()
profile.save()
profile.refresh_from_db()

subject = (
f"You just made a ${amount} {config.MEMBERBUCKS_NAME} purchase."
)
message = (
f"Description: {transaction.description}. Balance Remaining: "
)
f"${profile.memberbucks_balance}. If this wasn't you, or you believe there "
f"has been an error, please let us know."

User.objects.get(profile=profile).email_notification(
subject, message
)

profile.user.log_event(
f"Debited ${amount} from {config.MEMBERBUCKS_NAME} account.",
"memberbucks",
)

self.send_json(
{
"command": "debit",
"balance": int(profile.memberbucks_balance * 100),
}
)
return True

else:
self.send_json(
{
"command": "rate_limited",
}
)

else:
profile.user.log_event(
f"Not enough funds to debit ${amount} from {config.MEMBERBUCKS_NAME} account by {self.device.name}.",
"memberbucks",
)

subject = (
f"Failed to make a ${amount} {config.MEMBERBUCKS_NAME} purchase."
)
message = f"We just tried to debit ${amount} from your {config.MEMBERBUCKS_NAME} balance but were not "
f"successful. You currently have ${profile.memberbucks_balance}. If this wasn't you, please let us know "
f"immediately."

User.objects.get(profile=profile).email_notification(subject, message)

self.send_json(
{
"command": "debit_declined",
"reason": "insufficient_funds",
"balance": int(profile.memberbucks_balance * 100),
}
)
return True

if content.get("command") == "credit":
return False # TODO: implement
else:
return False
40 changes: 0 additions & 40 deletions memberportal/memberbucks/urls.py

This file was deleted.

124 changes: 0 additions & 124 deletions memberportal/memberbucks/views.py

This file was deleted.

1 change: 0 additions & 1 deletion memberportal/membermatters/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def safe_constance_get(fld: str):

urlpatterns = [
path("api/openid/", include("oidc_provider.urls", namespace="oidc_provider")),
path("", include("memberbucks.urls")),
path("", include("api_spacedirectory.urls")),
path("", include("api_general.urls")),
path("", include("api_access.urls")),
Expand Down
Loading

0 comments on commit ae89a20

Please sign in to comment.