adding balance

This commit is contained in:
Sayyid Hamid Mahdavi 2025-05-13 16:35:58 +03:30
parent 87e403f7ca
commit 6621853c53
11 changed files with 69 additions and 20 deletions

View file

@ -1,3 +1,8 @@
from django.contrib import admin from django.contrib import admin
from .models import ChargeRequest
# Register your models here.
class ChargeRequestAdmin(admin.ModelAdmin):
pass
admin.site.register(ChargeRequest, ChargeRequestAdmin)

View file

@ -3,4 +3,4 @@ from django.apps import AppConfig
class PgConfig(AppConfig): class PgConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField' default_auto_field = 'django.db.models.BigAutoField'
name = 'pg' name = 'apps.pg'

View file

@ -7,3 +7,4 @@ class ChargeRequestForm(forms.ModelForm):
class Meta: class Meta:
model = ChargeRequest model = ChargeRequest
fields = []

View file

@ -0,0 +1,36 @@
# Generated by Django 5.1.7 on 2025-05-13 10:26
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
migrations.swappable_dependency(settings.OAUTH2_PROVIDER_APPLICATION_MODEL),
]
operations = [
migrations.CreateModel(
name='ChargeRequest',
fields=[
('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
('updated_at', models.DateTimeField(auto_now=True, db_index=True)),
('state', models.IntegerField(choices=[(1, 'created'), (2, 'delayed'), (3, 'pending'), (4, 'incomplete'), (5, 'success'), (6, 'failed'), (7, 'expected_failure')], default=1)),
('amount', models.PositiveBigIntegerField(blank=True, null=True)),
('callback_url', models.URLField(blank=True, null=True)),
('details', models.JSONField(blank=True, default=dict, null=True)),
('application', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
]

View file

@ -12,7 +12,7 @@ from utils.wallet_client import deposit_to_user_wallet_submit, withdraw_from_use
class ChargeRequest(BaseModel): class ChargeRequest(BaseModel):
application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT, application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT,
related_name='+', null=True) related_name='+', null=True, blank=True)
state = models.IntegerField(choices=StateChoices.choices, default=StateChoices.CREATED) state = models.IntegerField(choices=StateChoices.choices, default=StateChoices.CREATED)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
amount = models.PositiveBigIntegerField(null=True, blank=True) amount = models.PositiveBigIntegerField(null=True, blank=True)
@ -45,11 +45,11 @@ class ChargeRequest(BaseModel):
data = { data = {
"uuid": str(self.pk), "uuid": str(self.pk),
"payer_id": str(self.user.uuid), "payee_id": str(self.user.uuid),
"payer_type": 1, "payee_type": 1,
"amount": self.amount, "amount": self.amount,
"details": { "details": {
'description': "ad balance charge", 'description': "charge via IPG",
'reference_id': str(self.pk), 'reference_id': str(self.pk),
'application_details_url': '' 'application_details_url': ''
}, },

9
apps/pg/urls.py Normal file
View file

@ -0,0 +1,9 @@
from django.urls import path, include
from .views import ChargeRequestView, ChargeRequestCreateApiView
app_name = "pg"
urlpatterns = [
path('page/charge/<pk>/', ChargeRequestView.as_view(), name='charge-request-view'),
path('api/charge_create/', ChargeRequestCreateApiView.as_view(), name='charge-request-create-api-view'),
]

View file

@ -9,14 +9,14 @@ from oauth2_provider.contrib.rest_framework import TokenHasScope, IsAuthenticate
from rest_framework import generics from rest_framework import generics
from rest_framework.views import APIView from rest_framework.views import APIView
from .forms import ChargeForm from .forms import ChargeRequestForm
from .models import ChargeRequest from .models import ChargeRequest
from .serializers import ChargeRequestSerializer from .serializers import ChargeRequestSerializer
from .constans import StateChoices from .constans import StateChoices
from ..gooyal_oauth2.utils import get_application from ..gooyal_oauth2.utils import get_application
class ChargeRequestApiView(generics.CreateAPIView): class ChargeRequestCreateApiView(generics.CreateAPIView):
permission_classes = [IsAuthenticatedOrTokenHasScope] permission_classes = [IsAuthenticatedOrTokenHasScope]
serializer_class = ChargeRequestSerializer serializer_class = ChargeRequestSerializer
required_scopes = ['wallet.wallet:get_balance'] # TODO: is it good scope? required_scopes = ['wallet.wallet:get_balance'] # TODO: is it good scope?
@ -31,9 +31,9 @@ class ChargeRequestApiView(generics.CreateAPIView):
# charge_request.charge_wallet_balance() # charge_request.charge_wallet_balance()
class ChargeView(UpdateView): class ChargeRequestView(UpdateView):
template_name = 'pg/charge-request.html' template_name = 'pg/charge-request.html'
form_class = ChargeForm form_class = ChargeRequestForm
def get_queryset(self): def get_queryset(self):
return ChargeRequest.objects.all() return ChargeRequest.objects.all()
@ -58,11 +58,12 @@ class ChargeView(UpdateView):
# charge.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.SUCCESS.value) # charge.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.SUCCESS.value)
messages.success(self.request, 'شارژ انجام شد') messages.success(self.request, 'شارژ انجام شد')
except: except Exception as e:
print(e)
messages.error(self.request, 'خطایی رخ داده است') messages.error(self.request, 'خطایی رخ داده است')
charge_request.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.EXPECTED_FAILURE.value) charge_request.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.EXPECTED_FAILURE.value)
return HttpResponseRedirect(self.get_success_url()) return HttpResponseRedirect(self.get_success_url())
def get_success_url(self): def get_success_url(self):
return reverse('core:charge', kwargs={'pk': self.object.pk}) return reverse('pg:charge-request-view', kwargs={'pk': self.object.pk})

View file

@ -53,6 +53,7 @@ INSTALLED_APPS = [
'apps.core', 'apps.core',
'apps.users', 'apps.users',
'apps.gooyal_oauth2', 'apps.gooyal_oauth2',
'apps.pg'
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View file

@ -34,7 +34,7 @@ urlpatterns = [
path('swagger/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), path('swagger/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('', include('apps.core.urls')), path('', include('apps.pg.urls')),
# path('users/', include('apps.users.urls')), # path('users/', include('apps.users.urls')),
path('oauth2/', include('oauth2_provider.urls', namespace='oauth2_provider')), path('oauth2/', include('oauth2_provider.urls', namespace='oauth2_provider')),
] ]

View file

@ -46,7 +46,7 @@
<div class="m-0 p-0 w-100 " style="background-color: green; height: 3px;"></div> <div class="m-0 p-0 w-100 " style="background-color: green; height: 3px;"></div>
<main class="row overflow-auto pb-3"> <main class="row overflow-auto pb-3">
<div class="col pt-2"> <div class="col pt-2">
{% include "include/top_bar.html" %} {# {% include "include/top_bar.html" %}#}
{% include "include/messages.html" %} {% include "include/messages.html" %}
{# {% block breadcrumbs %}#} {# {% block breadcrumbs %}#}
{# {% render_breadcrumbs %}#} {# {% render_breadcrumbs %}#}

View file

@ -1,4 +1,4 @@
{% extends "base_charge.html" %} {% extends "base.html" %}
{% load static %} {% load static %}
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% load jalali_tags %} {% load jalali_tags %}
@ -8,7 +8,7 @@
{% block content %} {% block content %}
{% if object.state in '1' %} مبلغ {{ object.amount }} ریال با وضعیت {{ object.get_state_display }}<br>
<form action="{{ request.get_full_path }}" method="post" enctype="multipart/form-data"> <form action="{{ request.get_full_path }}" method="post" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<div class="row g-3"> <div class="row g-3">
@ -24,9 +24,5 @@
</div> </div>
</div> </div>
</form> </form>
{% else %}
{{ object.amount }} in state {{ object.get_state_display }}<br>
back to application
{% endif %}
{% endblock %} {% endblock %}