Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:/sweeftdigital/accounts_G2 into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
sandronadiradze committed Nov 1, 2024
2 parents e0b0f74 + 8ebc92c commit ddbce48
Show file tree
Hide file tree
Showing 9 changed files with 261 additions and 54 deletions.
45 changes: 45 additions & 0 deletions apis/admin.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.core.exceptions import ValidationError
from django.db import transaction

from apis.models import CustomUser
from payments.models import Payment
from payments.models.balance import Balance


class CustomUserAdmin(UserAdmin):
Expand Down Expand Up @@ -166,5 +169,47 @@ class PaymentAdmin(admin.ModelAdmin):
readonly_fields = ("created_at", "updated_at")


class BalanceAdmin(admin.ModelAdmin):
model = Balance
list_display = ("user", "amount")
search_fields = ("user__email",)
readonly_fields = ("amount",)

actions = ["add_to_balance", "subtract_from_balance"]

@admin.action(description="Add to balance")
def add_to_balance(self, request, queryset):
amount = float(request.POST.get("amount", 0))
if amount <= 0:
self.message_user(request, "Amount must be positive.", level="error")
return

for balance in queryset:
try:
with transaction.atomic():
balance.add(amount)
self.message_user(request, f"Added {amount} to {balance.user}'s balance.")
except ValidationError as e:
self.message_user(request, str(e), level="error")

@admin.action(description="Subtract from balance")
def subtract_from_balance(self, request, queryset):
amount = float(request.POST.get("amount", 0))
if amount <= 0:
self.message_user(request, "Amount must be positive.", level="error")
return

for balance in queryset:
try:
with transaction.atomic():
balance.subtract(amount)
self.message_user(
request, f"Subtracted {amount} from {balance.user}'s balance."
)
except ValidationError as e:
self.message_user(request, str(e), level="error")


admin.site.register(Balance, BalanceAdmin)
admin.site.register(CustomUser, CustomUserAdmin)
admin.site.register(Payment, PaymentAdmin)
6 changes: 3 additions & 3 deletions apis/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,9 @@ def validate(self, attrs):

user = User.objects.get(id=user_id)
if settings.SIMPLE_JWT.get("REVOKE_TOKEN_CLAIM"):
current_user_password = get_md5_hash_password(user.passwrod)
if current_user_password != refresh.payload.get("REVOKE_TOKEN_CLAIM"):
return ValidationError(_("Invalid token payload"))
current_user_password = get_md5_hash_password(user.password)
if current_user_password != refresh.get("password"):
raise serializers.ValidationError({"message": _("Invalid token payload")})

# Set additional claims in the access token manually
additional_claims = {
Expand Down
60 changes: 30 additions & 30 deletions locale/ka/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-31 02:35+0400\n"
"POT-Creation-Date: 2024-10-31 13:07+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down Expand Up @@ -48,22 +48,22 @@ msgstr ""
"თქვენ არ გაქვთ ამ მოქმედების შესრულების უფლება, მომხმარებელი უნდა იყოს "
"მყიდველი."

#: apis/serializers.py:75 apis/serializers.py:304 apis/serializers.py:896
#: apis/serializers.py:915 apis/serializers.py:1079
#: apis/serializers.py:75 apis/serializers.py:310 apis/serializers.py:902
#: apis/serializers.py:921 apis/serializers.py:1085
msgid ""
"Enter a valid phone number with country code at the beginning. ex: +1 (208) "
"696-4143."
msgstr ""
"შეიყვანეთ ვალიდური ტელეფონის ნომერი, რომელიც შეიცავს ქვეყნის კოდს, "
"მაგალითად: +995 599 30-66-92."

#: apis/serializers.py:77 apis/serializers.py:306 apis/serializers.py:898
#: apis/serializers.py:917 apis/serializers.py:1081
#: apis/serializers.py:77 apis/serializers.py:312 apis/serializers.py:904
#: apis/serializers.py:923 apis/serializers.py:1087
msgid "Phone number field can not be left blank."
msgstr "ტელეფონის ნომრის ველი არ შეიძლება რომ იყოს ცარიელი."

#: apis/serializers.py:78 apis/serializers.py:307 apis/serializers.py:899
#: apis/serializers.py:918 apis/serializers.py:1082
#: apis/serializers.py:78 apis/serializers.py:313 apis/serializers.py:905
#: apis/serializers.py:924 apis/serializers.py:1088
msgid "Phone number field can not be null."
msgstr "ტელეფონის ნომრის ველი არ შეიძლება რომ იყოს null ტიპის."

Expand All @@ -75,115 +75,115 @@ msgstr ""
"მომხმარებელი ამ მეილით/ტელეფონის ნომრით ან პაროლით არ არსებობს, გთხოვოთ "
"ავტორიზაციის გავლა სცადოთ თავიდან."

#: apis/serializers.py:174 apis/serializers.py:566
#: apis/serializers.py:174 apis/serializers.py:572
msgid "User has not completed the registration process."
msgstr "მომხმარებელს არ დაუსრულებია რეგისტრაციის პროცესი."

#: apis/serializers.py:207
msgid "token_not_valid"
msgstr "ტოკენი ვალიდური არ არის."

#: apis/serializers.py:214
#: apis/serializers.py:214 apis/serializers.py:220
msgid "Invalid token payload"
msgstr "ტოკენის payload-ი არ არის ვალიდური."

#: apis/serializers.py:346
#: apis/serializers.py:352
msgid "This field is required for individuals."
msgstr "ინდივიდუალურმა მომხმარებლებმა ეს ველი აუცილებლად უნდა შეავსონ."

#: apis/serializers.py:347
#: apis/serializers.py:353
msgid "This field is required for companies."
msgstr "კომპანიამ ეს ველი აუცილებლად უნდა შეავსოს."

#: apis/serializers.py:349
#: apis/serializers.py:355
msgid "Company fields should not be provided for individuals."
msgstr "ინდივიდუალურ მომხმარებელს არ შეიძლება, რომ ჰქონდეს კომპანიის ველები."

#: apis/serializers.py:352
#: apis/serializers.py:358
msgid "Personal fields should not be provided for companies."
msgstr "კოპმანიას არ შეიძლება, რომ ჰქონდეს ინდივიდუალური მომხმარებლის ველები."

#: apis/serializers.py:354
#: apis/serializers.py:360
msgid "Company can only register with email."
msgstr "კომპანიას მხოლოდ მეილით შეუძლია დარეგისტრირება."

#: apis/serializers.py:355 apis/serializers.py:556
#: apis/serializers.py:361 apis/serializers.py:562
msgid "User already exists, please sign in."
msgstr "მომხმარებელი უკვე არსებობს, გთხოვთ გაიაროთ ავთენტიფიკაცია."

#: apis/serializers.py:356 apis/serializers.py:508
#: apis/serializers.py:362 apis/serializers.py:514
msgid "This company code is already taken."
msgstr "კომპანიის ეს კოდი უკვე ეკუთვნის სხვა კოპმანიას."

#: apis/serializers.py:365
#: apis/serializers.py:371
msgid "The two password fields must match."
msgstr "პაროლის ორივე ველი ერთმანეთს უნდა ემთხვეოდეს."

#: apis/serializers.py:486
#: apis/serializers.py:492
msgid ""
"An error occurred while creating user with phone number. Please try again."
msgstr "ინდივიდუალური მომხმარებლის პროფილის შეცვლისას error-მა იჩინა თავი."

#: apis/serializers.py:542
#: apis/serializers.py:548
msgid "An error occurred while creating user with email. Please try again."
msgstr "კომპანიის პროფილის შეცვლისას error-მა იჩინა თავი."

#: apis/serializers.py:579
#: apis/serializers.py:585
msgid ""
"User has already registered, OTP is already sent to the specified phone "
"number."
msgstr ""
"მომხმარებელი უკვე დარეგისტრირებულია, ერთჯერადი კოდი უკვე გაგზავნილია "
"მითითებულ ტელეფონის ნომერზე."

#: apis/serializers.py:583
#: apis/serializers.py:589
msgid ""
"User has already registered, OTP is already sent to the specified email."
msgstr ""
"მომხმარებელი უკვე დარეგისტრირებულია, ერთჯერადი კოდი უკვე გაგზავნილია "
"მითითებულ მეილზე."

#: apis/serializers.py:595
#: apis/serializers.py:601
msgid ""
"User has already registered, OTP has expired so we are sending new one to "
"specified phone number."
msgstr ""
"მომხმარებელი უკვე დარეგისტრირებულია, ერთჯერად კოდს ვადა გაუვიდა, ამიტომაც "
"გიგზავნით ახალ ერთჯერად კოდს მითითებულ ტელეფონის ნომერზე."

#: apis/serializers.py:602
#: apis/serializers.py:608
msgid ""
"User has already registered, OTP has expired so we are sending new one to "
"specified email."
msgstr ""
"მომხმარებელი უკვე დარეგისტრირებულია, ერთჯერად კოდს ვადა გაუვიდა, ამიტომაც "
"გიგზავნით ახალ ერთჯერად კოდს მითითებულ მეილზე."

#: apis/serializers.py:666
#: apis/serializers.py:672
msgid "Old password is incorrect"
msgstr "ძველი პაროლი არასწორია."

#: apis/serializers.py:674
#: apis/serializers.py:680
msgid "New passwords do not match"
msgstr "ახალი პაროლები ერთმანეთს არ ემთხვევა."

#: apis/serializers.py:677
#: apis/serializers.py:683
msgid "New password cannot be the same as the old password"
msgstr "ახალი პაროლი არ შეიძლება რომ იგივე იყოს რაც ძველი."

#: apis/serializers.py:939 apis/serializers.py:945
#: apis/serializers.py:945 apis/serializers.py:951
msgid "User does not exist"
msgstr "მომხმარებელი არ არსებობს."

#: apis/serializers.py:1011 apis/serializers.py:1014
#: apis/serializers.py:1017 apis/serializers.py:1020
msgid "Invalid value"
msgstr "მნიშვნელობა არავალიდურია."

#: apis/serializers.py:1022
#: apis/serializers.py:1028
msgid "The new password cannot be the same as the old password."
msgstr "ახალი პაროლი არ შეიძლება რომ იგივე იყოს რაც ძველი."

#: apis/serializers.py:1090
#: apis/serializers.py:1096
msgid "Message is too short. Please provide more details."
msgstr "მესიჯი ზედმეტად მოკლეა. გთხოვთ მოგვაწოდოთ მეტი ინფორმაცია."

Expand Down
42 changes: 42 additions & 0 deletions payments/migrations/0002_balance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Generated by Django 5.0.4 on 2024-11-01 11:31

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("payments", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name="Balance",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"amount",
models.DecimalField(decimal_places=2, default=0.0, max_digits=10),
),
(
"user",
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="balance",
to=settings.AUTH_USER_MODEL,
),
),
],
),
]
1 change: 1 addition & 0 deletions payments/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from payments.models.payment import Payment
from payments.models.balance import Balance
29 changes: 29 additions & 0 deletions payments/models/balance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models, transaction


class Balance(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="balance"
)
amount = models.DecimalField(max_digits=10, decimal_places=2, default=0.0)

def add(self, amount):
"""Add money to the balance."""
if amount <= 0:
raise ValidationError("Amount must be positive.")
with transaction.atomic():
self.amount += amount
self.save()

def subtract(self, amount):
"""Subtract money from the balance if funds are sufficient."""
if amount > self.amount:
raise ValidationError("Insufficient balance.")
with transaction.atomic():
self.amount -= amount
self.save()

def __str__(self):
return f"{self.user} - Balance: {self.amount}"
6 changes: 6 additions & 0 deletions payments/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ class Meta:
def validate_amount(self, value):
"""Convert dollars to cents for internal processing"""
return int(value * 100)


class DepositSerializer(serializers.Serializer):
amount = serializers.DecimalField(
min_value=0.01, max_digits=10, decimal_places=2, help_text="Amount to deposit."
)
11 changes: 10 additions & 1 deletion payments/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from django.urls import path

from .views import CreateCheckoutSession, stripe_webhook
from .views import (
BalanceView,
CreateCheckoutSession,
DepositBalanceView,
stripe_webhook,
)

urlpatterns = [
path(
Expand All @@ -9,4 +14,8 @@
name="create-checkout-session",
),
path("webhook/", stripe_webhook, name="stripe-webhook"),
path("balance/<uuid:user_id>/", BalanceView.as_view(), name="balance-view"),
path(
"deposit/", DepositBalanceView.as_view(), name="deposit-balance"
), # New deposit endpoint
]
Loading

0 comments on commit ddbce48

Please sign in to comment.