diff --git a/apps/pg/admin.py b/apps/pg/admin.py index cf2eea9..1dc9b08 100644 --- a/apps/pg/admin.py +++ b/apps/pg/admin.py @@ -1,15 +1,112 @@ -from django.contrib import admin +import logging +import io + +import jdatetime +import xlsxwriter +from django.contrib import admin, messages +from django.db.models import Sum +from django.http import HttpResponse +from django.utils import timezone +from django.utils.html import format_html +from django.shortcuts import redirect, get_object_or_404 +from django.urls import path + +from .constans import StateChoices from .models import PaymentRequest, PNA, Fake +logger = logging.getLogger(__name__) 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'] + + +@admin.action(description="export exel") +def export_exel(modeladmin, request, queryset): + output = io.BytesIO() + workbook = xlsxwriter.Workbook(output, options={"remove_timezone": True}) + worksheet = workbook.add_worksheet() + + for col, header in enumerate([]): + worksheet.write(0, col, header) + + for row, payment_request in enumerate(queryset, 1): + worksheet.write(row, 0, payment_request.amount) + worksheet.write(row, 1, str(payment_request.pk)) + worksheet.write(row, 2, str(payment_request.user.pk)) + worksheet.write(row, 3, payment_request.jajali_datetime) + worksheet.write(row, 4, payment_request.gateway) + worksheet.write(row, 5, payment_request.get_state_display()) + + workbook.close() + + # create a response + response = HttpResponse(content_type='application/vnd.ms-excel') + + # tell the browser what the file is named + file_name = jdatetime.date.fromgregorian(date=timezone.now(), locale='fa_IR').strftime("%Y/%m/%d") + response['Content-Disposition'] = f'attachment;filename="{file_name}.xlsx"' + + # put the spreadsheet data into the response + response.write(output.getvalue()) + + # return the response + return response + +@admin.action(description="mark as registered") +def mark_as_registered(model_admin, request, queryset): + for obj in queryset: + obj.is_registered = True + obj.save(update_fields=['is_registered']) 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', 'check_success_again', 'uuid', 'splited_amount', 'user_id', 'jajali_datetime', 'is_registered', 'created_at', 'application', 'gateway'] + search_fields = ['application__uuid','application__client_id', 'amount', 'user__uuid'] + list_filter = ['application', 'state', 'gateway'] + actions = [export_exel, mark_as_registered] + + + def changelist_view(self, request, extra_context=None): + extra_context = extra_context or {} + + cl = self.get_changelist_instance(request) + queryset = cl.result_list + totals = queryset.aggregate( + total_amount=Sum('amount'), + ) + extra_context['totals'] = totals + return super().changelist_view(request, extra_context=extra_context) + + def check_success_again(self, obj): + if obj.state in [StateChoices.IPG_SUCCESS, StateChoices.WALLET_SUBMIT_PENDING, StateChoices.WALLET_SUBMIT_SUCCESS]: + return format_html( + 'بررسی دوباره موفقیت', + f'{obj.uuid}/check_success_again/' + ) + return '' + + def get_urls(self): + urls = super().get_urls() + custom_urls = [ + path('/check_success_again/', self.admin_site.admin_view(self.check_success_again_view)) + ] + return custom_urls + urls + def check_success_again_view(self, request, payment_request_uuid): + logger.info(f"[Admin panel] Check success again for payment_request_uuid={payment_request_uuid}") + payment_request: PaymentRequest = get_object_or_404(PaymentRequest, uuid=payment_request_uuid) + logger.info(f"[Admin panel] initial payment_request state={payment_request.state}") + if payment_request.state == StateChoices.IPG_SUCCESS: + payment_request.charge_wallet_balance() + elif payment_request.state == StateChoices.WALLET_SUBMIT_PENDING: + payment_request.deposit_submit() + elif payment_request.state == StateChoices.WALLET_SUBMIT_SUCCESS: + payment_request.deposit_verify() + payment_request.refresh_from_db() + logger.info(f"[Admin panel] final payment_request state={payment_request.state}") + self.message_user(request, f"درخواست {payment_request_uuid} بررسی شد ✅") + return redirect(request.META.get("HTTP_REFERER", "..")) class FakeAdmin(admin.ModelAdmin): diff --git a/apps/pg/migrations/0006_paymentrequest_is_registered.py b/apps/pg/migrations/0006_paymentrequest_is_registered.py new file mode 100644 index 0000000..1ce1a07 --- /dev/null +++ b/apps/pg/migrations/0006_paymentrequest_is_registered.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.4 on 2025-10-14 11:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pg', '0005_fake'), + ] + + operations = [ + migrations.AddField( + model_name='paymentrequest', + name='is_registered', + field=models.BooleanField(default=False), + ), + ] diff --git a/apps/pg/migrations/0007_paymentrequest_commission.py b/apps/pg/migrations/0007_paymentrequest_commission.py new file mode 100644 index 0000000..b7bb0cd --- /dev/null +++ b/apps/pg/migrations/0007_paymentrequest_commission.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.4 on 2025-11-10 15:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pg', '0006_paymentrequest_is_registered'), + ] + + operations = [ + migrations.AddField( + model_name='paymentrequest', + name='commission', + field=models.PositiveBigIntegerField(null=True), + ), + ] diff --git a/apps/pg/models.py b/apps/pg/models.py index 4d7faa3..1adc4bb 100644 --- a/apps/pg/models.py +++ b/apps/pg/models.py @@ -1,6 +1,8 @@ -import urllib.parse -from mimetypes import guess_all_extensions +import logging +import urllib.parse + +import jdatetime from django.conf import settings from django.contrib import messages from django.db import models @@ -12,14 +14,15 @@ from apps.core.models import BaseModel, BasePGModel from apps.pg.constans import StateChoices import uuid -from utils.wallet_client import deposit_to_user_wallet_submit, withdraw_from_user_wallet_verify, \ - deposit_to_user_wallet_verify +from utils.clients.wallet_client import deposit_to_user_wallet_submit, deposit_to_user_wallet_verify +from utils.commons import calculate_pna_commission +from main import settings from utils.pna import PNAClient from utils.sep import SEPClient from django.utils.translation import gettext_lazy as _ - +logger = logging.getLogger(__name__) class GatewayChoise(TextChoices): FAKE = "fake", _("fake") @@ -40,12 +43,40 @@ class PaymentRequest(models.Model): state = models.IntegerField(choices=StateChoices.choices, default=StateChoices.CREATED) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT) amount = models.PositiveBigIntegerField(null=True, blank=True) + commission = models.PositiveBigIntegerField(null=True) phone_number = models.CharField(max_length=255, null=True, blank=True) callback_url = models.CharField(max_length=255, null=True, blank=True) + is_registered = models.BooleanField(default=False) + 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 save_commission(self): + self.commission = calculate_pna_commission(self.amount) + self.save(update_fields=['commission']) + def get_gateway_tools(self): if self.gateway == GatewayChoise.PNA: return PNA.objects.get(payment_request=self) @@ -79,6 +110,15 @@ class PaymentRequest(models.Model): self.save() + @property + def reference_number(self): + pna = PNA.objects.filter(payment_request=self).first() + if pna: + return pna.pk + + else: + return '00000000' + # TODO: complete and use this def change_state(self, from_state, to_state, error_message=None, **data): if self.state == from_state: @@ -93,7 +133,72 @@ class PaymentRequest(models.Model): else: raise Exception(error_message) + def deposit_submit(self): + data = { + "uuid": str(self.uuid), + "payee": str(self.user.uuid), + "payee_type": 1, + "payee_wallet": settings.WALLET_RIAL, + "amount": self.amount, + "details": { + 'description': str(_("charge via ipg")), + 'reference_id': str(self.uuid), + 'application_details_url': '' + }, + } + submit_response = deposit_to_user_wallet_submit(settings.WALLET_RIAL, data) + + if not submit_response or not submit_response.uuid: + logger.error(f"[Deposit Submit] Wallet submission failed | payment_id={self.pk}") + raise Exception('Failed to submit payment in wallet') + + to_success = PaymentRequest.objects.filter( + pk=self.pk, + state=StateChoices.WALLET_SUBMIT_PENDING.value, + ).update( + state=StateChoices.WALLET_SUBMIT_SUCCESS.value) + + if not to_success: + logger.error(f"[Deposit Submit] Failed to update state to WALLET_SUBMIT_SUCCESS | payment_id={self.pk}") + raise Exception('Cannot charge balance because state') + return to_success + + def deposit_verify(self): + verify_response = deposit_to_user_wallet_verify(settings.WALLET_RIAL, self.uuid) + + if not verify_response: + logger.error(f"[Deposit Verify] Failed to get response from wallet service | payment_id={self.pk}") + raise Exception('Failed to get response from wallet service') + + if not verify_response.uuid: + logger.error(f"[Deposit Verify] Failed to get response uuid from wallet service | payment_id={self.pk}") + raise Exception('Failed to get response uuid from wallet service') + + if verify_response.state != 5: + logger.error(f"[Deposit Verify] Wallet verification failed | payment_id={self.pk}, response={verify_response}") + # to_pay_failed = PaymentRequest.objects.filter( + # pk=self.pk, + # state=StateChoices.WALLET_SUBMIT_SUCCESS.value + # ).update( + # state=StateChoices.FAILED.value, + # ) + raise Exception('Failed to verify payment in wallet') + + to_pay_success = PaymentRequest.objects.filter( + pk=self.pk, + state=StateChoices.WALLET_SUBMIT_SUCCESS.value + ).update( + state=StateChoices.SUCCESS.value, + ) + + if not to_pay_success: + logger.error(f"[Deposit Verify] Failed to update state to SUCCESS | payment_id={self.pk}") + raise Exception('Failed to update state payment') + + return to_pay_success + def charge_wallet_balance(self): + logger.info(f"[Charge Wallet] Starting wallet charge process | payment_id={self.pk}") if self.state in [StateChoices.IPG_SUCCESS]: to_pending = PaymentRequest.objects.filter( pk=self.pk, @@ -101,54 +206,15 @@ class PaymentRequest(models.Model): ).update( state=StateChoices.WALLET_SUBMIT_PENDING.value) if not to_pending: + logger.error(f"[Charge Wallet] Failed to update state to WALLET_SUBMIT_PENDING | payment_id={self.pk}") raise Exception('Cannot charge balance because state') - - data = { - "uuid": str(self.uuid), - "payee_id": str(self.user.uuid), - "payee_type": 1, - "amount": self.amount, - "details": { - 'description': "charge via IPG", - 'reference_id': str(self.uuid), - 'application_details_url': '' - }, - } - submit_response = deposit_to_user_wallet_submit(data) - - if not submit_response.uuid: - raise Exception('Failed to submit payment in wallet') - - to_success = PaymentRequest.objects.filter( - pk=self.pk, - state=StateChoices.WALLET_SUBMIT_PENDING.value, - ).update( - state=StateChoices.WALLET_SUBMIT_SUCCESS.value) - - if not to_success: - raise Exception('Cannot charge balance because state') - - verify_response = deposit_to_user_wallet_verify(self.uuid) - - if not verify_response.uuid or verify_response.state != 5: - to_pay_failed = PaymentRequest.objects.filter( - pk=self.pk, - state=StateChoices.WALLET_SUBMIT_SUCCESS.value - ).update( - state=StateChoices.FAILED.value, - ) - raise Exception('Failed to verify payment in wallet') - - to_pay_success = PaymentRequest.objects.filter( - pk=self.pk, - state=StateChoices.WALLET_SUBMIT_SUCCESS.value - ).update( - state=StateChoices.SUCCESS.value, - ) - - if not to_pay_success: - raise Exception('Failed to update state payment') - + logger.info(f"[Charge Wallet] State updated to WALLET_SUBMIT_PENDING | payment_id={self.pk}") + self.deposit_submit() + to_pay_success = self.deposit_verify() + if to_pay_success: + logger.info(f"[Charge Wallet] Wallet charged successfully | payment_id={self.pk}") + else: + logger.warning(f"[Charge Wallet] Wallet charge verification failed | payment_id={self.pk}") return bool(to_pay_success) @@ -166,9 +232,20 @@ 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 + amount = self.payment_request.amount + self.payment_request.commission description = 'from addwin ipg' callback_url = urllib.parse.urljoin( settings.IPG_BASE_PUBLIC_URL, @@ -199,7 +276,7 @@ class PNA(BasePGModel): def confirm_request(self, request=None): if self.payment_request.state not in [StateChoices.IPG_PENDING]: messages.error(request, "وضعیت تراکنش در حالت مناسبی نیست.") - return + return False, "وضعیت تراکنش در حالت مناسبی نیست." print(dict(request.POST)) post_dict = dict(request.POST) @@ -223,13 +300,16 @@ class PNA(BasePGModel): self.payment_request.charge_wallet_balance() messages.success(request, 'شارژ انجام شد') + return True, 'شارژ انجام شد' except Exception as e: print(e) messages.error(request, str(e)) + return False, "خطایی رخ داده است." else: print(request.POST) messages.error(request, "نتیجه تراکنش از سمت درگاه دریافت نشد.") + return False, "نتیجه تراکنش از سمت درگاه دریافت نشد." def reverse_request(self): raise NotImplementedError() diff --git a/apps/pg/serializers.py b/apps/pg/serializers.py index 1f5f18f..3be3ace 100644 --- a/apps/pg/serializers.py +++ b/apps/pg/serializers.py @@ -39,3 +39,7 @@ class ApplicationPaymentRequestSerializer(serializers.ModelSerializer): read_only_fields = ['uuid', 'updated_at', 'state', 'created_at'] + +class CommissionSerializer(serializers.Serializer): + amount = serializers.IntegerField() + commission = serializers.IntegerField(read_only=True) \ No newline at end of file diff --git a/apps/pg/urls.py b/apps/pg/urls.py index febc622..5eb12ad 100644 --- a/apps/pg/urls.py +++ b/apps/pg/urls.py @@ -1,12 +1,13 @@ from django.urls import path, include from .views import PaymentRequestView, PaymentRequestCreateApiView, PaymentConfirmView, \ - ApplicationPaymentRequestCreateApiView + ApplicationPaymentRequestCreateApiView, CalculateCommissionView app_name = "pg" urlpatterns = [ path('page/charge//', PaymentRequestView.as_view(), name='payment-request-view'), - path('page/callback//', PaymentConfirmView.as_view(), name='payment-confirm-view'), + path('page/confirm//', PaymentConfirmView.as_view(), name='payment-confirm-view'), path('api/charge_create/', PaymentRequestCreateApiView.as_view(), name='charge-request-create-api-view'), path('api/application/charge_create/', ApplicationPaymentRequestCreateApiView.as_view(), name='application-user-charge-request-create-api-view'), + path('api/calculate_commission/', CalculateCommissionView.as_view(), name='calculate-commission-view'), ] diff --git a/apps/pg/views.py b/apps/pg/views.py index 5135177..79b1d47 100644 --- a/apps/pg/views.py +++ b/apps/pg/views.py @@ -1,24 +1,42 @@ from django.contrib import messages -from django.contrib.auth.decorators import login_required from django.http import HttpResponseRedirect, HttpResponse -from django.shortcuts import render from django.urls import reverse from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt -from django.views.generic import UpdateView, DetailView -from oauth2_provider.contrib.rest_framework import TokenHasScope, IsAuthenticatedOrTokenHasScope +from django.views.generic import UpdateView +from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope from rest_framework import generics +from rest_framework.response import Response from rest_framework.views import APIView +from drf_spectacular.utils import extend_schema +from django.shortcuts import render -from .forms import PaymentRequestForm -from .models import PaymentRequest, GatewayChoise -from .serializers import PaymentRequestSerializer, ApplicationPaymentRequestSerializer +from utils.commons import calculate_pna_commission from .constans import StateChoices +from .forms import PaymentRequestForm +from .models import PaymentRequest +from .serializers import PaymentRequestSerializer, CommissionSerializer from ..core.models import BasePGModel from ..gooyal_oauth2.utils import get_application from ..users.models import User +class CalculateCommissionView(APIView): + @extend_schema( + request=CommissionSerializer, + responses=CommissionSerializer + ) + def post(self, request): + serializer = CommissionSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + amount = serializer.validated_data['amount'] + commission = calculate_pna_commission(amount) + serializer = CommissionSerializer({ + "amount": amount, + "commission": commission + }) + return Response(serializer.data) + class PaymentRequestCreateApiView(generics.CreateAPIView): permission_classes = [IsAuthenticatedOrTokenHasScope] serializer_class = PaymentRequestSerializer @@ -50,12 +68,41 @@ class ApplicationPaymentRequestCreateApiView(generics.CreateAPIView): @method_decorator(csrf_exempt, name='dispatch') class PaymentRequestView(UpdateView): - template_name = 'pg/payment-request.html' + template_name = 'pg/payment_request.html' form_class = PaymentRequestForm # pk_url_kwarg = 'uuid' slug_field = 'uuid' slug_url_kwarg = 'uuid' + # TODO: remove it in future + def get(self, request, *args, **kwargs): + charge_request: PaymentRequest = self.get_object() + charge_request.set_gateway({'pna': True}) + charge_request.save_commission() + tool = charge_request.get_gateway_tools() + tool.make_request() + charge_request.refresh_from_db() + if charge_request.state == StateChoices.FAILED: + return render(request, 'pg/payment_failure.html', { + 'object': charge_request + }) + redirect_url = tool.get_pg_page_url() + return HttpResponseRedirect(redirect_url) + + # TODO: remove it in future + def post(self, request, *args, **kwargs): + charge_request: PaymentRequest = self.get_object() + charge_request.set_gateway({'pna': True}) + tool = charge_request.get_gateway_tools() + tool.make_request() + charge_request.refresh_from_db() + if charge_request.state == StateChoices.FAILED: + return render(request, 'pg/payment_failure.html', { + 'object': charge_request + }) + redirect_url = tool.get_pg_page_url() + return HttpResponseRedirect(redirect_url) + def get_queryset(self): # return ChargeRequest.objects.all() # return Charge.objects.filter(state__in=[StateChoices.CREATED.value, StateChoices.SUCCESS.value]) @@ -91,7 +138,8 @@ class PaymentRequestView(UpdateView): @method_decorator(csrf_exempt, name='dispatch') class PaymentConfirmView(UpdateView): - template_name = 'pg/payment-confirm.html' + # template_name = 'pg/payment_confirm.html' + template_name = 'pg/payment_failure.html' form_class = PaymentRequestForm # pk_url_kwarg = 'uuid' slug_field = 'uuid' @@ -107,7 +155,14 @@ class PaymentConfirmView(UpdateView): print(kwargs) self.object = self.get_object() tool = self.object.get_gateway_tools() - tool.confirm_request(request) + # state, message = tool.confirm_request(request) + # if state: + # self.template_name = 'pg/payment_success.html' + # + # + # # TODO: + # context = self.get_context_data(object=self.object) + # context['message'] = message context = self.get_context_data() return self.render_to_response(context) @@ -122,37 +177,13 @@ class PaymentConfirmView(UpdateView): if 'redirect-to-app' in request.POST: response = HttpResponse(status=302) - response['Location'] = self.object.callback_url + response['Location'] = self.object.callback_url + f'?state={self.object.state}' return response tool = self.object.get_gateway_tools() - tool.confirm_request(request) + state, message = tool.confirm_request(request) + if state: + self.template_name = 'pg/payment_success.html' context = self.get_context_data(object=self.object) + context['message'] = message return self.render_to_response(context) - - - # def form_valid(self, form): - # self.object = form.save() - # charge_request: ChargeRequest = self.get_object() - # try: - # - # # transaction = Transaction.objects.create( - # # uuid=charge.uuid, - # # payee_id=charge.user.pk, - # # payee_type=1, - # # payer_id=payer_pk, - # # payer_type=2, - # # amount=amount, - # # details={'description': 'شارژ مجازی کیف پول'} - # # ) - # # transaction.submit() - # # transaction.verify() - # # charge.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.SUCCESS.value) - # - # except Exception as e: - # print(e) - # messages.error(self.request, 'خطایی رخ داده است') - # charge_request.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.EXPECTED_FAILURE.value) - # - # return HttpResponseRedirect(self.get_success_url()) - diff --git a/gooyal_wallet_client/api/wallet/__init__.py b/gooyal_wallet_client/api/wallet/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/gooyal_wallet_client/api/wallet/wallet_api_application_balance_retrieve.py b/gooyal_wallet_client/api/wallet/wallet_api_application_balance_retrieve.py deleted file mode 100644 index 6e39db6..0000000 --- a/gooyal_wallet_client/api/wallet/wallet_api_application_balance_retrieve.py +++ /dev/null @@ -1,126 +0,0 @@ -from http import HTTPStatus -from typing import Any, Optional, Union - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.application_balance import ApplicationBalance -from ...types import Response - - -def _get_kwargs() -> dict[str, Any]: - _kwargs: dict[str, Any] = { - "method": "get", - "url": "/wallet/api/application/balance", - } - - return _kwargs - - -def _parse_response( - *, client: Union[AuthenticatedClient, Client], response: httpx.Response -) -> Optional[ApplicationBalance]: - if response.status_code == 200: - response_200 = ApplicationBalance.from_dict(response.json()) - - return response_200 - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: Union[AuthenticatedClient, Client], response: httpx.Response -) -> Response[ApplicationBalance]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - *, - client: AuthenticatedClient, -) -> Response[ApplicationBalance]: - """API for getting specified user or application balance. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[ApplicationBalance] - """ - - kwargs = _get_kwargs() - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - *, - client: AuthenticatedClient, -) -> Optional[ApplicationBalance]: - """API for getting specified user or application balance. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - ApplicationBalance - """ - - return sync_detailed( - client=client, - ).parsed - - -async def asyncio_detailed( - *, - client: AuthenticatedClient, -) -> Response[ApplicationBalance]: - """API for getting specified user or application balance. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[ApplicationBalance] - """ - - kwargs = _get_kwargs() - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - *, - client: AuthenticatedClient, -) -> Optional[ApplicationBalance]: - """API for getting specified user or application balance. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - ApplicationBalance - """ - - return ( - await asyncio_detailed( - client=client, - ) - ).parsed diff --git a/gooyal_wallet_client/api/wallet/wallet_api_wallet_balance_retrieve.py b/gooyal_wallet_client/api/wallet/wallet_api_wallet_balance_retrieve.py deleted file mode 100644 index a05375e..0000000 --- a/gooyal_wallet_client/api/wallet/wallet_api_wallet_balance_retrieve.py +++ /dev/null @@ -1,122 +0,0 @@ -from http import HTTPStatus -from typing import Any, Optional, Union - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.my_wallet import MyWallet -from ...types import Response - - -def _get_kwargs() -> dict[str, Any]: - _kwargs: dict[str, Any] = { - "method": "get", - "url": "/wallet/api/wallet/balance", - } - - return _kwargs - - -def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[MyWallet]: - if response.status_code == 200: - response_200 = MyWallet.from_dict(response.json()) - - return response_200 - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[MyWallet]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - *, - client: AuthenticatedClient, -) -> Response[MyWallet]: - """API for getting authenticated user balance. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[MyWallet] - """ - - kwargs = _get_kwargs() - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - *, - client: AuthenticatedClient, -) -> Optional[MyWallet]: - """API for getting authenticated user balance. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - MyWallet - """ - - return sync_detailed( - client=client, - ).parsed - - -async def asyncio_detailed( - *, - client: AuthenticatedClient, -) -> Response[MyWallet]: - """API for getting authenticated user balance. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[MyWallet] - """ - - kwargs = _get_kwargs() - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - *, - client: AuthenticatedClient, -) -> Optional[MyWallet]: - """API for getting authenticated user balance. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - MyWallet - """ - - return ( - await asyncio_detailed( - client=client, - ) - ).parsed diff --git a/gooyal_wallet_client/models/__init__.py b/gooyal_wallet_client/models/__init__.py deleted file mode 100644 index 30db318..0000000 --- a/gooyal_wallet_client/models/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Contains all the data models used in inputs/outputs""" - -from .application_balance import ApplicationBalance -from .application_deposit import ApplicationDeposit -from .application_transaction import ApplicationTransaction -from .application_withdraw import ApplicationWithdraw -from .my_wallet import MyWallet -from .paginated_application_transaction_list import PaginatedApplicationTransactionList -from .paginated_user_transaction_list import PaginatedUserTransactionList -from .payee_type_enum import PayeeTypeEnum -from .payer_type_enum import PayerTypeEnum -from .state_enum import StateEnum -from .user_transaction import UserTransaction - -__all__ = ( - "ApplicationBalance", - "ApplicationDeposit", - "ApplicationTransaction", - "ApplicationWithdraw", - "MyWallet", - "PaginatedApplicationTransactionList", - "PaginatedUserTransactionList", - "PayeeTypeEnum", - "PayerTypeEnum", - "StateEnum", - "UserTransaction", -) diff --git a/gooyal_wallet_client/models/application_balance.py b/gooyal_wallet_client/models/application_balance.py deleted file mode 100644 index c094cc5..0000000 --- a/gooyal_wallet_client/models/application_balance.py +++ /dev/null @@ -1,58 +0,0 @@ -from typing import Any, TypeVar, Union - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -T = TypeVar("T", bound="ApplicationBalance") - - -@_attrs_define -class ApplicationBalance: - """ - Attributes: - balance (Union[Unset, int]): - """ - - balance: Union[Unset, int] = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - balance = self.balance - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if balance is not UNSET: - field_dict["balance"] = balance - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: - d = src_dict.copy() - balance = d.pop("balance", UNSET) - - application_balance = cls( - balance=balance, - ) - - application_balance.additional_properties = d - return application_balance - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/gooyal_wallet_client/models/application_deposit.py b/gooyal_wallet_client/models/application_deposit.py deleted file mode 100644 index 267dc45..0000000 --- a/gooyal_wallet_client/models/application_deposit.py +++ /dev/null @@ -1,235 +0,0 @@ -import datetime -from typing import Any, TypeVar, Union, cast -from uuid import UUID - -from attrs import define as _attrs_define -from attrs import field as _attrs_field -from dateutil.parser import isoparse - -from ..models.payee_type_enum import PayeeTypeEnum -from ..models.payer_type_enum import PayerTypeEnum -from ..models.state_enum import StateEnum -from ..types import UNSET, Unset - -T = TypeVar("T", bound="ApplicationDeposit") - - -@_attrs_define -class ApplicationDeposit: - """ - Attributes: - uuid (UUID): - payer_id (Union[None, UUID]): - payer_type (Union[None, PayerTypeEnum]): - payee_id (UUID): - created_at (Union[None, datetime.datetime]): - state (StateEnum): * `1` - created - * `2` - delayed - * `3` - pending - * `4` - incomplete - * `5` - success - * `6` - failed - * `7` - expected_failure - amount (int): - updated_at (Union[None, datetime.datetime]): - payee_type (Union[None, PayeeTypeEnum, Unset]): - details (Union[Unset, Any]): - """ - - uuid: UUID - payer_id: Union[None, UUID] - payer_type: Union[None, PayerTypeEnum] - payee_id: UUID - created_at: Union[None, datetime.datetime] - state: StateEnum - amount: int - updated_at: Union[None, datetime.datetime] - payee_type: Union[None, PayeeTypeEnum, Unset] = UNSET - details: Union[Unset, Any] = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - uuid = str(self.uuid) - - payer_id: Union[None, str] - if isinstance(self.payer_id, UUID): - payer_id = str(self.payer_id) - else: - payer_id = self.payer_id - - payer_type: Union[None, int] - if isinstance(self.payer_type, PayerTypeEnum): - payer_type = self.payer_type.value - else: - payer_type = self.payer_type - - payee_id = str(self.payee_id) - - created_at: Union[None, str] - if isinstance(self.created_at, datetime.datetime): - created_at = self.created_at.isoformat() - else: - created_at = self.created_at - - state = self.state.value - - amount = self.amount - - updated_at: Union[None, str] - if isinstance(self.updated_at, datetime.datetime): - updated_at = self.updated_at.isoformat() - else: - updated_at = self.updated_at - - payee_type: Union[None, Unset, int] - if isinstance(self.payee_type, Unset): - payee_type = UNSET - elif isinstance(self.payee_type, PayeeTypeEnum): - payee_type = self.payee_type.value - else: - payee_type = self.payee_type - - details = self.details - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "uuid": uuid, - "payer_id": payer_id, - "payer_type": payer_type, - "payee_id": payee_id, - "created_at": created_at, - "state": state, - "amount": amount, - "updated_at": updated_at, - } - ) - if payee_type is not UNSET: - field_dict["payee_type"] = payee_type - if details is not UNSET: - field_dict["details"] = details - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: - d = src_dict.copy() - uuid = UUID(d.pop("uuid")) - - def _parse_payer_id(data: object) -> Union[None, UUID]: - if data is None: - return data - try: - if not isinstance(data, str): - raise TypeError() - payer_id_type_0 = UUID(data) - - return payer_id_type_0 - except: # noqa: E722 - pass - return cast(Union[None, UUID], data) - - payer_id = _parse_payer_id(d.pop("payer_id")) - - def _parse_payer_type(data: object) -> Union[None, PayerTypeEnum]: - if data is None: - return data - try: - if not isinstance(data, int): - raise TypeError() - payer_type_type_0 = PayerTypeEnum(data) - - return payer_type_type_0 - except: # noqa: E722 - pass - return cast(Union[None, PayerTypeEnum], data) - - payer_type = _parse_payer_type(d.pop("payer_type")) - - payee_id = UUID(d.pop("payee_id")) - - def _parse_created_at(data: object) -> Union[None, datetime.datetime]: - if data is None: - return data - try: - if not isinstance(data, str): - raise TypeError() - created_at_type_0 = isoparse(data) - - return created_at_type_0 - except: # noqa: E722 - pass - return cast(Union[None, datetime.datetime], data) - - created_at = _parse_created_at(d.pop("created_at")) - - state = StateEnum(d.pop("state")) - - amount = d.pop("amount") - - def _parse_updated_at(data: object) -> Union[None, datetime.datetime]: - if data is None: - return data - try: - if not isinstance(data, str): - raise TypeError() - updated_at_type_0 = isoparse(data) - - return updated_at_type_0 - except: # noqa: E722 - pass - return cast(Union[None, datetime.datetime], data) - - updated_at = _parse_updated_at(d.pop("updated_at")) - - def _parse_payee_type(data: object) -> Union[None, PayeeTypeEnum, Unset]: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, int): - raise TypeError() - payee_type_type_0 = PayeeTypeEnum(data) - - return payee_type_type_0 - except: # noqa: E722 - pass - return cast(Union[None, PayeeTypeEnum, Unset], data) - - payee_type = _parse_payee_type(d.pop("payee_type", UNSET)) - - details = d.pop("details", UNSET) - - application_deposit = cls( - uuid=uuid, - payer_id=payer_id, - payer_type=payer_type, - payee_id=payee_id, - created_at=created_at, - state=state, - amount=amount, - updated_at=updated_at, - payee_type=payee_type, - details=details, - ) - - application_deposit.additional_properties = d - return application_deposit - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/gooyal_wallet_client/models/application_transaction.py b/gooyal_wallet_client/models/application_transaction.py deleted file mode 100644 index 0bd6ab3..0000000 --- a/gooyal_wallet_client/models/application_transaction.py +++ /dev/null @@ -1,238 +0,0 @@ -import datetime -from typing import Any, TypeVar, Union, cast -from uuid import UUID - -from attrs import define as _attrs_define -from attrs import field as _attrs_field -from dateutil.parser import isoparse - -from ..models.payer_type_enum import PayerTypeEnum -from ..models.state_enum import StateEnum -from ..types import UNSET, Unset - -T = TypeVar("T", bound="ApplicationTransaction") - - -@_attrs_define -class ApplicationTransaction: - """ - Attributes: - uuid (UUID): - payee_id (UUID): - payee_type (UUID): - created_at (Union[None, datetime.datetime]): - state (StateEnum): * `1` - created - * `2` - delayed - * `3` - pending - * `4` - incomplete - * `5` - success - * `6` - failed - * `7` - expected_failure - amount (int): - updated_at (Union[None, datetime.datetime]): - details (Any): - role (str): - payer_id (Union[None, UUID, Unset]): - payer_type (Union[None, PayerTypeEnum, Unset]): - delay (Union[Unset, int]): - """ - - uuid: UUID - payee_id: UUID - payee_type: UUID - created_at: Union[None, datetime.datetime] - state: StateEnum - amount: int - updated_at: Union[None, datetime.datetime] - details: Any - role: str - payer_id: Union[None, UUID, Unset] = UNSET - payer_type: Union[None, PayerTypeEnum, Unset] = UNSET - delay: Union[Unset, int] = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - uuid = str(self.uuid) - - payee_id = str(self.payee_id) - - payee_type = str(self.payee_type) - - created_at: Union[None, str] - if isinstance(self.created_at, datetime.datetime): - created_at = self.created_at.isoformat() - else: - created_at = self.created_at - - state = self.state.value - - amount = self.amount - - updated_at: Union[None, str] - if isinstance(self.updated_at, datetime.datetime): - updated_at = self.updated_at.isoformat() - else: - updated_at = self.updated_at - - details = self.details - - role = self.role - - payer_id: Union[None, Unset, str] - if isinstance(self.payer_id, Unset): - payer_id = UNSET - elif isinstance(self.payer_id, UUID): - payer_id = str(self.payer_id) - else: - payer_id = self.payer_id - - payer_type: Union[None, Unset, int] - if isinstance(self.payer_type, Unset): - payer_type = UNSET - elif isinstance(self.payer_type, PayerTypeEnum): - payer_type = self.payer_type.value - else: - payer_type = self.payer_type - - delay = self.delay - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "uuid": uuid, - "payee_id": payee_id, - "payee_type": payee_type, - "created_at": created_at, - "state": state, - "amount": amount, - "updated_at": updated_at, - "details": details, - "role": role, - } - ) - if payer_id is not UNSET: - field_dict["payer_id"] = payer_id - if payer_type is not UNSET: - field_dict["payer_type"] = payer_type - if delay is not UNSET: - field_dict["delay"] = delay - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: - d = src_dict.copy() - uuid = UUID(d.pop("uuid")) - - payee_id = UUID(d.pop("payee_id")) - - payee_type = UUID(d.pop("payee_type")) - - def _parse_created_at(data: object) -> Union[None, datetime.datetime]: - if data is None: - return data - try: - if not isinstance(data, str): - raise TypeError() - created_at_type_0 = isoparse(data) - - return created_at_type_0 - except: # noqa: E722 - pass - return cast(Union[None, datetime.datetime], data) - - created_at = _parse_created_at(d.pop("created_at")) - - state = StateEnum(d.pop("state")) - - amount = d.pop("amount") - - def _parse_updated_at(data: object) -> Union[None, datetime.datetime]: - if data is None: - return data - try: - if not isinstance(data, str): - raise TypeError() - updated_at_type_0 = isoparse(data) - - return updated_at_type_0 - except: # noqa: E722 - pass - return cast(Union[None, datetime.datetime], data) - - updated_at = _parse_updated_at(d.pop("updated_at")) - - details = d.pop("details") - - role = d.pop("role") - - def _parse_payer_id(data: object) -> Union[None, UUID, Unset]: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, str): - raise TypeError() - payer_id_type_0 = UUID(data) - - return payer_id_type_0 - except: # noqa: E722 - pass - return cast(Union[None, UUID, Unset], data) - - payer_id = _parse_payer_id(d.pop("payer_id", UNSET)) - - def _parse_payer_type(data: object) -> Union[None, PayerTypeEnum, Unset]: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, int): - raise TypeError() - payer_type_type_0 = PayerTypeEnum(data) - - return payer_type_type_0 - except: # noqa: E722 - pass - return cast(Union[None, PayerTypeEnum, Unset], data) - - payer_type = _parse_payer_type(d.pop("payer_type", UNSET)) - - delay = d.pop("delay", UNSET) - - application_transaction = cls( - uuid=uuid, - payee_id=payee_id, - payee_type=payee_type, - created_at=created_at, - state=state, - amount=amount, - updated_at=updated_at, - details=details, - role=role, - payer_id=payer_id, - payer_type=payer_type, - delay=delay, - ) - - application_transaction.additional_properties = d - return application_transaction - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/gooyal_wallet_client/models/application_withdraw.py b/gooyal_wallet_client/models/application_withdraw.py deleted file mode 100644 index cd473a2..0000000 --- a/gooyal_wallet_client/models/application_withdraw.py +++ /dev/null @@ -1,239 +0,0 @@ -import datetime -from typing import Any, TypeVar, Union, cast -from uuid import UUID - -from attrs import define as _attrs_define -from attrs import field as _attrs_field -from dateutil.parser import isoparse - -from ..models.payee_type_enum import PayeeTypeEnum -from ..models.payer_type_enum import PayerTypeEnum -from ..models.state_enum import StateEnum -from ..types import UNSET, Unset - -T = TypeVar("T", bound="ApplicationWithdraw") - - -@_attrs_define -class ApplicationWithdraw: - """ - Attributes: - uuid (UUID): - payee_id (UUID): - payee_type (Union[None, PayeeTypeEnum]): - created_at (Union[None, datetime.datetime]): - state (StateEnum): * `1` - created - * `2` - delayed - * `3` - pending - * `4` - incomplete - * `5` - success - * `6` - failed - * `7` - expected_failure - amount (int): - updated_at (Union[None, datetime.datetime]): - details (Any): - payer_id (Union[None, UUID, Unset]): - payer_type (Union[None, PayerTypeEnum, Unset]): - """ - - uuid: UUID - payee_id: UUID - payee_type: Union[None, PayeeTypeEnum] - created_at: Union[None, datetime.datetime] - state: StateEnum - amount: int - updated_at: Union[None, datetime.datetime] - details: Any - payer_id: Union[None, UUID, Unset] = UNSET - payer_type: Union[None, PayerTypeEnum, Unset] = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - uuid = str(self.uuid) - - payee_id = str(self.payee_id) - - payee_type: Union[None, int] - if isinstance(self.payee_type, PayeeTypeEnum): - payee_type = self.payee_type.value - else: - payee_type = self.payee_type - - created_at: Union[None, str] - if isinstance(self.created_at, datetime.datetime): - created_at = self.created_at.isoformat() - else: - created_at = self.created_at - - state = self.state.value - - amount = self.amount - - updated_at: Union[None, str] - if isinstance(self.updated_at, datetime.datetime): - updated_at = self.updated_at.isoformat() - else: - updated_at = self.updated_at - - details = self.details - - payer_id: Union[None, Unset, str] - if isinstance(self.payer_id, Unset): - payer_id = UNSET - elif isinstance(self.payer_id, UUID): - payer_id = str(self.payer_id) - else: - payer_id = self.payer_id - - payer_type: Union[None, Unset, int] - if isinstance(self.payer_type, Unset): - payer_type = UNSET - elif isinstance(self.payer_type, PayerTypeEnum): - payer_type = self.payer_type.value - else: - payer_type = self.payer_type - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "uuid": uuid, - "payee_id": payee_id, - "payee_type": payee_type, - "created_at": created_at, - "state": state, - "amount": amount, - "updated_at": updated_at, - "details": details, - } - ) - if payer_id is not UNSET: - field_dict["payer_id"] = payer_id - if payer_type is not UNSET: - field_dict["payer_type"] = payer_type - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: - d = src_dict.copy() - uuid = UUID(d.pop("uuid")) - - payee_id = UUID(d.pop("payee_id")) - - def _parse_payee_type(data: object) -> Union[None, PayeeTypeEnum]: - if data is None: - return data - try: - if not isinstance(data, int): - raise TypeError() - payee_type_type_0 = PayeeTypeEnum(data) - - return payee_type_type_0 - except: # noqa: E722 - pass - return cast(Union[None, PayeeTypeEnum], data) - - payee_type = _parse_payee_type(d.pop("payee_type")) - - def _parse_created_at(data: object) -> Union[None, datetime.datetime]: - if data is None: - return data - try: - if not isinstance(data, str): - raise TypeError() - created_at_type_0 = isoparse(data) - - return created_at_type_0 - except: # noqa: E722 - pass - return cast(Union[None, datetime.datetime], data) - - created_at = _parse_created_at(d.pop("created_at")) - - state = StateEnum(d.pop("state")) - - amount = d.pop("amount") - - def _parse_updated_at(data: object) -> Union[None, datetime.datetime]: - if data is None: - return data - try: - if not isinstance(data, str): - raise TypeError() - updated_at_type_0 = isoparse(data) - - return updated_at_type_0 - except: # noqa: E722 - pass - return cast(Union[None, datetime.datetime], data) - - updated_at = _parse_updated_at(d.pop("updated_at")) - - details = d.pop("details") - - def _parse_payer_id(data: object) -> Union[None, UUID, Unset]: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, str): - raise TypeError() - payer_id_type_0 = UUID(data) - - return payer_id_type_0 - except: # noqa: E722 - pass - return cast(Union[None, UUID, Unset], data) - - payer_id = _parse_payer_id(d.pop("payer_id", UNSET)) - - def _parse_payer_type(data: object) -> Union[None, PayerTypeEnum, Unset]: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, int): - raise TypeError() - payer_type_type_0 = PayerTypeEnum(data) - - return payer_type_type_0 - except: # noqa: E722 - pass - return cast(Union[None, PayerTypeEnum, Unset], data) - - payer_type = _parse_payer_type(d.pop("payer_type", UNSET)) - - application_withdraw = cls( - uuid=uuid, - payee_id=payee_id, - payee_type=payee_type, - created_at=created_at, - state=state, - amount=amount, - updated_at=updated_at, - details=details, - payer_id=payer_id, - payer_type=payer_type, - ) - - application_withdraw.additional_properties = d - return application_withdraw - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/gooyal_wallet_client/models/my_wallet.py b/gooyal_wallet_client/models/my_wallet.py deleted file mode 100644 index 16f9ade..0000000 --- a/gooyal_wallet_client/models/my_wallet.py +++ /dev/null @@ -1,58 +0,0 @@ -from typing import Any, TypeVar, Union - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -T = TypeVar("T", bound="MyWallet") - - -@_attrs_define -class MyWallet: - """ - Attributes: - balance (Union[Unset, int]): - """ - - balance: Union[Unset, int] = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - balance = self.balance - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if balance is not UNSET: - field_dict["balance"] = balance - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: - d = src_dict.copy() - balance = d.pop("balance", UNSET) - - my_wallet = cls( - balance=balance, - ) - - my_wallet.additional_properties = d - return my_wallet - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/gooyal_wallet_client/models/payee_type_enum.py b/gooyal_wallet_client/models/payee_type_enum.py deleted file mode 100644 index 2d56dd5..0000000 --- a/gooyal_wallet_client/models/payee_type_enum.py +++ /dev/null @@ -1,9 +0,0 @@ -from enum import IntEnum - - -class PayeeTypeEnum(IntEnum): - VALUE_1 = 1 - VALUE_2 = 2 - - def __str__(self) -> str: - return str(self.value) diff --git a/gooyal_wallet_client/models/payer_type_enum.py b/gooyal_wallet_client/models/payer_type_enum.py deleted file mode 100644 index f49196c..0000000 --- a/gooyal_wallet_client/models/payer_type_enum.py +++ /dev/null @@ -1,9 +0,0 @@ -from enum import IntEnum - - -class PayerTypeEnum(IntEnum): - VALUE_1 = 1 - VALUE_2 = 2 - - def __str__(self) -> str: - return str(self.value) diff --git a/gooyal_wallet_client/models/user_transaction.py b/gooyal_wallet_client/models/user_transaction.py deleted file mode 100644 index fcc64cf..0000000 --- a/gooyal_wallet_client/models/user_transaction.py +++ /dev/null @@ -1,238 +0,0 @@ -import datetime -from typing import Any, TypeVar, Union, cast -from uuid import UUID - -from attrs import define as _attrs_define -from attrs import field as _attrs_field -from dateutil.parser import isoparse - -from ..models.payer_type_enum import PayerTypeEnum -from ..models.state_enum import StateEnum -from ..types import UNSET, Unset - -T = TypeVar("T", bound="UserTransaction") - - -@_attrs_define -class UserTransaction: - """ - Attributes: - uuid (UUID): - payee_id (UUID): - payee_type (UUID): - created_at (Union[None, datetime.datetime]): - state (StateEnum): * `1` - created - * `2` - delayed - * `3` - pending - * `4` - incomplete - * `5` - success - * `6` - failed - * `7` - expected_failure - amount (int): - updated_at (Union[None, datetime.datetime]): - details (Any): - role (int): - payer_id (Union[None, UUID, Unset]): - payer_type (Union[None, PayerTypeEnum, Unset]): - delay (Union[Unset, int]): - """ - - uuid: UUID - payee_id: UUID - payee_type: UUID - created_at: Union[None, datetime.datetime] - state: StateEnum - amount: int - updated_at: Union[None, datetime.datetime] - details: Any - role: int - payer_id: Union[None, UUID, Unset] = UNSET - payer_type: Union[None, PayerTypeEnum, Unset] = UNSET - delay: Union[Unset, int] = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - uuid = str(self.uuid) - - payee_id = str(self.payee_id) - - payee_type = str(self.payee_type) - - created_at: Union[None, str] - if isinstance(self.created_at, datetime.datetime): - created_at = self.created_at.isoformat() - else: - created_at = self.created_at - - state = self.state.value - - amount = self.amount - - updated_at: Union[None, str] - if isinstance(self.updated_at, datetime.datetime): - updated_at = self.updated_at.isoformat() - else: - updated_at = self.updated_at - - details = self.details - - role = self.role - - payer_id: Union[None, Unset, str] - if isinstance(self.payer_id, Unset): - payer_id = UNSET - elif isinstance(self.payer_id, UUID): - payer_id = str(self.payer_id) - else: - payer_id = self.payer_id - - payer_type: Union[None, Unset, int] - if isinstance(self.payer_type, Unset): - payer_type = UNSET - elif isinstance(self.payer_type, PayerTypeEnum): - payer_type = self.payer_type.value - else: - payer_type = self.payer_type - - delay = self.delay - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "uuid": uuid, - "payee_id": payee_id, - "payee_type": payee_type, - "created_at": created_at, - "state": state, - "amount": amount, - "updated_at": updated_at, - "details": details, - "role": role, - } - ) - if payer_id is not UNSET: - field_dict["payer_id"] = payer_id - if payer_type is not UNSET: - field_dict["payer_type"] = payer_type - if delay is not UNSET: - field_dict["delay"] = delay - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: - d = src_dict.copy() - uuid = UUID(d.pop("uuid")) - - payee_id = UUID(d.pop("payee_id")) - - payee_type = UUID(d.pop("payee_type")) - - def _parse_created_at(data: object) -> Union[None, datetime.datetime]: - if data is None: - return data - try: - if not isinstance(data, str): - raise TypeError() - created_at_type_0 = isoparse(data) - - return created_at_type_0 - except: # noqa: E722 - pass - return cast(Union[None, datetime.datetime], data) - - created_at = _parse_created_at(d.pop("created_at")) - - state = StateEnum(d.pop("state")) - - amount = d.pop("amount") - - def _parse_updated_at(data: object) -> Union[None, datetime.datetime]: - if data is None: - return data - try: - if not isinstance(data, str): - raise TypeError() - updated_at_type_0 = isoparse(data) - - return updated_at_type_0 - except: # noqa: E722 - pass - return cast(Union[None, datetime.datetime], data) - - updated_at = _parse_updated_at(d.pop("updated_at")) - - details = d.pop("details") - - role = d.pop("role") - - def _parse_payer_id(data: object) -> Union[None, UUID, Unset]: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, str): - raise TypeError() - payer_id_type_0 = UUID(data) - - return payer_id_type_0 - except: # noqa: E722 - pass - return cast(Union[None, UUID, Unset], data) - - payer_id = _parse_payer_id(d.pop("payer_id", UNSET)) - - def _parse_payer_type(data: object) -> Union[None, PayerTypeEnum, Unset]: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, int): - raise TypeError() - payer_type_type_0 = PayerTypeEnum(data) - - return payer_type_type_0 - except: # noqa: E722 - pass - return cast(Union[None, PayerTypeEnum, Unset], data) - - payer_type = _parse_payer_type(d.pop("payer_type", UNSET)) - - delay = d.pop("delay", UNSET) - - user_transaction = cls( - uuid=uuid, - payee_id=payee_id, - payee_type=payee_type, - created_at=created_at, - state=state, - amount=amount, - updated_at=updated_at, - details=details, - role=role, - payer_id=payer_id, - payer_type=payer_type, - delay=delay, - ) - - user_transaction.additional_properties = d - return user_transaction - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/locale/ar/LC_MESSAGES/django.mo b/locale/ar/LC_MESSAGES/django.mo new file mode 100644 index 0000000..74dbaf6 Binary files /dev/null and b/locale/ar/LC_MESSAGES/django.mo differ diff --git a/locale/ar/LC_MESSAGES/django.po b/locale/ar/LC_MESSAGES/django.po new file mode 100644 index 0000000..c3dc886 --- /dev/null +++ b/locale/ar/LC_MESSAGES/django.po @@ -0,0 +1,120 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-09 14:04+0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +#: apps/pg/constans.py:6 +msgid "created" +msgstr "" + +#: apps/pg/constans.py:7 +msgid "ipg pending" +msgstr "" + +#: apps/pg/constans.py:8 +msgid "ipg success" +msgstr "" + +#: apps/pg/constans.py:10 +msgid "wallet submit pending" +msgstr "" + +#: apps/pg/constans.py:11 +msgid "wallet submit success" +msgstr "" + +#: apps/pg/constans.py:13 +msgid "failed" +msgstr "" + +#: apps/pg/constans.py:14 +msgid "expected failure" +msgstr "" + +#: apps/pg/constans.py:15 +msgid "success" +msgstr "" + +#: apps/pg/constans.py:19 +msgid "user" +msgstr "" + +#: apps/pg/constans.py:20 +msgid "application" +msgstr "" + +#: apps/pg/models.py:24 +msgid "fake" +msgstr "" + +#: apps/pg/models.py:25 +msgid "pna" +msgstr "" + +#: apps/pg/models.py:133 +msgid "charge via ipg" +msgstr "" + +#: apps/users/models.py:49 +msgid "password" +msgstr "" + +#: apps/users/models.py:52 +msgid "username" +msgstr "" + +#: apps/users/models.py:55 +msgid "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only." +msgstr "" + +#: apps/users/models.py:58 +msgid "A user with that username already exists." +msgstr "" + +#: apps/users/models.py:64 +msgid "last update" +msgstr "" + +#: apps/users/models.py:65 +msgid "last login" +msgstr "" + +#: apps/users/models.py:66 +msgid "date joined" +msgstr "" + +#: main/settings.py:184 +msgid "English" +msgstr "" + +#: main/settings.py:185 +msgid "Persian" +msgstr "" + +#: main/settings.py:186 +msgid "Arabic" +msgstr "" + +#: main/settings.py:187 +msgid "Turkish" +msgstr "" + +#: templates/admin/input_filter.html:5 +#, python-format +msgid " By %(filter_title)s " +msgstr "" diff --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo new file mode 100644 index 0000000..71cbdf3 Binary files /dev/null and b/locale/en/LC_MESSAGES/django.mo differ diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po new file mode 100644 index 0000000..584b9ba --- /dev/null +++ b/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,119 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-09 14:04+0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +#: apps/pg/constans.py:6 +msgid "created" +msgstr "" + +#: apps/pg/constans.py:7 +msgid "ipg pending" +msgstr "" + +#: apps/pg/constans.py:8 +msgid "ipg success" +msgstr "" + +#: apps/pg/constans.py:10 +msgid "wallet submit pending" +msgstr "" + +#: apps/pg/constans.py:11 +msgid "wallet submit success" +msgstr "" + +#: apps/pg/constans.py:13 +msgid "failed" +msgstr "" + +#: apps/pg/constans.py:14 +msgid "expected failure" +msgstr "" + +#: apps/pg/constans.py:15 +msgid "success" +msgstr "" + +#: apps/pg/constans.py:19 +msgid "user" +msgstr "" + +#: apps/pg/constans.py:20 +msgid "application" +msgstr "" + +#: apps/pg/models.py:24 +msgid "fake" +msgstr "" + +#: apps/pg/models.py:25 +msgid "pna" +msgstr "" + +#: apps/pg/models.py:133 +msgid "charge via ipg" +msgstr "" + +#: apps/users/models.py:49 +msgid "password" +msgstr "" + +#: apps/users/models.py:52 +msgid "username" +msgstr "" + +#: apps/users/models.py:55 +msgid "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only." +msgstr "" + +#: apps/users/models.py:58 +msgid "A user with that username already exists." +msgstr "" + +#: apps/users/models.py:64 +msgid "last update" +msgstr "" + +#: apps/users/models.py:65 +msgid "last login" +msgstr "" + +#: apps/users/models.py:66 +msgid "date joined" +msgstr "" + +#: main/settings.py:184 +msgid "English" +msgstr "" + +#: main/settings.py:185 +msgid "Persian" +msgstr "" + +#: main/settings.py:186 +msgid "Arabic" +msgstr "" + +#: main/settings.py:187 +msgid "Turkish" +msgstr "" + +#: templates/admin/input_filter.html:5 +#, python-format +msgid " By %(filter_title)s " +msgstr "" diff --git a/locale/fa/LC_MESSAGES/django.mo b/locale/fa/LC_MESSAGES/django.mo new file mode 100644 index 0000000..2e8cd0d Binary files /dev/null and b/locale/fa/LC_MESSAGES/django.mo differ diff --git a/locale/fa/LC_MESSAGES/django.po b/locale/fa/LC_MESSAGES/django.po new file mode 100644 index 0000000..6252a0f --- /dev/null +++ b/locale/fa/LC_MESSAGES/django.po @@ -0,0 +1,119 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-09 14:03+0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +#: apps/pg/constans.py:6 +msgid "created" +msgstr "" + +#: apps/pg/constans.py:7 +msgid "ipg pending" +msgstr "" + +#: apps/pg/constans.py:8 +msgid "ipg success" +msgstr "" + +#: apps/pg/constans.py:10 +msgid "wallet submit pending" +msgstr "" + +#: apps/pg/constans.py:11 +msgid "wallet submit success" +msgstr "" + +#: apps/pg/constans.py:13 +msgid "failed" +msgstr "" + +#: apps/pg/constans.py:14 +msgid "expected failure" +msgstr "" + +#: apps/pg/constans.py:15 +msgid "success" +msgstr "" + +#: apps/pg/constans.py:19 +msgid "user" +msgstr "" + +#: apps/pg/constans.py:20 +msgid "application" +msgstr "" + +#: apps/pg/models.py:24 +msgid "fake" +msgstr "" + +#: apps/pg/models.py:25 +msgid "pna" +msgstr "" + +#: apps/pg/models.py:133 +msgid "charge via ipg" +msgstr "افزایش موجودی از طریق پرداخت آنلاین" + +#: apps/users/models.py:49 +msgid "password" +msgstr "" + +#: apps/users/models.py:52 +msgid "username" +msgstr "" + +#: apps/users/models.py:55 +msgid "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only." +msgstr "" + +#: apps/users/models.py:58 +msgid "A user with that username already exists." +msgstr "" + +#: apps/users/models.py:64 +msgid "last update" +msgstr "" + +#: apps/users/models.py:65 +msgid "last login" +msgstr "" + +#: apps/users/models.py:66 +msgid "date joined" +msgstr "" + +#: main/settings.py:184 +msgid "English" +msgstr "انگلیسی" + +#: main/settings.py:185 +msgid "Persian" +msgstr "فارسی" + +#: main/settings.py:186 +msgid "Arabic" +msgstr "عربی" + +#: main/settings.py:187 +msgid "Turkish" +msgstr "ترکی" + +#: templates/admin/input_filter.html:5 +#, python-format +msgid " By %(filter_title)s " +msgstr "" diff --git a/locale/tr/LC_MESSAGES/django.mo b/locale/tr/LC_MESSAGES/django.mo new file mode 100644 index 0000000..2c90dd0 Binary files /dev/null and b/locale/tr/LC_MESSAGES/django.mo differ diff --git a/locale/tr/LC_MESSAGES/django.po b/locale/tr/LC_MESSAGES/django.po new file mode 100644 index 0000000..dd60a8c --- /dev/null +++ b/locale/tr/LC_MESSAGES/django.po @@ -0,0 +1,119 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-09-09 14:04+0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +#: apps/pg/constans.py:6 +msgid "created" +msgstr "" + +#: apps/pg/constans.py:7 +msgid "ipg pending" +msgstr "" + +#: apps/pg/constans.py:8 +msgid "ipg success" +msgstr "" + +#: apps/pg/constans.py:10 +msgid "wallet submit pending" +msgstr "" + +#: apps/pg/constans.py:11 +msgid "wallet submit success" +msgstr "" + +#: apps/pg/constans.py:13 +msgid "failed" +msgstr "" + +#: apps/pg/constans.py:14 +msgid "expected failure" +msgstr "" + +#: apps/pg/constans.py:15 +msgid "success" +msgstr "" + +#: apps/pg/constans.py:19 +msgid "user" +msgstr "" + +#: apps/pg/constans.py:20 +msgid "application" +msgstr "" + +#: apps/pg/models.py:24 +msgid "fake" +msgstr "" + +#: apps/pg/models.py:25 +msgid "pna" +msgstr "" + +#: apps/pg/models.py:133 +msgid "charge via ipg" +msgstr "" + +#: apps/users/models.py:49 +msgid "password" +msgstr "" + +#: apps/users/models.py:52 +msgid "username" +msgstr "" + +#: apps/users/models.py:55 +msgid "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only." +msgstr "" + +#: apps/users/models.py:58 +msgid "A user with that username already exists." +msgstr "" + +#: apps/users/models.py:64 +msgid "last update" +msgstr "" + +#: apps/users/models.py:65 +msgid "last login" +msgstr "" + +#: apps/users/models.py:66 +msgid "date joined" +msgstr "" + +#: main/settings.py:184 +msgid "English" +msgstr "" + +#: main/settings.py:185 +msgid "Persian" +msgstr "" + +#: main/settings.py:186 +msgid "Arabic" +msgstr "" + +#: main/settings.py:187 +msgid "Turkish" +msgstr "" + +#: templates/admin/input_filter.html:5 +#, python-format +msgid " By %(filter_title)s " +msgstr "" diff --git a/main/settings.py b/main/settings.py index 5632a26..1c406a3 100644 --- a/main/settings.py +++ b/main/settings.py @@ -48,6 +48,7 @@ INSTALLED_APPS = [ 'crispy_bootstrap5', 'django_filters', 'jalali_date', + 'django_admin_logs', # local apps 'apps.core', @@ -61,13 +62,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" @@ -76,12 +78,12 @@ OAUTH2_PROVIDER_ID_TOKEN_MODEL = "gooyal_oauth2.IDToken" OAUTH2_PROVIDER_GRANT_MODEL = "gooyal_oauth2.Grant" OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = "gooyal_oauth2.RefreshToken" -BASE_OAUTH2_PROVIDER_PUBLIC_URL = config("BASE_OAUTH2_PROVIDER_PUBLIC_URL") -BASE_OAUTH2_PROVIDER_PRIVATE_URL = config("BASE_OAUTH2_PROVIDER_PRIVATE_URL") +OAUTH2_PROVIDER_BASE_PUBLIC_URL = config("OAUTH2_PROVIDER_BASE_PUBLIC_URL") +OAUTH2_PROVIDER_BASE_PRIVATE_URL = config("OAUTH2_PROVIDER_BASE_PRIVATE_URL") -CLIENT_ID = config('CLIENT_ID') -CLIENT_SECRET = config('CLIENT_SECRET') -SCOPES = config('SCOPES', default='') +OAUTH2_PROVIDER_CLIENT_ID = config('OAUTH2_PROVIDER_CLIENT_ID') +OAUTH2_PROVIDER_CLIENT_SECRET = config('OAUTH2_PROVIDER_CLIENT_SECRET') +OAUTH2_PROVIDER_SCOPES = config('OAUTH2_PROVIDER_SCOPES', default='') OAUTH2_PROVIDER = { # this is the list of available scopes # 'SCOPES_BACKEND_CLASS': 'apps.gooyal_oauth2.scopes.Scopes', @@ -90,22 +92,24 @@ OAUTH2_PROVIDER = { # 'groups': 'Access to your groups', # 'introspection': 'Introspect token scope'}, 'OAUTH2_VALIDATOR_CLASS': 'apps.gooyal_oauth2.validators.OAuth2Validator', - 'RESOURCE_SERVER_INTROSPECTION_URL': BASE_OAUTH2_PROVIDER_PRIVATE_URL + '/introspect/', + 'RESOURCE_SERVER_INTROSPECTION_URL': OAUTH2_PROVIDER_BASE_PRIVATE_URL + '/introspect/', # 'RESOURCE_SERVER_AUTH_TOKEN': '3yUqsWtwKYKHnfivFcJu', # OR this but not both: - 'RESOURCE_SERVER_INTROSPECTION_CREDENTIALS': (CLIENT_ID, CLIENT_SECRET), + 'RESOURCE_SERVER_INTROSPECTION_CREDENTIALS': (OAUTH2_PROVIDER_CLIENT_ID, OAUTH2_PROVIDER_CLIENT_SECRET), } REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'oauth2_provider.contrib.rest_framework.OAuth2Authentication', 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.TokenAuthentication', ), 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), - 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 'PAGE_SIZE': 200, "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", + 'EXCEPTION_HANDLER': 'utils.exceptions.exception_handler', } ROOT_URLCONF = 'main.urls' @@ -144,7 +148,6 @@ DATABASES = { 'HOST': config('DB_HOST', '127.0.0.1'), 'PORT': config('DB_PORT', ''), } - } # Password validation @@ -170,13 +173,20 @@ AUTH_PASSWORD_VALIDATORS = [ LANGUAGE_CODE = 'en-us' -TIME_ZONE = 'UTC' +TIME_ZONE = 'Asia/Tehran' USE_I18N = True USE_L10N = True -USE_TZ = True +USE_TZ = False + +LANGUAGES = [ + ('en', _('English')), + ('fa', _('Persian')), + ('ar', _('Arabic')), + ('tr', _('Turkish')), +] LOCALE_PATHS = [ BASE_DIR / 'locale', @@ -237,16 +247,61 @@ JALALI_DATE_DEFAULTS = { CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", - "LOCATION": config('BASE_REDIS_URL'), + "LOCATION": config('REDIS_BASE_URL'), "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } } -PNA_CORPORATION_PIN = config('PNA_CORPORATION_PIN') -WALLET_BASE_PUBLIC_URL = config('WALLET_BASE_PUBLIC_URL') -IPG_BASE_PUBLIC_URL = config('IPG_BASE_PUBLIC_URL') +LOKI_BASE_PUBLIC_URL = config('LOKI_BASE_PUBLIC_URL', default=None, cast=str) + + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'loki': { + 'class': 'utils.logs.LokiFormatter', # required + }, + }, + + 'handlers': { + 'loki': { + 'level': 'DEBUG', # Log level. Required + 'class': 'utils.logs.LokiHandler', # Required + 'formatter': 'loki', # Loki formatter. Required + 'timeout': 2, # Post request timeout, default is 0.5. Optional + 'url': f'{LOKI_BASE_PUBLIC_URL}/loki/api/v1/push', # Loki url. Defaults to localhost. Optional. + # 'auth': ("user", "password"), # Basic auth to authenticate with loki. Default is None (i.e. no auth). Optional + 'tags': {"app": "ipg"}, # Tags / Labels to attach to the log. Optional, but strongly encoraged to use. + 'mode': 'thread', # Push mode. Can be 'sync' or 'thread'. Sync is blocking, thread is non-blocking. Defaults to sync. Optional. + }, + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + # 'formatter': 'verbose', + }, + }, + 'loggers': { + '': { + 'handlers': ['console', 'loki'], + 'level': 'INFO', + 'propagate': True, + }, + }, +} + +PNA_CORPORATION_PIN = config('PNA_CORPORATION_PIN') +WALLET_BASE_PUBLIC_URL = config('WALLET_BASE_PUBLIC_URL') +WALLET_RIAL = config('WALLET_RIAL') +IPG_BASE_PUBLIC_URL = config('IPG_BASE_PUBLIC_URL') + +COMMISSION_LEVEL1 = config('COMMISSION_LEVEL1', cast=int) +COMMISSION_LEVEL2_MIN_AMOUNT = config('COMMISSION_LEVEL2_MIN_AMOUNT', cast=int) +COMMISSION_LEVEL2_MAX_AMOUNT = config('COMMISSION_LEVEL2_MAX_AMOUNT', cast=int) +COMMISSION_LEVEL2_RATE = config('COMMISSION_LEVEL2_RATE', cast=float) +COMMISSION_LEVEL3 = config('COMMISSION_LEVEL3', cast=int) SEP_TERMINAL_ID = config('SEP_TERMINAL_ID') SEP_TERMINAL_PASSWORD = config('SEP_TERMINAL_PASSWORD') \ No newline at end of file diff --git a/requirements.in b/requirements.in index 47bd1bb..c6a14d0 100644 --- a/requirements.in +++ b/requirements.in @@ -16,4 +16,7 @@ django-oauth-toolkit redis celery httpx -django-redis \ No newline at end of file +django-redis +xlsxwriter +xlrd +django_admin_logs \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index fb0e1f6..65e6719 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.11 +# This file is autogenerated by pip-compile with Python 3.13 # by the following command: # # pip-compile @@ -12,8 +12,6 @@ asgiref==3.8.1 # via # django # django-cors-headers -async-timeout==5.0.1 - # via redis attrs==24.3.0 # via # jsonschema @@ -51,6 +49,7 @@ django==5.1.4 # via # -r requirements.in # crispy-bootstrap5 + # django-admin-logs # django-cors-headers # django-crispy-forms # django-filter @@ -59,6 +58,8 @@ django==5.1.4 # django-redis # djangorestframework # drf-spectacular +django-admin-logs==1.4.0 + # via -r requirements.in django-cors-headers==4.6.0 # via -r requirements.in django-crispy-forms==2.3 @@ -156,9 +157,7 @@ sqlparse==0.5.3 # via django typing-extensions==4.12.2 # via - # anyio # jwcrypto - # psycopg # psycopg-pool tzdata==2024.2 # via @@ -175,6 +174,10 @@ vine==5.1.0 # kombu wcwidth==0.2.13 # via prompt-toolkit +xlrd==2.0.2 + # via -r requirements.in +xlsxwriter==3.2.5 + # via -r requirements.in zope-event==5.0 # via gevent zope-interface==7.2 diff --git a/static/css/datetimepicker.css b/static/css/datetimepicker.css new file mode 100644 index 0000000..ea9cf87 --- /dev/null +++ b/static/css/datetimepicker.css @@ -0,0 +1,34 @@ +.cursorily{ cursor: pointer;} +.hov:hover{ color: #000;} +.ico-size{font-size: 16px;} +.ico-size-month{font-size: 26px!important; line-height: 26px!important;} +.ico-size-large{ font-size: 40px!important; line-height: 30px;} +.dtp_main{ border: solid 1px #eee; border-radius: 3px; background-color: #fff; padding: 8px 0 8px 8px;} +.dtp_main span, .dtp_main i{ display: inline-block; padding-right: 8px;} +.dtp_modal-win{position: fixed;left: 0; top: 0; width: 100%; height: 100%; + z-index: 999; background-color: #eeeeee; opacity: 0.6;} +.dtp_modal-content{ background-color: #fff; border-radius: 10px; width: 624px; + position: absolute; z-index: 1000; top: 100px; left: 100px; font-size: 16px;font-weight: normal;} +.dtp_modal-content-no-time{ background-color: #fff; border-radius: 10px; width: 312px; + position: absolute; z-index: 1000; top: 100px; left: 100px; font-size: 16px;font-weight: normal;} +.dtp_modal-title{ border-bottom: solid 3px #54646b; padding: 16px 36px; margin-bottom: 16px; font-size: 22px; } +.dtp_modal-cell-date{ width: 312px; float: right; margin-bottom: 22px; margin-top: 6px;} +.dtp_modal-cell-time{width: 311px; float: left; direction: ltr; border-right: solid 1px #000;} +.dtp_modal-months{ color: #7d7d7d; text-align: center; font-size: 20px; padding: 0 20px;} +.dtp_modal-months span{ display: inline-block; padding: 10px 20px; width: 182px;} +.dtp_modal-calendar{ width: 266px; margin-left: 22px; } +.dtp_modal-calendar-cell{ width: 38px; padding: 7px 0; display: inline-block; text-align: center;} +.dtp_modal-colored{ color: #54646b; } +.dtp_modal-grey{ color: #7d7d7d; } +.dtp_modal-cell-selected{ background-color: #54646b; border-radius: 48%; transition: background-color 1s ease-out;} +.dtp_modal-time-block{ height: 212px; width: 310px; } +.dpt_modal-button{ background-color: #54646b; color: #fff; font-size: 24px; padding: 8px 40px; float: left; + text-align: center; display: inline-block; margin-left: 22px; cursor: pointer; border: solid 1px #fff; +border-radius: 3px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);} +.dtp_modal-time-line{ text-align: center; color: #7d7d7d; font-size: 20px; padding-top: 15px; } +.dtp_modal-time-mechanic{ padding-top: 16px;} +.dtp_modal-append{ color: #7d7d7d; padding-left: 108px; font-weight: normal; } +.dtp_modal-midle{ display: inline-block; width: 40px; } +.dtp_modal-midle-dig{display: inline-block; width: 16px; text-align: center; } +.dtp_modal-digits{ font-size: 50px; padding-left: 96px;} +.dtp_modal-digit{ } diff --git a/static/image/pg/fail.png b/static/image/pg/fail.png new file mode 100644 index 0000000..ec72d92 Binary files /dev/null and b/static/image/pg/fail.png differ diff --git a/static/image/pg/tik.png b/static/image/pg/tik.png new file mode 100644 index 0000000..c6beb97 Binary files /dev/null and b/static/image/pg/tik.png differ diff --git a/static/js/datetimepicker.js b/static/js/datetimepicker.js new file mode 100644 index 0000000..adb871e --- /dev/null +++ b/static/js/datetimepicker.js @@ -0,0 +1,396 @@ +(function ($) { + 'use strict'; + $.fn.dateTimePicker = function (options) { + + var settings = $.extend({ + selectData: "now", + dateFormat: "YYYY-MM-DD HH:mm", + showTime: true, + locale: 'en', + positionShift: { top: 20, left: 0}, + title: "Select Date and Time", + buttonTitle: "Select", + allowBackwards: false + }, options); + moment.locale(settings.locale); + var elem = this; + var limitation = {"hour": 23, "minute": 59}; + var mousedown = false; + var timeout = 800; + var selectDate = settings.selectData == "now" ? moment() : moment(settings.selectData, settings.dateFormat); + if (selectDate < moment() && (settings.allowBackwards == false)) { + selectDate = moment(); + } + var startDate = copyDate(moment()); + var lastSelected = copyDate(selectDate); + return this.each(function () { + if (lastSelected != selectDate) { + selectDate = copyDate(lastSelected); + } + elem.addClass("dtp_main"); + updateMainElemGlobal(); + // elem.text(selectDate.format(settings.dateFormat)); + function updateMainElemGlobal() { + var arrF = settings.dateFormat.split(' '); + if (settings.showTime && arrF.length != 2) { + arrF.length = 2; + arrF[0] = 'DD/MM/YY'; + arrF[1] = 'HH:mm'; + } + var $s = $(''); + $s.text(lastSelected.format(arrF[0])); + elem.empty(); + elem.append($s); + $s = $(''); + $s.addClass('fa fa-calendar ico-size'); + elem.append($s); + if (settings.showTime) { + $s = $(''); + $s.text(lastSelected.format(arrF[1])); + elem.append($s); + $s = $(''); + $s.addClass('fa fa-clock-o ico-size'); + elem.append($s); + } + } + elem.on('click', function () { + var $win = $(''); + $win.addClass("dtp_modal-win"); + var $body = $('body'); + $body.append($win); + var $content = createContent(); + $body.append($content); + var offset = elem.offset(); + $content.css({top: (offset.top + settings.positionShift.top) + "px", left: (offset.left + settings.positionShift.left) + "px"}); + feelDates(selectDate); + $win.on('click', function () { + $content.remove(); + $win.remove(); + }) + if (settings.showTime) { + attachChangeTime(); + var $fieldTime = $('#field-time'); + var $hour = $fieldTime.find('#d-hh'); + var $minute = $fieldTime.find('#d-mm'); + } + + function feelDates(selectM) { + var $fDate = $content.find('#field-data'); + $fDate.empty(); + $fDate.append(createMonthPanel(selectM)); + $fDate.append(createCalendar(selectM)); + } + + function createCalendar(selectedMonth) { + var $c = $(''); + $c.addClass('dtp_modal-calendar'); + for (var i = 0; i < 7; i++) { + var $e = $(''); + $e.addClass('dtp_modal-calendar-cell dtp_modal-colored'); + $e.text(moment().weekday(i).format('ddd')); + $c.append($e); + } + var m = copyDate(selectedMonth); + m.date(1); + // console.log(m.format('DD--MM--YYYY')); + // console.log(selectData.format('DD--MM--YYYY')); + // console.log(m.weekday()); + var flagStart = totalMonths(selectedMonth) === totalMonths(startDate); + var flagSelect = totalMonths(lastSelected) === totalMonths(selectedMonth); + var cerDay = parseInt(selectedMonth.format('D')); + var dayNow = parseInt(startDate.format('D')); + for (var i = 0; i < 6; i++) { + for (var j = 0; j < 7; j++) { + var $b = $(''); + $b.html(' '); + $b.addClass('dtp_modal-calendar-cell'); + if (m.month() == selectedMonth.month() && m.weekday() == j) { + var day = parseInt(m.format('D')); + $b.text(day); + if (flagStart && day < dayNow) { + + if (settings.allowBackwards == false) { + $b.addClass('dtp_modal-grey'); + } else { + $b.addClass('cursorily'); + $b.bind('click', changeDate); + } + + } + else if (flagSelect && day == cerDay) { + $b.addClass('dtp_modal-cell-selected'); + } + else { + $b.addClass('cursorily'); + $b.bind('click', changeDate); + } + m.add(1, 'days'); + } + $c.append($b); + } + } + return $c; + } + + function changeDate() { + + var $div = $(this); + selectDate.date($div.text()); + lastSelected = copyDate(selectDate); + updateDate(); + var $fDate = $content.find('#field-data'); + var old = $fDate.find('.dtp_modal-cell-selected'); + old.removeClass('dtp_modal-cell-selected'); + old.addClass('cursorily'); + $div.addClass('dtp_modal-cell-selected'); + $div.removeClass('cursorily'); + old.bind('click', changeDate); + $div.unbind('click'); + // console.log(selectDate.format('DD-MM-YYYY')); + } + + function createMonthPanel(selectMonth) { + var $d = $(''); + $d.addClass('dtp_modal-months'); + var $s = $(''); + $s.addClass('fa fa-angle-left cursorily ico-size-month hov'); + //$s.attr('data-fa-mask', 'fas fa-circle'); + $s.bind('click', prevMonth); + $d.append($s); + $s = $(''); + $s.text(selectMonth.format("MMMM YYYY")); + $d.append($s); + $s = $(''); + $s.addClass('fa fa-angle-right cursorily ico-size-month hov'); + $s.bind('click', nextMonth); + $d.append($s); + return $d; + } + + function close() { + if (settings.showTime) { + lastSelected.hour(parseInt($hour.text())); + lastSelected.minute(parseInt($minute.text())); + selectDate.hour(parseInt($hour.text())); + selectDate.minute(parseInt($minute.text())); + } + updateDate(); + $content.remove(); + $win.remove(); + } + + function nextMonth() { + selectDate.add(1, 'month'); + feelDates(selectDate); + } + + function prevMonth() { + if (totalMonths(selectDate) > totalMonths(startDate) || settings.allowBackwards == true) { + selectDate.add(-1, 'month'); + feelDates(selectDate); + } + } + + function attachChangeTime() { + var $angles = $($content).find('i[id^="angle-"]'); + // $angles.bind('click', changeTime); + $angles.bind('mouseup', function () { + mousedown = false; + timeout = 800; + }); + $angles.bind('mousedown', function () { + mousedown = true; + changeTime(this); + }); + } + + function changeTime(el) { + var $el = this || el; + $el = $($el); + ///angle-up-hour angle-up-minute angle-down-hour angle-down-minute + var arr = $el.attr('id').split('-'); + var increment = 1; + if (arr[1] == 'down') { + increment = -1; + } + appendIncrement(arr[2], increment); + setTimeout(function () { + autoIncrement($el); + }, timeout); + } + + function autoIncrement(el) { + if (mousedown) { + if (timeout > 200) { + timeout -= 200; + } + changeTime(el); + } + } + + function appendIncrement(typeDigits, increment) { + + var $i = typeDigits == "hour" ? $hour : $minute; + var val = parseInt($i.text()) + increment; + if (val < 0) { + val = limitation[typeDigits]; + } + else if (val > limitation[typeDigits]) { + val = 0; + } + $i.text(formatDigits(val)); + } + + function formatDigits(val) { + + if (val < 10) { + return '0' + val; + } + return val; + } + + function createTimer() { + var $div = $(''); + $div.addClass('dtp_modal-time-mechanic'); + var $panel = $(''); + $panel.addClass('dtp_modal-append'); + var $i = $(''); + $i.attr('id', 'angle-up-hour'); + $i.addClass('fa fa-angle-up ico-size-large cursorily hov'); + $panel.append($i); + var $m = $(''); + $m.addClass('dtp_modal-midle'); + $panel.append($m); + $i = $(''); + $i.attr('id', 'angle-up-minute'); + $i.addClass('fa fa-angle-up ico-size-large cursorily hov'); + $panel.append($i); + $div.append($panel); + + $panel = $(''); + $panel.addClass('dtp_modal-digits'); + var $d = $(''); + $d.addClass('dtp_modal-digit'); + $d.attr('id', 'd-hh'); + $d.text(lastSelected.format('HH')); + $panel.append($d); + $m = $(''); + $m.addClass('dtp_modal-midle-dig'); + $m.html(':'); + $panel.append($m); + $d = $(''); + $d.addClass('dtp_modal-digit'); + $d.attr('id', 'd-mm'); + $d.text(lastSelected.format('mm')); + $panel.append($d); + $div.append($panel); + + $panel = $(''); + $panel.addClass('dtp_modal-append'); + $i = $(''); + $i.attr('id', 'angle-down-hour'); + $i.addClass('fa fa-angle-down ico-size-large cursorily hov'); + $panel.append($i); + $m = $(''); + $m.addClass('dtp_modal-midle'); + $panel.append($m); + $i = $(''); + $i.attr('id', 'angle-down-minute'); + $i.addClass('fa fa-angle-down ico-size-large cursorily hov'); + $panel.append($i); + $div.append($panel); + return $div; + } + + function createContent() { + var $c = $(''); + if (settings.showTime) { + $c.addClass("dtp_modal-content"); + } + else { + $c.addClass("dtp_modal-content-no-time"); + } + var $el = $(''); + $el.addClass("dtp_modal-title"); + $el.text(settings.title); + $c.append($el); + $el = $(''); + $el.addClass('dtp_modal-cell-date'); + $el.attr('id', 'field-data'); + $c.append($el); + if (settings.showTime) { + $el = $(''); + $el.addClass('dtp_modal-cell-time'); + var $a = $(''); + $a.addClass('dtp_modal-time-block'); + $a.attr('id', 'field-time'); + $el.append($a); + var $line = $(''); + $line.attr('id', 'time-line'); + $line.addClass('dtp_modal-time-line'); + $line.text(lastSelected.format(settings.dateFormat)); + + $a.append($line); + $a.append(createTimer()); + var $but = $(''); + $but.addClass('dpt_modal-button'); + $but.text(settings.buttonTitle); + $but.bind('click', close); + $el.append($but); + $c.append($el); + } + return $c; + } + function updateDate() { + if (settings.showTime) { + $('#time-line').text(lastSelected.format(settings.dateFormat)); + } + updateMainElem(); + elem.next().val(selectDate.format(settings.dateFormat)); + if (!settings.showTime) { + $content.remove(); + $win.remove(); + } + } + + function updateMainElem() { + var arrF = settings.dateFormat.split(' '); + if (settings.showTime && arrF.length != 2) { + arrF.length = 2; + arrF[0] = 'DD/MM/YY'; + arrF[1] = 'HH:mm'; + } + var $s = $(''); + $s.text(lastSelected.format(arrF[0])); + elem.empty(); + elem.append($s); + $s = $(''); + $s.addClass('fa fa-calendar ico-size'); + elem.append($s); + if (settings.showTime) { + $s = $(''); + $s.text(lastSelected.format(arrF[1])); + elem.append($s); + $s = $(''); + $s.addClass('fa fa-clock-o ico-size'); + elem.append($s); + } + } + + }); + + }); + + }; + + function copyDate(d) { + return moment(d.toDate()); + } + + function totalMonths(m) { + var r = m.format('YYYY') * 12 + parseInt(m.format('MM')); + return r; + } + +}(jQuery)); +// fa-caret-down \ No newline at end of file diff --git a/templates/admin/input_filter.html b/templates/admin/input_filter.html new file mode 100644 index 0000000..168713b --- /dev/null +++ b/templates/admin/input_filter.html @@ -0,0 +1,15 @@ + + +{% load i18n %} + +{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %} + + + + + + + \ No newline at end of file diff --git a/templates/admin/pg/paymentrequest/change_list.html b/templates/admin/pg/paymentrequest/change_list.html new file mode 100644 index 0000000..dab27a4 --- /dev/null +++ b/templates/admin/pg/paymentrequest/change_list.html @@ -0,0 +1,11 @@ +{% extends "admin/change_list.html" %} +{% load tags %} +{% block result_list %} + {{ block.super }} + + جمع کل: + + {{ totals.total_amount|default:"0"|amount_split_3digit }} + + +{% endblock %} \ No newline at end of file diff --git a/templates/pg/payment-confirm.html b/templates/pg/payment_confirm.html similarity index 100% rename from templates/pg/payment-confirm.html rename to templates/pg/payment_confirm.html diff --git a/templates/pg/payment_failure.html b/templates/pg/payment_failure.html new file mode 100644 index 0000000..1559144 --- /dev/null +++ b/templates/pg/payment_failure.html @@ -0,0 +1,168 @@ +{% load static %} +{% load crispy_forms_tags %} +{% load jalali_tags %} + + + + + + + + Payment Unsuccessful + + + + + + + + + + + + + + + {% if message %} + {{ message }} + {% else %} + پرداخت ناموفق + {% endif %} + + + کد پیگیری تراکنش شما: {{ object.reference_number }} + در صورت کسر از موجودی، مبلغ پرداختی طی یک تا 72 ساعت آینده به حساب شما بازگردانده خواهد شد. + + winsoo + + + + + {% csrf_token %} + {{ form|crispy }} + بازگشت به صفحه اصلی + + + + + + + \ No newline at end of file diff --git a/templates/pg/payment-request.html b/templates/pg/payment_request.html similarity index 100% rename from templates/pg/payment-request.html rename to templates/pg/payment_request.html diff --git a/templates/pg/payment_success.html b/templates/pg/payment_success.html new file mode 100644 index 0000000..e0e9d75 --- /dev/null +++ b/templates/pg/payment_success.html @@ -0,0 +1,162 @@ +{% load static %} +{% load crispy_forms_tags %} +{% load jalali_tags %} + + + + + + + Payment Successful + + + + + + + + + + + + + + + پرداخت موفق + + + مبلغ شارژ + {{ object.amount }} ریال + + winsoo + + + + + {% csrf_token %} + {{ form|crispy }} + بازگشت به وینسو + + + + + + + + \ No newline at end of file diff --git a/gooyal_wallet_client/__init__.py b/utils/clients/gooyal_wallet_client/__init__.py similarity index 100% rename from gooyal_wallet_client/__init__.py rename to utils/clients/gooyal_wallet_client/__init__.py diff --git a/gooyal_wallet_client/api/__init__.py b/utils/clients/gooyal_wallet_client/api/__init__.py similarity index 100% rename from gooyal_wallet_client/api/__init__.py rename to utils/clients/gooyal_wallet_client/api/__init__.py diff --git a/utils/clients/gooyal_wallet_client/api/wallet/__init__.py b/utils/clients/gooyal_wallet_client/api/wallet/__init__.py new file mode 100644 index 0000000..2d7c0b2 --- /dev/null +++ b/utils/clients/gooyal_wallet_client/api/wallet/__init__.py @@ -0,0 +1 @@ +"""Contains endpoint functions for accessing the API""" diff --git a/gooyal_wallet_client/api/wallet/wallet_api_application_deposit_create.py b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_deposit_create.py similarity index 88% rename from gooyal_wallet_client/api/wallet/wallet_api_application_deposit_create.py rename to utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_deposit_create.py index 0612c2d..c4f8fa1 100644 --- a/gooyal_wallet_client/api/wallet/wallet_api_application_deposit_create.py +++ b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_deposit_create.py @@ -10,6 +10,7 @@ from ...types import Response def _get_kwargs( + payer_wallet: str, *, body: ApplicationDeposit, ) -> dict[str, Any]: @@ -17,12 +18,11 @@ def _get_kwargs( _kwargs: dict[str, Any] = { "method": "post", - "url": "/wallet/api/application/deposit/", + "url": f"/wallet/api/application/{payer_wallet}/deposit/", } - _body = body.to_dict() + _kwargs["json"] = body.to_dict() - _kwargs["json"] = _body headers["Content-Type"] = "application/json" _kwargs["headers"] = headers @@ -36,6 +36,7 @@ def _parse_response( response_201 = ApplicationDeposit.from_dict(response.json()) return response_201 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -54,12 +55,14 @@ def _build_response( def sync_detailed( + payer_wallet: str, *, client: AuthenticatedClient, body: ApplicationDeposit, ) -> Response[ApplicationDeposit]: """ Args: + payer_wallet (str): body (ApplicationDeposit): Raises: @@ -71,6 +74,7 @@ def sync_detailed( """ kwargs = _get_kwargs( + payer_wallet=payer_wallet, body=body, ) @@ -82,12 +86,14 @@ def sync_detailed( def sync( + payer_wallet: str, *, client: AuthenticatedClient, body: ApplicationDeposit, ) -> Optional[ApplicationDeposit]: """ Args: + payer_wallet (str): body (ApplicationDeposit): Raises: @@ -99,18 +105,21 @@ def sync( """ return sync_detailed( + payer_wallet=payer_wallet, client=client, body=body, ).parsed async def asyncio_detailed( + payer_wallet: str, *, client: AuthenticatedClient, body: ApplicationDeposit, ) -> Response[ApplicationDeposit]: """ Args: + payer_wallet (str): body (ApplicationDeposit): Raises: @@ -122,6 +131,7 @@ async def asyncio_detailed( """ kwargs = _get_kwargs( + payer_wallet=payer_wallet, body=body, ) @@ -131,12 +141,14 @@ async def asyncio_detailed( async def asyncio( + payer_wallet: str, *, client: AuthenticatedClient, body: ApplicationDeposit, ) -> Optional[ApplicationDeposit]: """ Args: + payer_wallet (str): body (ApplicationDeposit): Raises: @@ -149,6 +161,7 @@ async def asyncio( return ( await asyncio_detailed( + payer_wallet=payer_wallet, client=client, body=body, ) diff --git a/gooyal_wallet_client/api/wallet/wallet_api_application_deposit_verify_retrieve.py b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_deposit_verify_retrieve.py similarity index 88% rename from gooyal_wallet_client/api/wallet/wallet_api_application_deposit_verify_retrieve.py rename to utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_deposit_verify_retrieve.py index e5b7c34..29042f3 100644 --- a/gooyal_wallet_client/api/wallet/wallet_api_application_deposit_verify_retrieve.py +++ b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_deposit_verify_retrieve.py @@ -10,11 +10,12 @@ from ...types import Response def _get_kwargs( + payer_wallet: str, uuid: str, ) -> dict[str, Any]: _kwargs: dict[str, Any] = { "method": "get", - "url": f"/wallet/api/application/deposit/{uuid}/verify", + "url": f"/wallet/api/application/{payer_wallet}/deposit/{uuid}/verify", } return _kwargs @@ -27,6 +28,7 @@ def _parse_response( response_200 = ApplicationDeposit.from_dict(response.json()) return response_200 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -45,12 +47,14 @@ def _build_response( def sync_detailed( + payer_wallet: str, uuid: str, *, client: AuthenticatedClient, ) -> Response[ApplicationDeposit]: """ Args: + payer_wallet (str): uuid (str): Raises: @@ -62,6 +66,7 @@ def sync_detailed( """ kwargs = _get_kwargs( + payer_wallet=payer_wallet, uuid=uuid, ) @@ -73,12 +78,14 @@ def sync_detailed( def sync( + payer_wallet: str, uuid: str, *, client: AuthenticatedClient, ) -> Optional[ApplicationDeposit]: """ Args: + payer_wallet (str): uuid (str): Raises: @@ -90,18 +97,21 @@ def sync( """ return sync_detailed( + payer_wallet=payer_wallet, uuid=uuid, client=client, ).parsed async def asyncio_detailed( + payer_wallet: str, uuid: str, *, client: AuthenticatedClient, ) -> Response[ApplicationDeposit]: """ Args: + payer_wallet (str): uuid (str): Raises: @@ -113,6 +123,7 @@ async def asyncio_detailed( """ kwargs = _get_kwargs( + payer_wallet=payer_wallet, uuid=uuid, ) @@ -122,12 +133,14 @@ async def asyncio_detailed( async def asyncio( + payer_wallet: str, uuid: str, *, client: AuthenticatedClient, ) -> Optional[ApplicationDeposit]: """ Args: + payer_wallet (str): uuid (str): Raises: @@ -140,6 +153,7 @@ async def asyncio( return ( await asyncio_detailed( + payer_wallet=payer_wallet, uuid=uuid, client=client, ) diff --git a/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_transactions_list.py b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_transactions_list.py new file mode 100644 index 0000000..e808f0e --- /dev/null +++ b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_transactions_list.py @@ -0,0 +1,227 @@ +from http import HTTPStatus +from typing import Any, Optional, Union +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.paginated_transaction_list import PaginatedTransactionList +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + payee: Union[Unset, UUID] = UNSET, + payer: Union[Unset, UUID] = UNSET, + wallets: list[UUID], +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["limit"] = limit + + params["offset"] = offset + + json_payee: Union[Unset, str] = UNSET + if not isinstance(payee, Unset): + json_payee = str(payee) + params["payee"] = json_payee + + json_payer: Union[Unset, str] = UNSET + if not isinstance(payer, Unset): + json_payer = str(payer) + params["payer"] = json_payer + + json_wallets = [] + for wallets_item_data in wallets: + wallets_item = str(wallets_item_data) + json_wallets.append(wallets_item) + + params["wallets"] = json_wallets + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/wallet/api/application/transactions/", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[PaginatedTransactionList]: + if response.status_code == 200: + response_200 = PaginatedTransactionList.from_dict(response.json()) + + return response_200 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[PaginatedTransactionList]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + payee: Union[Unset, UUID] = UNSET, + payer: Union[Unset, UUID] = UNSET, + wallets: list[UUID], +) -> Response[PaginatedTransactionList]: + """ + Args: + limit (Union[Unset, int]): + offset (Union[Unset, int]): + payee (Union[Unset, UUID]): + payer (Union[Unset, UUID]): + wallets (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[PaginatedTransactionList] + """ + + kwargs = _get_kwargs( + limit=limit, + offset=offset, + payee=payee, + payer=payer, + wallets=wallets, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + payee: Union[Unset, UUID] = UNSET, + payer: Union[Unset, UUID] = UNSET, + wallets: list[UUID], +) -> Optional[PaginatedTransactionList]: + """ + Args: + limit (Union[Unset, int]): + offset (Union[Unset, int]): + payee (Union[Unset, UUID]): + payer (Union[Unset, UUID]): + wallets (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + PaginatedTransactionList + """ + + return sync_detailed( + client=client, + limit=limit, + offset=offset, + payee=payee, + payer=payer, + wallets=wallets, + ).parsed + + +async def asyncio_detailed( + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + payee: Union[Unset, UUID] = UNSET, + payer: Union[Unset, UUID] = UNSET, + wallets: list[UUID], +) -> Response[PaginatedTransactionList]: + """ + Args: + limit (Union[Unset, int]): + offset (Union[Unset, int]): + payee (Union[Unset, UUID]): + payer (Union[Unset, UUID]): + wallets (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[PaginatedTransactionList] + """ + + kwargs = _get_kwargs( + limit=limit, + offset=offset, + payee=payee, + payer=payer, + wallets=wallets, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + payee: Union[Unset, UUID] = UNSET, + payer: Union[Unset, UUID] = UNSET, + wallets: list[UUID], +) -> Optional[PaginatedTransactionList]: + """ + Args: + limit (Union[Unset, int]): + offset (Union[Unset, int]): + payee (Union[Unset, UUID]): + payer (Union[Unset, UUID]): + wallets (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + PaginatedTransactionList + """ + + return ( + await asyncio_detailed( + client=client, + limit=limit, + offset=offset, + payee=payee, + payer=payer, + wallets=wallets, + ) + ).parsed diff --git a/gooyal_wallet_client/api/wallet/wallet_api_application_retrieve.py b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_transactions_retrieve.py similarity index 74% rename from gooyal_wallet_client/api/wallet/wallet_api_application_retrieve.py rename to utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_transactions_retrieve.py index bbb4146..1939f25 100644 --- a/gooyal_wallet_client/api/wallet/wallet_api_application_retrieve.py +++ b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_transactions_retrieve.py @@ -1,41 +1,39 @@ from http import HTTPStatus from typing import Any, Optional, Union +from uuid import UUID import httpx from ... import errors from ...client import AuthenticatedClient, Client -from ...models.application_transaction import ApplicationTransaction +from ...models.transaction import Transaction from ...types import Response def _get_kwargs( - uuid: str, + uuid: UUID, ) -> dict[str, Any]: _kwargs: dict[str, Any] = { "method": "get", - "url": f"/wallet/api/application/{uuid}/", + "url": f"/wallet/api/application/transactions/{uuid}/", } return _kwargs -def _parse_response( - *, client: Union[AuthenticatedClient, Client], response: httpx.Response -) -> Optional[ApplicationTransaction]: +def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Transaction]: if response.status_code == 200: - response_200 = ApplicationTransaction.from_dict(response.json()) + response_200 = Transaction.from_dict(response.json()) return response_200 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: return None -def _build_response( - *, client: Union[AuthenticatedClient, Client], response: httpx.Response -) -> Response[ApplicationTransaction]: +def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Transaction]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -45,20 +43,20 @@ def _build_response( def sync_detailed( - uuid: str, + uuid: UUID, *, client: AuthenticatedClient, -) -> Response[ApplicationTransaction]: +) -> Response[Transaction]: """ Args: - uuid (str): + uuid (UUID): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ApplicationTransaction] + Response[Transaction] """ kwargs = _get_kwargs( @@ -73,20 +71,20 @@ def sync_detailed( def sync( - uuid: str, + uuid: UUID, *, client: AuthenticatedClient, -) -> Optional[ApplicationTransaction]: +) -> Optional[Transaction]: """ Args: - uuid (str): + uuid (UUID): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ApplicationTransaction + Transaction """ return sync_detailed( @@ -96,20 +94,20 @@ def sync( async def asyncio_detailed( - uuid: str, + uuid: UUID, *, client: AuthenticatedClient, -) -> Response[ApplicationTransaction]: +) -> Response[Transaction]: """ Args: - uuid (str): + uuid (UUID): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ApplicationTransaction] + Response[Transaction] """ kwargs = _get_kwargs( @@ -122,20 +120,20 @@ async def asyncio_detailed( async def asyncio( - uuid: str, + uuid: UUID, *, client: AuthenticatedClient, -) -> Optional[ApplicationTransaction]: +) -> Optional[Transaction]: """ Args: - uuid (str): + uuid (UUID): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ApplicationTransaction + Transaction """ return ( diff --git a/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_user_wallets_list.py b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_user_wallets_list.py new file mode 100644 index 0000000..3317b1e --- /dev/null +++ b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_user_wallets_list.py @@ -0,0 +1,208 @@ +from http import HTTPStatus +from typing import Any, Optional, Union +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.paginated_account_list import PaginatedAccountList +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + owner: str, + *, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + wallet: list[UUID], +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["limit"] = limit + + params["offset"] = offset + + json_wallet = [] + for wallet_item_data in wallet: + wallet_item = str(wallet_item_data) + json_wallet.append(wallet_item) + + params["wallet"] = json_wallet + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: dict[str, Any] = { + "method": "get", + "url": f"/wallet/api/application/user/wallets/{owner}/", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[PaginatedAccountList]: + if response.status_code == 200: + response_200 = PaginatedAccountList.from_dict(response.json()) + + return response_200 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[PaginatedAccountList]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + owner: str, + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + wallet: list[UUID], +) -> Response[PaginatedAccountList]: + """API for getting specified user wallet. + + Args: + owner (str): + limit (Union[Unset, int]): + offset (Union[Unset, int]): + wallet (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[PaginatedAccountList] + """ + + kwargs = _get_kwargs( + owner=owner, + limit=limit, + offset=offset, + wallet=wallet, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + owner: str, + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + wallet: list[UUID], +) -> Optional[PaginatedAccountList]: + """API for getting specified user wallet. + + Args: + owner (str): + limit (Union[Unset, int]): + offset (Union[Unset, int]): + wallet (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + PaginatedAccountList + """ + + return sync_detailed( + owner=owner, + client=client, + limit=limit, + offset=offset, + wallet=wallet, + ).parsed + + +async def asyncio_detailed( + owner: str, + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + wallet: list[UUID], +) -> Response[PaginatedAccountList]: + """API for getting specified user wallet. + + Args: + owner (str): + limit (Union[Unset, int]): + offset (Union[Unset, int]): + wallet (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[PaginatedAccountList] + """ + + kwargs = _get_kwargs( + owner=owner, + limit=limit, + offset=offset, + wallet=wallet, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + owner: str, + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + wallet: list[UUID], +) -> Optional[PaginatedAccountList]: + """API for getting specified user wallet. + + Args: + owner (str): + limit (Union[Unset, int]): + offset (Union[Unset, int]): + wallet (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + PaginatedAccountList + """ + + return ( + await asyncio_detailed( + owner=owner, + client=client, + limit=limit, + offset=offset, + wallet=wallet, + ) + ).parsed diff --git a/gooyal_wallet_client/api/wallet/wallet_api_application_list.py b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_wallets_list.py similarity index 62% rename from gooyal_wallet_client/api/wallet/wallet_api_application_list.py rename to utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_wallets_list.py index 8c65444..9d5a57b 100644 --- a/gooyal_wallet_client/api/wallet/wallet_api_application_list.py +++ b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_wallets_list.py @@ -5,23 +5,26 @@ import httpx from ... import errors from ...client import AuthenticatedClient, Client -from ...models.paginated_application_transaction_list import PaginatedApplicationTransactionList +from ...models.paginated_account_list import PaginatedAccountList from ...types import UNSET, Response, Unset def _get_kwargs( *, - page: Union[Unset, int] = UNSET, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, ) -> dict[str, Any]: params: dict[str, Any] = {} - params["page"] = page + params["limit"] = limit + + params["offset"] = offset params = {k: v for k, v in params.items() if v is not UNSET and v is not None} _kwargs: dict[str, Any] = { "method": "get", - "url": "/wallet/api/application/", + "url": "/wallet/api/application/wallets/", "params": params, } @@ -30,11 +33,12 @@ def _get_kwargs( def _parse_response( *, client: Union[AuthenticatedClient, Client], response: httpx.Response -) -> Optional[PaginatedApplicationTransactionList]: +) -> Optional[PaginatedAccountList]: if response.status_code == 200: - response_200 = PaginatedApplicationTransactionList.from_dict(response.json()) + response_200 = PaginatedAccountList.from_dict(response.json()) return response_200 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -43,7 +47,7 @@ def _parse_response( def _build_response( *, client: Union[AuthenticatedClient, Client], response: httpx.Response -) -> Response[PaginatedApplicationTransactionList]: +) -> Response[PaginatedAccountList]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -55,22 +59,26 @@ def _build_response( def sync_detailed( *, client: AuthenticatedClient, - page: Union[Unset, int] = UNSET, -) -> Response[PaginatedApplicationTransactionList]: - """ + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, +) -> Response[PaginatedAccountList]: + """API for getting specified user or application balance. + Args: - page (Union[Unset, int]): + limit (Union[Unset, int]): + offset (Union[Unset, int]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[PaginatedApplicationTransactionList] + Response[PaginatedAccountList] """ kwargs = _get_kwargs( - page=page, + limit=limit, + offset=offset, ) response = client.get_httpx_client().request( @@ -83,45 +91,53 @@ def sync_detailed( def sync( *, client: AuthenticatedClient, - page: Union[Unset, int] = UNSET, -) -> Optional[PaginatedApplicationTransactionList]: - """ + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, +) -> Optional[PaginatedAccountList]: + """API for getting specified user or application balance. + Args: - page (Union[Unset, int]): + limit (Union[Unset, int]): + offset (Union[Unset, int]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - PaginatedApplicationTransactionList + PaginatedAccountList """ return sync_detailed( client=client, - page=page, + limit=limit, + offset=offset, ).parsed async def asyncio_detailed( *, client: AuthenticatedClient, - page: Union[Unset, int] = UNSET, -) -> Response[PaginatedApplicationTransactionList]: - """ + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, +) -> Response[PaginatedAccountList]: + """API for getting specified user or application balance. + Args: - page (Union[Unset, int]): + limit (Union[Unset, int]): + offset (Union[Unset, int]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[PaginatedApplicationTransactionList] + Response[PaginatedAccountList] """ kwargs = _get_kwargs( - page=page, + limit=limit, + offset=offset, ) response = await client.get_async_httpx_client().request(**kwargs) @@ -132,23 +148,27 @@ async def asyncio_detailed( async def asyncio( *, client: AuthenticatedClient, - page: Union[Unset, int] = UNSET, -) -> Optional[PaginatedApplicationTransactionList]: - """ + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, +) -> Optional[PaginatedAccountList]: + """API for getting specified user or application balance. + Args: - page (Union[Unset, int]): + limit (Union[Unset, int]): + offset (Union[Unset, int]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - PaginatedApplicationTransactionList + PaginatedAccountList """ return ( await asyncio_detailed( client=client, - page=page, + limit=limit, + offset=offset, ) ).parsed diff --git a/gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_create.py b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_create.py similarity index 88% rename from gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_create.py rename to utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_create.py index 731ae3c..74d6944 100644 --- a/gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_create.py +++ b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_create.py @@ -10,6 +10,7 @@ from ...types import Response def _get_kwargs( + payee_wallet: str, *, body: ApplicationWithdraw, ) -> dict[str, Any]: @@ -17,12 +18,11 @@ def _get_kwargs( _kwargs: dict[str, Any] = { "method": "post", - "url": "/wallet/api/application/withdraw/", + "url": f"/wallet/api/application/{payee_wallet}/withdraw/", } - _body = body.to_dict() + _kwargs["json"] = body.to_dict() - _kwargs["json"] = _body headers["Content-Type"] = "application/json" _kwargs["headers"] = headers @@ -36,6 +36,7 @@ def _parse_response( response_201 = ApplicationWithdraw.from_dict(response.json()) return response_201 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -54,12 +55,14 @@ def _build_response( def sync_detailed( + payee_wallet: str, *, client: AuthenticatedClient, body: ApplicationWithdraw, ) -> Response[ApplicationWithdraw]: """ Args: + payee_wallet (str): body (ApplicationWithdraw): Raises: @@ -71,6 +74,7 @@ def sync_detailed( """ kwargs = _get_kwargs( + payee_wallet=payee_wallet, body=body, ) @@ -82,12 +86,14 @@ def sync_detailed( def sync( + payee_wallet: str, *, client: AuthenticatedClient, body: ApplicationWithdraw, ) -> Optional[ApplicationWithdraw]: """ Args: + payee_wallet (str): body (ApplicationWithdraw): Raises: @@ -99,18 +105,21 @@ def sync( """ return sync_detailed( + payee_wallet=payee_wallet, client=client, body=body, ).parsed async def asyncio_detailed( + payee_wallet: str, *, client: AuthenticatedClient, body: ApplicationWithdraw, ) -> Response[ApplicationWithdraw]: """ Args: + payee_wallet (str): body (ApplicationWithdraw): Raises: @@ -122,6 +131,7 @@ async def asyncio_detailed( """ kwargs = _get_kwargs( + payee_wallet=payee_wallet, body=body, ) @@ -131,12 +141,14 @@ async def asyncio_detailed( async def asyncio( + payee_wallet: str, *, client: AuthenticatedClient, body: ApplicationWithdraw, ) -> Optional[ApplicationWithdraw]: """ Args: + payee_wallet (str): body (ApplicationWithdraw): Raises: @@ -149,6 +161,7 @@ async def asyncio( return ( await asyncio_detailed( + payee_wallet=payee_wallet, client=client, body=body, ) diff --git a/gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_verify_retrieve.py b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_verify_retrieve.py similarity index 88% rename from gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_verify_retrieve.py rename to utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_verify_retrieve.py index 0e0d0db..757b597 100644 --- a/gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_verify_retrieve.py +++ b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_application_withdraw_verify_retrieve.py @@ -10,11 +10,12 @@ from ...types import Response def _get_kwargs( + payee_wallet: str, uuid: str, ) -> dict[str, Any]: _kwargs: dict[str, Any] = { "method": "get", - "url": f"/wallet/api/application/withdraw/{uuid}/verify", + "url": f"/wallet/api/application/{payee_wallet}/withdraw/{uuid}/verify", } return _kwargs @@ -27,6 +28,7 @@ def _parse_response( response_200 = ApplicationWithdraw.from_dict(response.json()) return response_200 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -45,12 +47,14 @@ def _build_response( def sync_detailed( + payee_wallet: str, uuid: str, *, client: AuthenticatedClient, ) -> Response[ApplicationWithdraw]: """ Args: + payee_wallet (str): uuid (str): Raises: @@ -62,6 +66,7 @@ def sync_detailed( """ kwargs = _get_kwargs( + payee_wallet=payee_wallet, uuid=uuid, ) @@ -73,12 +78,14 @@ def sync_detailed( def sync( + payee_wallet: str, uuid: str, *, client: AuthenticatedClient, ) -> Optional[ApplicationWithdraw]: """ Args: + payee_wallet (str): uuid (str): Raises: @@ -90,18 +97,21 @@ def sync( """ return sync_detailed( + payee_wallet=payee_wallet, uuid=uuid, client=client, ).parsed async def asyncio_detailed( + payee_wallet: str, uuid: str, *, client: AuthenticatedClient, ) -> Response[ApplicationWithdraw]: """ Args: + payee_wallet (str): uuid (str): Raises: @@ -113,6 +123,7 @@ async def asyncio_detailed( """ kwargs = _get_kwargs( + payee_wallet=payee_wallet, uuid=uuid, ) @@ -122,12 +133,14 @@ async def asyncio_detailed( async def asyncio( + payee_wallet: str, uuid: str, *, client: AuthenticatedClient, ) -> Optional[ApplicationWithdraw]: """ Args: + payee_wallet (str): uuid (str): Raises: @@ -140,6 +153,7 @@ async def asyncio( return ( await asyncio_detailed( + payee_wallet=payee_wallet, uuid=uuid, client=client, ) diff --git a/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_transactions_list.py b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_transactions_list.py new file mode 100644 index 0000000..328df18 --- /dev/null +++ b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_transactions_list.py @@ -0,0 +1,247 @@ +from http import HTTPStatus +from typing import Any, Optional, Union +from uuid import UUID + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.paginated_transaction_list import PaginatedTransactionList +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + payee: Union[Unset, UUID] = UNSET, + payer: Union[Unset, UUID] = UNSET, + wallets: list[UUID], +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["limit"] = limit + + params["offset"] = offset + + json_payee: Union[Unset, str] = UNSET + if not isinstance(payee, Unset): + json_payee = str(payee) + params["payee"] = json_payee + + json_payer: Union[Unset, str] = UNSET + if not isinstance(payer, Unset): + json_payer = str(payer) + params["payer"] = json_payer + + json_wallets = [] + for wallets_item_data in wallets: + wallets_item = str(wallets_item_data) + json_wallets.append(wallets_item) + + params["wallets"] = json_wallets + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/wallet/api/transactions/", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[PaginatedTransactionList]: + if response.status_code == 200: + response_200 = PaginatedTransactionList.from_dict(response.json()) + + return response_200 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[PaginatedTransactionList]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + payee: Union[Unset, UUID] = UNSET, + payer: Union[Unset, UUID] = UNSET, + wallets: list[UUID], +) -> Response[PaginatedTransactionList]: + """GET: API for getting list of transactions for authenticated user + POST: API for creating transaction for transferring funds from authenticated user to application + owner. (deprecated) + args: + - user: authenticated user + + Args: + limit (Union[Unset, int]): + offset (Union[Unset, int]): + payee (Union[Unset, UUID]): + payer (Union[Unset, UUID]): + wallets (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[PaginatedTransactionList] + """ + + kwargs = _get_kwargs( + limit=limit, + offset=offset, + payee=payee, + payer=payer, + wallets=wallets, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + payee: Union[Unset, UUID] = UNSET, + payer: Union[Unset, UUID] = UNSET, + wallets: list[UUID], +) -> Optional[PaginatedTransactionList]: + """GET: API for getting list of transactions for authenticated user + POST: API for creating transaction for transferring funds from authenticated user to application + owner. (deprecated) + args: + - user: authenticated user + + Args: + limit (Union[Unset, int]): + offset (Union[Unset, int]): + payee (Union[Unset, UUID]): + payer (Union[Unset, UUID]): + wallets (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + PaginatedTransactionList + """ + + return sync_detailed( + client=client, + limit=limit, + offset=offset, + payee=payee, + payer=payer, + wallets=wallets, + ).parsed + + +async def asyncio_detailed( + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + payee: Union[Unset, UUID] = UNSET, + payer: Union[Unset, UUID] = UNSET, + wallets: list[UUID], +) -> Response[PaginatedTransactionList]: + """GET: API for getting list of transactions for authenticated user + POST: API for creating transaction for transferring funds from authenticated user to application + owner. (deprecated) + args: + - user: authenticated user + + Args: + limit (Union[Unset, int]): + offset (Union[Unset, int]): + payee (Union[Unset, UUID]): + payer (Union[Unset, UUID]): + wallets (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[PaginatedTransactionList] + """ + + kwargs = _get_kwargs( + limit=limit, + offset=offset, + payee=payee, + payer=payer, + wallets=wallets, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: AuthenticatedClient, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + payee: Union[Unset, UUID] = UNSET, + payer: Union[Unset, UUID] = UNSET, + wallets: list[UUID], +) -> Optional[PaginatedTransactionList]: + """GET: API for getting list of transactions for authenticated user + POST: API for creating transaction for transferring funds from authenticated user to application + owner. (deprecated) + args: + - user: authenticated user + + Args: + limit (Union[Unset, int]): + offset (Union[Unset, int]): + payee (Union[Unset, UUID]): + payer (Union[Unset, UUID]): + wallets (list[UUID]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + PaginatedTransactionList + """ + + return ( + await asyncio_detailed( + client=client, + limit=limit, + offset=offset, + payee=payee, + payer=payer, + wallets=wallets, + ) + ).parsed diff --git a/gooyal_wallet_client/api/wallet/wallet_api_transactions_list.py b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_wallets_list.py similarity index 56% rename from gooyal_wallet_client/api/wallet/wallet_api_transactions_list.py rename to utils/clients/gooyal_wallet_client/api/wallet/wallet_api_wallets_list.py index 4009fe1..f406ae8 100644 --- a/gooyal_wallet_client/api/wallet/wallet_api_transactions_list.py +++ b/utils/clients/gooyal_wallet_client/api/wallet/wallet_api_wallets_list.py @@ -1,27 +1,39 @@ from http import HTTPStatus from typing import Any, Optional, Union +from uuid import UUID import httpx from ... import errors from ...client import AuthenticatedClient, Client -from ...models.paginated_user_transaction_list import PaginatedUserTransactionList +from ...models.paginated_account_list import PaginatedAccountList from ...types import UNSET, Response, Unset def _get_kwargs( *, - page: Union[Unset, int] = UNSET, + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + wallet: list[UUID], ) -> dict[str, Any]: params: dict[str, Any] = {} - params["page"] = page + params["limit"] = limit + + params["offset"] = offset + + json_wallet = [] + for wallet_item_data in wallet: + wallet_item = str(wallet_item_data) + json_wallet.append(wallet_item) + + params["wallet"] = json_wallet params = {k: v for k, v in params.items() if v is not UNSET and v is not None} _kwargs: dict[str, Any] = { "method": "get", - "url": "/wallet/api/transactions/", + "url": "/wallet/api/wallets/", "params": params, } @@ -30,11 +42,12 @@ def _get_kwargs( def _parse_response( *, client: Union[AuthenticatedClient, Client], response: httpx.Response -) -> Optional[PaginatedUserTransactionList]: +) -> Optional[PaginatedAccountList]: if response.status_code == 200: - response_200 = PaginatedUserTransactionList.from_dict(response.json()) + response_200 = PaginatedAccountList.from_dict(response.json()) return response_200 + if client.raise_on_unexpected_status: raise errors.UnexpectedStatus(response.status_code, response.content) else: @@ -43,7 +56,7 @@ def _parse_response( def _build_response( *, client: Union[AuthenticatedClient, Client], response: httpx.Response -) -> Response[PaginatedUserTransactionList]: +) -> Response[PaginatedAccountList]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -55,27 +68,29 @@ def _build_response( def sync_detailed( *, client: AuthenticatedClient, - page: Union[Unset, int] = UNSET, -) -> Response[PaginatedUserTransactionList]: - """GET: API for getting list of transactions for authenticated user - POST: API for creating transaction for transferring funds from authenticated user to application - owner. (deprecated) - args: - - user: authenticated user + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + wallet: list[UUID], +) -> Response[PaginatedAccountList]: + """API for getting authenticated user balance. Args: - page (Union[Unset, int]): + limit (Union[Unset, int]): + offset (Union[Unset, int]): + wallet (list[UUID]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[PaginatedUserTransactionList] + Response[PaginatedAccountList] """ kwargs = _get_kwargs( - page=page, + limit=limit, + offset=offset, + wallet=wallet, ) response = client.get_httpx_client().request( @@ -88,55 +103,59 @@ def sync_detailed( def sync( *, client: AuthenticatedClient, - page: Union[Unset, int] = UNSET, -) -> Optional[PaginatedUserTransactionList]: - """GET: API for getting list of transactions for authenticated user - POST: API for creating transaction for transferring funds from authenticated user to application - owner. (deprecated) - args: - - user: authenticated user + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + wallet: list[UUID], +) -> Optional[PaginatedAccountList]: + """API for getting authenticated user balance. Args: - page (Union[Unset, int]): + limit (Union[Unset, int]): + offset (Union[Unset, int]): + wallet (list[UUID]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - PaginatedUserTransactionList + PaginatedAccountList """ return sync_detailed( client=client, - page=page, + limit=limit, + offset=offset, + wallet=wallet, ).parsed async def asyncio_detailed( *, client: AuthenticatedClient, - page: Union[Unset, int] = UNSET, -) -> Response[PaginatedUserTransactionList]: - """GET: API for getting list of transactions for authenticated user - POST: API for creating transaction for transferring funds from authenticated user to application - owner. (deprecated) - args: - - user: authenticated user + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + wallet: list[UUID], +) -> Response[PaginatedAccountList]: + """API for getting authenticated user balance. Args: - page (Union[Unset, int]): + limit (Union[Unset, int]): + offset (Union[Unset, int]): + wallet (list[UUID]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[PaginatedUserTransactionList] + Response[PaginatedAccountList] """ kwargs = _get_kwargs( - page=page, + limit=limit, + offset=offset, + wallet=wallet, ) response = await client.get_async_httpx_client().request(**kwargs) @@ -147,28 +166,30 @@ async def asyncio_detailed( async def asyncio( *, client: AuthenticatedClient, - page: Union[Unset, int] = UNSET, -) -> Optional[PaginatedUserTransactionList]: - """GET: API for getting list of transactions for authenticated user - POST: API for creating transaction for transferring funds from authenticated user to application - owner. (deprecated) - args: - - user: authenticated user + limit: Union[Unset, int] = UNSET, + offset: Union[Unset, int] = UNSET, + wallet: list[UUID], +) -> Optional[PaginatedAccountList]: + """API for getting authenticated user balance. Args: - page (Union[Unset, int]): + limit (Union[Unset, int]): + offset (Union[Unset, int]): + wallet (list[UUID]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - PaginatedUserTransactionList + PaginatedAccountList """ return ( await asyncio_detailed( client=client, - page=page, + limit=limit, + offset=offset, + wallet=wallet, ) ).parsed diff --git a/gooyal_wallet_client/client.py b/utils/clients/gooyal_wallet_client/client.py similarity index 100% rename from gooyal_wallet_client/client.py rename to utils/clients/gooyal_wallet_client/client.py diff --git a/gooyal_wallet_client/errors.py b/utils/clients/gooyal_wallet_client/errors.py similarity index 100% rename from gooyal_wallet_client/errors.py rename to utils/clients/gooyal_wallet_client/errors.py diff --git a/utils/clients/gooyal_wallet_client/models/__init__.py b/utils/clients/gooyal_wallet_client/models/__init__.py new file mode 100644 index 0000000..4d9841d --- /dev/null +++ b/utils/clients/gooyal_wallet_client/models/__init__.py @@ -0,0 +1,19 @@ +"""Contains all the data models used in inputs/outputs""" + +from .account import Account +from .application_deposit import ApplicationDeposit +from .application_withdraw import ApplicationWithdraw +from .paginated_account_list import PaginatedAccountList +from .paginated_transaction_list import PaginatedTransactionList +from .state_enum import StateEnum +from .transaction import Transaction + +__all__ = ( + "Account", + "ApplicationDeposit", + "ApplicationWithdraw", + "PaginatedAccountList", + "PaginatedTransactionList", + "StateEnum", + "Transaction", +) diff --git a/utils/clients/gooyal_wallet_client/models/account.py b/utils/clients/gooyal_wallet_client/models/account.py new file mode 100644 index 0000000..25b08bb --- /dev/null +++ b/utils/clients/gooyal_wallet_client/models/account.py @@ -0,0 +1,90 @@ +from collections.abc import Mapping +from typing import Any, TypeVar, Union, cast +from uuid import UUID + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="Account") + + +@_attrs_define +class Account: + """ + Attributes: + balance (Union[Unset, int]): + wallet (Union[None, UUID, Unset]): + """ + + balance: Union[Unset, int] = UNSET + wallet: Union[None, UUID, Unset] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + balance = self.balance + + wallet: Union[None, Unset, str] + if isinstance(self.wallet, Unset): + wallet = UNSET + elif isinstance(self.wallet, UUID): + wallet = str(self.wallet) + else: + wallet = self.wallet + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if balance is not UNSET: + field_dict["balance"] = balance + if wallet is not UNSET: + field_dict["wallet"] = wallet + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + balance = d.pop("balance", UNSET) + + def _parse_wallet(data: object) -> Union[None, UUID, Unset]: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + wallet_type_0 = UUID(data) + + return wallet_type_0 + except: # noqa: E722 + pass + return cast(Union[None, UUID, Unset], data) + + wallet = _parse_wallet(d.pop("wallet", UNSET)) + + account = cls( + balance=balance, + wallet=wallet, + ) + + account.additional_properties = d + return account + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/utils/clients/gooyal_wallet_client/models/application_deposit.py b/utils/clients/gooyal_wallet_client/models/application_deposit.py new file mode 100644 index 0000000..71fb885 --- /dev/null +++ b/utils/clients/gooyal_wallet_client/models/application_deposit.py @@ -0,0 +1,168 @@ +import datetime +from collections.abc import Mapping +from typing import Any, TypeVar, Union +from uuid import UUID + +from attrs import define as _attrs_define +from attrs import field as _attrs_field +from dateutil.parser import isoparse + +from ..models.state_enum import StateEnum +from ..types import UNSET, Unset + +T = TypeVar("T", bound="ApplicationDeposit") + + +@_attrs_define +class ApplicationDeposit: + """ + Attributes: + payer (str): + payer_type (str): + payer_wallet (UUID): + payee (UUID): + payee_type (int): + payee_wallet (UUID): + created_at (datetime.datetime): + state (StateEnum): * `1` - created + * `2` - delayed + * `3` - pending + * `4` - incomplete + * `5` - success + * `6` - failed + * `7` - expected_failure + amount (int): + updated_at (datetime.datetime): + uuid (Union[Unset, UUID]): + details (Union[Unset, Any]): + """ + + payer: str + payer_type: str + payer_wallet: UUID + payee: UUID + payee_type: int + payee_wallet: UUID + created_at: datetime.datetime + state: StateEnum + amount: int + updated_at: datetime.datetime + uuid: Union[Unset, UUID] = UNSET + details: Union[Unset, Any] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + payer = self.payer + + payer_type = self.payer_type + + payer_wallet = str(self.payer_wallet) + + payee = str(self.payee) + + payee_type = self.payee_type + + payee_wallet = str(self.payee_wallet) + + created_at = self.created_at.isoformat() + + state = self.state.value + + amount = self.amount + + updated_at = self.updated_at.isoformat() + + uuid: Union[Unset, str] = UNSET + if not isinstance(self.uuid, Unset): + uuid = str(self.uuid) + + details = self.details + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "payer": payer, + "payer_type": payer_type, + "payer_wallet": payer_wallet, + "payee": payee, + "payee_type": payee_type, + "payee_wallet": payee_wallet, + "created_at": created_at, + "state": state, + "amount": amount, + "updated_at": updated_at, + } + ) + if uuid is not UNSET: + field_dict["uuid"] = uuid + if details is not UNSET: + field_dict["details"] = details + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + payer = d.pop("payer") + + payer_type = d.pop("payer_type") + + payer_wallet = UUID(d.pop("payer_wallet")) + + payee = UUID(d.pop("payee")) + + payee_type = d.pop("payee_type") + + payee_wallet = UUID(d.pop("payee_wallet")) + + created_at = isoparse(d.pop("created_at")) + + state = StateEnum(d.pop("state")) + + amount = d.pop("amount") + + updated_at = isoparse(d.pop("updated_at")) + + _uuid = d.pop("uuid", UNSET) + uuid: Union[Unset, UUID] + if isinstance(_uuid, Unset): + uuid = UNSET + else: + uuid = UUID(_uuid) + + details = d.pop("details", UNSET) + + application_deposit = cls( + payer=payer, + payer_type=payer_type, + payer_wallet=payer_wallet, + payee=payee, + payee_type=payee_type, + payee_wallet=payee_wallet, + created_at=created_at, + state=state, + amount=amount, + updated_at=updated_at, + uuid=uuid, + details=details, + ) + + application_deposit.additional_properties = d + return application_deposit + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/utils/clients/gooyal_wallet_client/models/application_withdraw.py b/utils/clients/gooyal_wallet_client/models/application_withdraw.py new file mode 100644 index 0000000..3ddd5b4 --- /dev/null +++ b/utils/clients/gooyal_wallet_client/models/application_withdraw.py @@ -0,0 +1,168 @@ +import datetime +from collections.abc import Mapping +from typing import Any, TypeVar, Union +from uuid import UUID + +from attrs import define as _attrs_define +from attrs import field as _attrs_field +from dateutil.parser import isoparse + +from ..models.state_enum import StateEnum +from ..types import UNSET, Unset + +T = TypeVar("T", bound="ApplicationWithdraw") + + +@_attrs_define +class ApplicationWithdraw: + """ + Attributes: + payer (UUID): + payer_type (int): + payer_wallet (UUID): + payee (str): + payee_type (str): + payee_wallet (UUID): + created_at (datetime.datetime): + state (StateEnum): * `1` - created + * `2` - delayed + * `3` - pending + * `4` - incomplete + * `5` - success + * `6` - failed + * `7` - expected_failure + amount (int): + updated_at (datetime.datetime): + uuid (Union[Unset, UUID]): + details (Union[Unset, Any]): + """ + + payer: UUID + payer_type: int + payer_wallet: UUID + payee: str + payee_type: str + payee_wallet: UUID + created_at: datetime.datetime + state: StateEnum + amount: int + updated_at: datetime.datetime + uuid: Union[Unset, UUID] = UNSET + details: Union[Unset, Any] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + payer = str(self.payer) + + payer_type = self.payer_type + + payer_wallet = str(self.payer_wallet) + + payee = self.payee + + payee_type = self.payee_type + + payee_wallet = str(self.payee_wallet) + + created_at = self.created_at.isoformat() + + state = self.state.value + + amount = self.amount + + updated_at = self.updated_at.isoformat() + + uuid: Union[Unset, str] = UNSET + if not isinstance(self.uuid, Unset): + uuid = str(self.uuid) + + details = self.details + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "payer": payer, + "payer_type": payer_type, + "payer_wallet": payer_wallet, + "payee": payee, + "payee_type": payee_type, + "payee_wallet": payee_wallet, + "created_at": created_at, + "state": state, + "amount": amount, + "updated_at": updated_at, + } + ) + if uuid is not UNSET: + field_dict["uuid"] = uuid + if details is not UNSET: + field_dict["details"] = details + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + payer = UUID(d.pop("payer")) + + payer_type = d.pop("payer_type") + + payer_wallet = UUID(d.pop("payer_wallet")) + + payee = d.pop("payee") + + payee_type = d.pop("payee_type") + + payee_wallet = UUID(d.pop("payee_wallet")) + + created_at = isoparse(d.pop("created_at")) + + state = StateEnum(d.pop("state")) + + amount = d.pop("amount") + + updated_at = isoparse(d.pop("updated_at")) + + _uuid = d.pop("uuid", UNSET) + uuid: Union[Unset, UUID] + if isinstance(_uuid, Unset): + uuid = UNSET + else: + uuid = UUID(_uuid) + + details = d.pop("details", UNSET) + + application_withdraw = cls( + payer=payer, + payer_type=payer_type, + payer_wallet=payer_wallet, + payee=payee, + payee_type=payee_type, + payee_wallet=payee_wallet, + created_at=created_at, + state=state, + amount=amount, + updated_at=updated_at, + uuid=uuid, + details=details, + ) + + application_withdraw.additional_properties = d + return application_withdraw + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/gooyal_wallet_client/models/paginated_user_transaction_list.py b/utils/clients/gooyal_wallet_client/models/paginated_account_list.py similarity index 81% rename from gooyal_wallet_client/models/paginated_user_transaction_list.py rename to utils/clients/gooyal_wallet_client/models/paginated_account_list.py index 631893f..18aee85 100644 --- a/gooyal_wallet_client/models/paginated_user_transaction_list.py +++ b/utils/clients/gooyal_wallet_client/models/paginated_account_list.py @@ -1,3 +1,4 @@ +from collections.abc import Mapping from typing import TYPE_CHECKING, Any, TypeVar, Union, cast from attrs import define as _attrs_define @@ -6,24 +7,24 @@ from attrs import field as _attrs_field from ..types import UNSET, Unset if TYPE_CHECKING: - from ..models.user_transaction import UserTransaction + from ..models.account import Account -T = TypeVar("T", bound="PaginatedUserTransactionList") +T = TypeVar("T", bound="PaginatedAccountList") @_attrs_define -class PaginatedUserTransactionList: +class PaginatedAccountList: """ Attributes: count (int): Example: 123. - results (list['UserTransaction']): - next_ (Union[None, Unset, str]): Example: http://api.example.org/accounts/?page=4. - previous (Union[None, Unset, str]): Example: http://api.example.org/accounts/?page=2. + results (list['Account']): + next_ (Union[None, Unset, str]): Example: http://api.example.org/accounts/?offset=400&limit=100. + previous (Union[None, Unset, str]): Example: http://api.example.org/accounts/?offset=200&limit=100. """ count: int - results: list["UserTransaction"] + results: list["Account"] next_: Union[None, Unset, str] = UNSET previous: Union[None, Unset, str] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -64,16 +65,16 @@ class PaginatedUserTransactionList: return field_dict @classmethod - def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: - from ..models.user_transaction import UserTransaction + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.account import Account - d = src_dict.copy() + d = dict(src_dict) count = d.pop("count") results = [] _results = d.pop("results") for results_item_data in _results: - results_item = UserTransaction.from_dict(results_item_data) + results_item = Account.from_dict(results_item_data) results.append(results_item) @@ -95,15 +96,15 @@ class PaginatedUserTransactionList: previous = _parse_previous(d.pop("previous", UNSET)) - paginated_user_transaction_list = cls( + paginated_account_list = cls( count=count, results=results, next_=next_, previous=previous, ) - paginated_user_transaction_list.additional_properties = d - return paginated_user_transaction_list + paginated_account_list.additional_properties = d + return paginated_account_list @property def additional_keys(self) -> list[str]: diff --git a/gooyal_wallet_client/models/paginated_application_transaction_list.py b/utils/clients/gooyal_wallet_client/models/paginated_transaction_list.py similarity index 79% rename from gooyal_wallet_client/models/paginated_application_transaction_list.py rename to utils/clients/gooyal_wallet_client/models/paginated_transaction_list.py index 2854f85..71f2a07 100644 --- a/gooyal_wallet_client/models/paginated_application_transaction_list.py +++ b/utils/clients/gooyal_wallet_client/models/paginated_transaction_list.py @@ -1,3 +1,4 @@ +from collections.abc import Mapping from typing import TYPE_CHECKING, Any, TypeVar, Union, cast from attrs import define as _attrs_define @@ -6,24 +7,24 @@ from attrs import field as _attrs_field from ..types import UNSET, Unset if TYPE_CHECKING: - from ..models.application_transaction import ApplicationTransaction + from ..models.transaction import Transaction -T = TypeVar("T", bound="PaginatedApplicationTransactionList") +T = TypeVar("T", bound="PaginatedTransactionList") @_attrs_define -class PaginatedApplicationTransactionList: +class PaginatedTransactionList: """ Attributes: count (int): Example: 123. - results (list['ApplicationTransaction']): - next_ (Union[None, Unset, str]): Example: http://api.example.org/accounts/?page=4. - previous (Union[None, Unset, str]): Example: http://api.example.org/accounts/?page=2. + results (list['Transaction']): + next_ (Union[None, Unset, str]): Example: http://api.example.org/accounts/?offset=400&limit=100. + previous (Union[None, Unset, str]): Example: http://api.example.org/accounts/?offset=200&limit=100. """ count: int - results: list["ApplicationTransaction"] + results: list["Transaction"] next_: Union[None, Unset, str] = UNSET previous: Union[None, Unset, str] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -64,16 +65,16 @@ class PaginatedApplicationTransactionList: return field_dict @classmethod - def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: - from ..models.application_transaction import ApplicationTransaction + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.transaction import Transaction - d = src_dict.copy() + d = dict(src_dict) count = d.pop("count") results = [] _results = d.pop("results") for results_item_data in _results: - results_item = ApplicationTransaction.from_dict(results_item_data) + results_item = Transaction.from_dict(results_item_data) results.append(results_item) @@ -95,15 +96,15 @@ class PaginatedApplicationTransactionList: previous = _parse_previous(d.pop("previous", UNSET)) - paginated_application_transaction_list = cls( + paginated_transaction_list = cls( count=count, results=results, next_=next_, previous=previous, ) - paginated_application_transaction_list.additional_properties = d - return paginated_application_transaction_list + paginated_transaction_list.additional_properties = d + return paginated_transaction_list @property def additional_keys(self) -> list[str]: diff --git a/gooyal_wallet_client/models/state_enum.py b/utils/clients/gooyal_wallet_client/models/state_enum.py similarity index 100% rename from gooyal_wallet_client/models/state_enum.py rename to utils/clients/gooyal_wallet_client/models/state_enum.py diff --git a/utils/clients/gooyal_wallet_client/models/transaction.py b/utils/clients/gooyal_wallet_client/models/transaction.py new file mode 100644 index 0000000..96e122a --- /dev/null +++ b/utils/clients/gooyal_wallet_client/models/transaction.py @@ -0,0 +1,176 @@ +import datetime +from collections.abc import Mapping +from typing import Any, TypeVar, Union +from uuid import UUID + +from attrs import define as _attrs_define +from attrs import field as _attrs_field +from dateutil.parser import isoparse + +from ..models.state_enum import StateEnum +from ..types import UNSET, Unset + +T = TypeVar("T", bound="Transaction") + + +@_attrs_define +class Transaction: + """ + Attributes: + uuid (UUID): + payer (str): + payer_type (str): + payer_wallet (str): + payee (UUID): + payee_type (int): + payee_wallet (str): + created_at (datetime.datetime): + state (StateEnum): * `1` - created + * `2` - delayed + * `3` - pending + * `4` - incomplete + * `5` - success + * `6` - failed + * `7` - expected_failure + amount (int): + updated_at (datetime.datetime): + details (Any): + role (int): + delay (Union[Unset, int]): + """ + + uuid: UUID + payer: str + payer_type: str + payer_wallet: str + payee: UUID + payee_type: int + payee_wallet: str + created_at: datetime.datetime + state: StateEnum + amount: int + updated_at: datetime.datetime + details: Any + role: int + delay: Union[Unset, int] = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + uuid = str(self.uuid) + + payer = self.payer + + payer_type = self.payer_type + + payer_wallet = self.payer_wallet + + payee = str(self.payee) + + payee_type = self.payee_type + + payee_wallet = self.payee_wallet + + created_at = self.created_at.isoformat() + + state = self.state.value + + amount = self.amount + + updated_at = self.updated_at.isoformat() + + details = self.details + + role = self.role + + delay = self.delay + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "uuid": uuid, + "payer": payer, + "payer_type": payer_type, + "payer_wallet": payer_wallet, + "payee": payee, + "payee_type": payee_type, + "payee_wallet": payee_wallet, + "created_at": created_at, + "state": state, + "amount": amount, + "updated_at": updated_at, + "details": details, + "role": role, + } + ) + if delay is not UNSET: + field_dict["delay"] = delay + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + uuid = UUID(d.pop("uuid")) + + payer = d.pop("payer") + + payer_type = d.pop("payer_type") + + payer_wallet = d.pop("payer_wallet") + + payee = UUID(d.pop("payee")) + + payee_type = d.pop("payee_type") + + payee_wallet = d.pop("payee_wallet") + + created_at = isoparse(d.pop("created_at")) + + state = StateEnum(d.pop("state")) + + amount = d.pop("amount") + + updated_at = isoparse(d.pop("updated_at")) + + details = d.pop("details") + + role = d.pop("role") + + delay = d.pop("delay", UNSET) + + transaction = cls( + uuid=uuid, + payer=payer, + payer_type=payer_type, + payer_wallet=payer_wallet, + payee=payee, + payee_type=payee_type, + payee_wallet=payee_wallet, + created_at=created_at, + state=state, + amount=amount, + updated_at=updated_at, + details=details, + role=role, + delay=delay, + ) + + transaction.additional_properties = d + return transaction + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/gooyal_wallet_client/py.typed b/utils/clients/gooyal_wallet_client/py.typed similarity index 100% rename from gooyal_wallet_client/py.typed rename to utils/clients/gooyal_wallet_client/py.typed diff --git a/gooyal_wallet_client/types.py b/utils/clients/gooyal_wallet_client/types.py similarity index 52% rename from gooyal_wallet_client/types.py rename to utils/clients/gooyal_wallet_client/types.py index b9ed58b..1b96ca4 100644 --- a/gooyal_wallet_client/types.py +++ b/utils/clients/gooyal_wallet_client/types.py @@ -1,8 +1,8 @@ """Contains some shared types for properties""" -from collections.abc import MutableMapping +from collections.abc import Mapping, MutableMapping from http import HTTPStatus -from typing import BinaryIO, Generic, Literal, Optional, TypeVar +from typing import IO, BinaryIO, Generic, Literal, Optional, TypeVar, Union from attrs import define @@ -14,7 +14,15 @@ class Unset: UNSET: Unset = Unset() -FileJsonType = tuple[Optional[str], BinaryIO, Optional[str]] +# The types that `httpx.Client(files=)` can accept, copied from that library. +FileContent = Union[IO[bytes], bytes, str] +FileTypes = Union[ + # (filename, file (or bytes), content_type) + tuple[Optional[str], FileContent, Optional[str]], + # (filename, file (or bytes), content_type, headers) + tuple[Optional[str], FileContent, Optional[str], Mapping[str, str]], +] +RequestFiles = list[tuple[str, FileTypes]] @define @@ -25,7 +33,7 @@ class File: file_name: Optional[str] = None mime_type: Optional[str] = None - def to_tuple(self) -> FileJsonType: + def to_tuple(self) -> FileTypes: """Return a tuple representation that httpx will accept for multipart/form-data""" return self.file_name, self.payload, self.mime_type @@ -43,4 +51,4 @@ class Response(Generic[T]): parsed: Optional[T] -__all__ = ["UNSET", "File", "FileJsonType", "Response", "Unset"] +__all__ = ["UNSET", "File", "FileTypes", "RequestFiles", "Response", "Unset"] diff --git a/utils/wallet_client.py b/utils/clients/wallet_client.py similarity index 69% rename from utils/wallet_client.py rename to utils/clients/wallet_client.py index 0762eaa..49f6dcd 100644 --- a/utils/wallet_client.py +++ b/utils/clients/wallet_client.py @@ -6,13 +6,13 @@ from django.core.cache import cache from django.db import models from httpx import Request -from gooyal_wallet_client import AuthenticatedClient -from gooyal_wallet_client.models import MyWallet, UserTransaction, ApplicationDeposit, ApplicationWithdraw -from gooyal_wallet_client.api.wallet import (wallet_api_application_deposit_create, +from utils.clients.gooyal_wallet_client import AuthenticatedClient +from utils.clients.gooyal_wallet_client.models import Transaction, Account, ApplicationDeposit, ApplicationWithdraw +from utils.clients.gooyal_wallet_client.api.wallet import (wallet_api_application_deposit_create, wallet_api_application_deposit_verify_retrieve, wallet_api_application_withdraw_create, wallet_api_application_withdraw_verify_retrieve) -from gooyal_wallet_client.types import Response +from utils.clients.gooyal_wallet_client.types import Response from django.conf import Settings @@ -37,11 +37,11 @@ def login_as_client_credentials(): data = { "grant_type": 'client_credentials', - "scope": settings.SCOPES, + "scope": settings.OAUTH2_PROVIDER_SCOPES, } - auth = (settings.CLIENT_ID, settings.CLIENT_SECRET) + auth = (settings.OAUTH2_PROVIDER_CLIENT_ID, settings.OAUTH2_PROVIDER_CLIENT_SECRET) - response = requests.post(f'{settings.BASE_OAUTH2_PROVIDER_PUBLIC_URL}/token/', + response = requests.post(f'{settings.OAUTH2_PROVIDER_BASE_PUBLIC_URL}/token/', data=data, auth=auth) print(response.content) @@ -73,52 +73,41 @@ def get_client(): return client -def deposit_to_user_wallet_submit(data): +def deposit_to_user_wallet_submit(payer_wallet, data): class Tmp(): def to_dict(self): return data deposit_data = Tmp() client = get_client() - response: ApplicationDeposit = wallet_api_application_deposit_create.sync(client=client, body=deposit_data) + response: ApplicationDeposit = wallet_api_application_deposit_create.sync(payer_wallet=payer_wallet, + client=client, + body=deposit_data) print(response) - return response -def deposit_to_user_wallet_verify(uuid): +def deposit_to_user_wallet_verify(payer_wallet, uuid): client = get_client() - response: ApplicationDeposit = wallet_api_application_deposit_verify_retrieve.sync(uuid=uuid, client=client) + response: ApplicationDeposit = wallet_api_application_deposit_verify_retrieve.sync(payer_wallet=payer_wallet, uuid=uuid, client=client) print(response) - return response -def withdraw_from_user_wallet_submit(data): +def withdraw_from_user_wallet_submit(payee_wallet, data): class Tmp(): def to_dict(self): return data withdraw_data = Tmp() client = get_client() - response: ApplicationWithdraw = wallet_api_application_withdraw_create.sync(client=client, body=withdraw_data) + response: ApplicationWithdraw = wallet_api_application_withdraw_create.sync(payee_wallet=payee_wallet, client=client, body=withdraw_data) print(response) - return response -def withdraw_from_user_wallet_verify(uuid): +def withdraw_from_user_wallet_verify(payee_wallet, uuid): client = get_client() - response: ApplicationWithdraw = wallet_api_application_withdraw_verify_retrieve.sync(uuid=uuid, client=client) + response: ApplicationWithdraw = wallet_api_application_withdraw_verify_retrieve.sync(payee_wallet=payee_wallet, uuid=uuid, client=client) print(response) - return response - - -sample_data = { - "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afb1", - "payee_id": "5d66d02e-6087-4b0a-bb0c-291d5c11755a", - "payee_type": 1, - "amount": 2000, - "details": "string", -} diff --git a/utils/commons.py b/utils/commons.py new file mode 100644 index 0000000..f48babd --- /dev/null +++ b/utils/commons.py @@ -0,0 +1,9 @@ +from main import settings + +def calculate_pna_commission(amount: int) -> int: + commission = settings.COMMISSION_LEVEL1 + if settings.COMMISSION_LEVEL2_MIN_AMOUNT <= amount <= settings.COMMISSION_LEVEL2_MAX_AMOUNT: + commission = settings.COMMISSION_LEVEL2_RATE * amount + elif settings.COMMISSION_LEVEL2_MAX_AMOUNT < amount: + commission = settings.COMMISSION_LEVEL3 + return commission \ No newline at end of file diff --git a/utils/exceptions.py b/utils/exceptions.py new file mode 100644 index 0000000..1fb3b04 --- /dev/null +++ b/utils/exceptions.py @@ -0,0 +1,51 @@ +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): + logger.exception(exc) + # پاسخ پیشفرض 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 + ) \ No newline at end of file diff --git a/utils/i18n.py b/utils/i18n.py new file mode 100644 index 0000000..fe38f0d --- /dev/null +++ b/utils/i18n.py @@ -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) \ No newline at end of file diff --git a/utils/logs/__init__.py b/utils/logs/__init__.py new file mode 100644 index 0000000..5afab06 --- /dev/null +++ b/utils/logs/__init__.py @@ -0,0 +1,4 @@ +from .formatters import LokiFormatter +from .handlers import LokiHandler + +__all__ = ['LokiHandler', 'LokiFormatter'] \ No newline at end of file diff --git a/utils/logs/formatters.py b/utils/logs/formatters.py new file mode 100644 index 0000000..def86d5 --- /dev/null +++ b/utils/logs/formatters.py @@ -0,0 +1,77 @@ +import logging +import socket +from datetime import datetime +from logging import BASIC_FORMAT + + +class LokiFormatter(logging.Formatter): + asctime_search = "%(asctime)" + tz = "UTC" + source = "Loki" + src_host = "localhost" + tags = {} + + def __init__(self, fmt, dfmt, style, fqdn=False): + super(LokiFormatter, self).__init__() + + self.fmt = fmt or BASIC_FORMAT + self.dfmt = dfmt or "%Y-%m-%d %H:%M:%S" + self.style = style + + if fqdn: + self.host = socket.getfqdn() + else: + self.host = socket.gethostname() + + def format_timestamp(self, time): + return str(int(time * 10**9)) + + def usesTime(self): + return self.fmt.find(self.asctime_search) >= 0 + + def formatMessage(self, record): + try: + return self.fmt % record.__dict__ + except KeyError as e: + raise ValueError("Formatting field not found in record: %s" % e) + + def format(self, record): + record.message = record.getMessage() + + if self.usesTime(): + record.asctime = self.formatTime(record, self.dfmt) + + message = self.formatMessage(record) + + if record.exc_info: + if not record.exc_text: + record.exc_text = self.formatException(record.exc_info) + + if record.exc_text: + if message[-1:] != "\n": + message = message + "\n" + message = message + record.exc_text + + if record.stack_info: + if message[-1:] != "\n": + message = message + "\n" + + message = message + self.formatStack(record.stack_info) + + message = { + "streams": [ + { + "stream": { + **self.tags, + }, + "values": [ + [ + self.format_timestamp(record.created), + message, + ] + ], + } + ] + } + + return message diff --git a/utils/logs/handlers.py b/utils/logs/handlers.py new file mode 100644 index 0000000..284e6a4 --- /dev/null +++ b/utils/logs/handlers.py @@ -0,0 +1,57 @@ +import logging +import sys +from threading import Thread + +import requests + + +class LokiHandler(logging.Handler): + def __init__( + self, + timeout=0.5, + url="http://localhost:3100/loki/api/v1/push", + auth=None, + tags={}, + mode="sync", + ): + super(LokiHandler, self).__init__() + + self._url = url + self._timeout = timeout + self._auth = auth + self._tags = tags + + self._mode = mode + + def emit(self, record): + try: + payload = self.formatter.format(record) + + self._push_message( + self._url, json=payload, timeout=self._timeout, auth=self._auth + ) + except requests.exceptions.ReadTimeout: + sys.stderr.write("Loki connection timed out\n") + except Exception as e: + sys.stderr.write(f"Loki connection failed with: {e}\n") + + def setFormatter(self, fmt): + fmt.tags = self._tags + + self.formatter = fmt + + def _push_message(self, *args, **kwargs): + if self._mode == "sync": + return _push_message(*args, **kwargs) + + if self._mode == "thread": + return Thread(target=_push_message, args=args, kwargs=kwargs).start() + + +def _push_message(*args, **kwargs): + response = requests.post(*args, **kwargs) + + if response.status_code != 204: + sys.stderr.write( + f"Got status {response.status_code} from loki with message: {response.text}\n" + )
{{ totals.total_amount|default:"0"|amount_split_3digit }}
{{ message }}
پرداخت ناموفق
کد پیگیری تراکنش شما: {{ object.reference_number }}
در صورت کسر از موجودی، مبلغ پرداختی طی یک تا 72 ساعت آینده به حساب شما بازگردانده خواهد شد.
پرداخت موفق