This commit is contained in:
Sayyid Hamid Mahdavi 2025-07-29 13:23:34 +03:30
parent 6037330c11
commit 2ccc838b11
5 changed files with 107 additions and 7 deletions

View file

@ -3,13 +3,15 @@ from .models import PaymentRequest, PNA, Fake
class PNAAdmin(admin.ModelAdmin):
list_display = ['pna_status_code', 'pna_status_message', 'created_at', 'payment_request']
list_display = ['pna_status_code', 'pna_status_message', 'jajali_datetime', 'payment_request']
list_filter = ['pna_status']
search_fields = ['pna_status_code', 'pna_status_message']
class PaymentRequestAdmin(admin.ModelAdmin):
list_display = ['state', 'uuid', 'amount', 'user_id', 'created_at', 'application', 'gateway']
search_fields = ['application__uuid','application__client_id', 'amount']
list_filter = ['application', 'state']
list_display = ['state', 'uuid', 'splited_amount', 'user_id', 'jajali_datetime', 'application', 'gateway']
search_fields = ['application__uuid','application__client_id', 'amount', 'user__uuid']
list_filter = ['application', 'state', 'gateway']
class FakeAdmin(admin.ModelAdmin):

View file

@ -1,6 +1,7 @@
import urllib.parse
from mimetypes import guess_all_extensions
import jdatetime
from django.conf import settings
from django.contrib import messages
from django.db import models
@ -43,6 +44,28 @@ class PaymentRequest(models.Model):
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
updated_at = models.DateTimeField(auto_now=True, db_index=True)
@property
def splited_amount(self):
def amount_split_3digit(value):
text = str(value)[::-1]
return ','.join([l[::-1] for l in [text[i:i + 3] for i in range(0, len(text), 3)][::-1]])
if self.amount:
amount_str = amount_split_3digit(str(self.amount))
return amount_str
return
@property
def jajali_datetime(self):
def to_jalali(value):
if value:
return jdatetime.datetime.fromgregorian(date=value, locale='fa_IR').strftime("%Y/%m/%d-%H:%M:%S")
else:
return value
return to_jalali(self.created_at)
def get_gateway_tools(self):
if self.gateway == GatewayChoise.PNA:
return PNA.objects.get(payment_request=self)
@ -155,6 +178,17 @@ class PNA(BasePGModel):
client = PNAClient()
@property
def jajali_datetime(self):
def to_jalali(value):
if value:
return jdatetime.datetime.fromgregorian(date=value, locale='fa_IR').strftime("%Y/%m/%d-%H:%M:%S")
else:
return value
return to_jalali(self.created_at)
def make_request(self):
self.payment_request.change_state(StateChoices.CREATED, StateChoices.IPG_PENDING, 'can not change state')
amount = self.payment_request.amount

View file

@ -61,13 +61,14 @@ MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.locale.LocaleMiddleware',
'django.middleware.locale.LocaleMiddleware',
'utils.i18n.ForceAdminLanguageMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'oauth2_provider.middleware.OAuth2TokenMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'utils.exceptions.ErrorMiddleware',
]
OAUTH2_PROVIDER_APPLICATION_MODEL = "gooyal_oauth2.Application"
@ -144,7 +145,6 @@ DATABASES = {
'HOST': config('DB_HOST', '127.0.0.1'),
'PORT': config('DB_PORT', ''),
}
}
# Password validation

50
utils/exceptions.py Normal file
View file

@ -0,0 +1,50 @@
import logging
from rest_framework.exceptions import APIException
from rest_framework.views import exception_handler as drf_exception_handler
logger = logging.getLogger(__name__)
def exception_handler(exc, context):
# پاسخ پیش‌فرض DRF را دریافت می‌کنیم
response = drf_exception_handler(exc, context)
if response is not None:
# ساختار دلخواه خود را تعریف می‌کنیم
response_data = {
'success': False,
'status_code': response.status_code,
'message': 'An error occurred',
'details': {}
}
if isinstance(exc, APIException):
response_data['message'] = exc.detail if isinstance(exc.detail, str) else "Validation error"
response_data['details'] = exc.detail if isinstance(exc.detail, dict) else {}
response.data = response_data
return response
# در فایل middleware.py
from django.http import JsonResponse
class ErrorMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def process_exception(self, request, exception):
logger.exception(exception)
return JsonResponse(
{
"success": False,
"status_code": 500,
"message": "Internal server error",
"details": str(exception) # فقط در حالت توسعه! در تولید بهتر است لاگ شود.
},
status=500
)

14
utils/i18n.py Normal file
View file

@ -0,0 +1,14 @@
from django.utils import translation
class ForceAdminLanguageMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.path.startswith('/admin/'):
translation.activate('fa')
request.LANGUAGE_CODE = 'fa'
else:
translation.activate('fa')
request.LANGUAGE_CODE = 'fa'
return self.get_response(request)