payment actions
This commit is contained in:
parent
9f14c9f79e
commit
d1eaaa25bd
20 changed files with 144 additions and 6 deletions
0
apps/core/__init__.py
Normal file
0
apps/core/__init__.py
Normal file
2
apps/core/admin.py
Normal file
2
apps/core/admin.py
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
6
apps/core/apps.py
Normal file
6
apps/core/apps.py
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class CoreConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'apps.core'
|
||||||
0
apps/core/migrations/__init__.py
Normal file
0
apps/core/migrations/__init__.py
Normal file
2
apps/core/models.py
Normal file
2
apps/core/models.py
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
1
apps/core/templates/jalali_date/widgets/attrs.html
Normal file
1
apps/core/templates/jalali_date/widgets/attrs.html
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{% for name, value in widget.attrs.items %}{% if value is not False %} {{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}{% endfor %}
|
||||||
1
apps/core/templates/jalali_date/widgets/date.html
Normal file
1
apps/core/templates/jalali_date/widgets/date.html
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<input type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value|stringformat:'s' }}"{% endif %}{% include "django/forms/widgets/attrs.html" %} data-jdp>
|
||||||
0
apps/core/templatetags/__init__.py
Normal file
0
apps/core/templatetags/__init__.py
Normal file
30
apps/core/templatetags/tags.py
Normal file
30
apps/core/templatetags/tags.py
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
from django import template
|
||||||
|
import jdatetime
|
||||||
|
from django.core.paginator import Paginator
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name="to_jalali")
|
||||||
|
def to_jalali(value):
|
||||||
|
if value:
|
||||||
|
return jdatetime.date.fromgregorian(date=value, locale='fa_IR').strftime("%Y/%m/%d")
|
||||||
|
else:
|
||||||
|
return value
|
||||||
|
|
||||||
|
@register.filter(name="amount_split_3digit")
|
||||||
|
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]])
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def get_proper_elided_page_range(p, number, on_each_side=2, on_ends=2):
|
||||||
|
paginator = Paginator(p.object_list, p.per_page)
|
||||||
|
return paginator.get_elided_page_range(number=number,
|
||||||
|
on_each_side=on_each_side,
|
||||||
|
on_ends=on_ends)
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def get_item(dictionary, key):
|
||||||
|
return dictionary.get(key)
|
||||||
3
apps/core/tests.py
Normal file
3
apps/core/tests.py
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
7
apps/core/urls.py
Normal file
7
apps/core/urls.py
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
from django.urls import path, include
|
||||||
|
from .views import HomeView
|
||||||
|
app_name = "core"
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', HomeView.as_view(), name='home'),
|
||||||
|
]
|
||||||
0
apps/core/utils/__init__.py
Normal file
0
apps/core/utils/__init__.py
Normal file
51
apps/core/utils/jalali_date.py
Normal file
51
apps/core/utils/jalali_date.py
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
|
from django.templatetags.static import static
|
||||||
|
from django.contrib.admin.widgets import AdminDateWidget
|
||||||
|
from django.forms.fields import DateField, SplitDateTimeField, TimeField, DateTimeField
|
||||||
|
from django.utils.encoding import force_str
|
||||||
|
from datetime import date as datetime_date, datetime as datetime_datetime
|
||||||
|
from jdatetime import GregorianToJalali, datetime as jalali_datetime
|
||||||
|
import jdatetime
|
||||||
|
|
||||||
|
class JalaliDateField(DateField):
|
||||||
|
def __init__(self, *, input_formats=None, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.input_formats.insert(0, settings.JALALI_DATE_DEFAULTS['Strftime']['date'])
|
||||||
|
|
||||||
|
def prepare_value(self, value):
|
||||||
|
if isinstance(value, datetime_date):
|
||||||
|
date_obj = jdatetime.datetime.fromgregorian(datetime=value)
|
||||||
|
return date_obj.strftime(settings.JALALI_DATE_DEFAULTS['Strftime']['date'])
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
def strptime(self, value, format):
|
||||||
|
return jalali_datetime.strptime(force_str(value), format).togregorian().date()
|
||||||
|
|
||||||
|
|
||||||
|
class CustomSelectWidget(forms.widgets.Select):
|
||||||
|
option_template_name = 'widgets/select_option.html'
|
||||||
|
|
||||||
|
|
||||||
|
class AdminJalaliDateWidget(AdminDateWidget):
|
||||||
|
template_name = "jalali_date/widgets/date.html"
|
||||||
|
|
||||||
|
# @property
|
||||||
|
# def media(self):
|
||||||
|
# js = settings.JALALI_DATE_DEFAULTS['Static']['js']
|
||||||
|
# css = settings.JALALI_DATE_DEFAULTS['Static']['css']
|
||||||
|
# return forms.Media(js=[static(path) for path in js], css=css)
|
||||||
|
|
||||||
|
def __init__(self, attrs=None, format=None):
|
||||||
|
final_attrs = {'class': 'jalali_date-date', 'size': '10'}
|
||||||
|
if attrs is not None:
|
||||||
|
final_attrs.update(attrs)
|
||||||
|
super(AdminJalaliDateWidget, self).__init__(attrs=final_attrs, format=format)
|
||||||
|
|
||||||
|
def render(self, name, value, attrs=None, renderer=None):
|
||||||
|
"""Render the widget as an HTML string."""
|
||||||
|
context = self.get_context(name, value, attrs)
|
||||||
|
return self._render(self.template_name, context, renderer)
|
||||||
|
|
||||||
|
|
||||||
10
apps/core/views.py
Normal file
10
apps/core/views.py
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
|
@method_decorator(login_required, name='dispatch')
|
||||||
|
class HomeView(TemplateView):
|
||||||
|
template_name = 'core/home.html'
|
||||||
|
|
||||||
|
|
@ -47,7 +47,8 @@ class OAUTHLoginCallbackView(DetailView):
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
state = self.request.GET.get('state')
|
state = self.request.GET.get('state')
|
||||||
code = self.request.GET.get('code')
|
code = self.request.GET.get('code')
|
||||||
obj = OAuthCode.objects.get(pk=state)
|
obj = OAuthCode.objects.filter(pk=state).first()
|
||||||
|
if obj:
|
||||||
obj.code = code
|
obj.code = code
|
||||||
obj.save()
|
obj.save()
|
||||||
return obj
|
return obj
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,11 @@ class TransactionDetailView(UpdateView):
|
||||||
form_class = TransactionActionForm
|
form_class = TransactionActionForm
|
||||||
template_name = 'wallet/transaction_detail.html'
|
template_name = 'wallet/transaction_detail.html'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context_data = super().get_context_data(**kwargs)
|
||||||
|
context_data['StateChoices'] = StateChoices
|
||||||
|
return context_data
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
return Transaction.objects.filter(Q(payee=user) | Q(payer=user) | Q(payer__isnull=True)).all()
|
return Transaction.objects.filter(Q(payee=user) | Q(payer=user) | Q(payer__isnull=True)).all()
|
||||||
|
|
|
||||||
12
templates/core/home.html
Normal file
12
templates/core/home.html
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
{% load jalali_tags %}
|
||||||
|
|
||||||
|
{% block title %}wallet: Home{% endblock %}
|
||||||
|
{% block page_title %}wallet: Home{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
wallet
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -18,6 +18,10 @@
|
||||||
<div class="bi bi-file-spreadsheet p-1"></div>
|
<div class="bi bi-file-spreadsheet p-1"></div>
|
||||||
<div class="p-1"><a class="text-decoration-none" href="{% url 'wallet:transaction_list' %}">transactions</a></div>
|
<div class="p-1"><a class="text-decoration-none" href="{% url 'wallet:transaction_list' %}">transactions</a></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col d-flex justify-content-center">
|
||||||
|
<div class="bi bi-file-spreadsheet p-1"></div>
|
||||||
|
<div class="p-1"><a class="text-decoration-none" href="{% url 'swagger-ui' %}">API's</a></div>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="col d-flex justify-content-end">
|
<div class="col d-flex justify-content-end">
|
||||||
{% if not user.is_authenticated %}
|
{% if not user.is_authenticated %}
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,14 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<form action="{{ request.get_full_path }}" method="post" enctype="multipart/form-data">
|
<form action="{{ request.get_full_path }}" method="post" enctype="multipart/form-data">
|
||||||
|
{{ object.state }}
|
||||||
|
{{ StateChoices.CREATED }}
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% if object.state == object.state_choices.created %}
|
{% if object.state == StateChoices.CREATED %}
|
||||||
<div class="col-6 mb-3">
|
<div class="col-6 mb-3">
|
||||||
<input class="w-100 btn btn-primary btn" type="submit" value="پرداخت" name="pay"/>
|
<input class="w-100 btn btn-primary btn" type="submit" value="پرداخت" name="pay"/>
|
||||||
</div>
|
</div>
|
||||||
{% elif object.state == object.state_choices.delayed %}
|
{% elif object.state == StateChoices.DELAYED %}
|
||||||
<div class="col-6 mb-3">
|
<div class="col-6 mb-3">
|
||||||
<input class="w-100 btn btn-primary btn" type="submit" value="تایید پرداخت" name="receipt"/>
|
<input class="w-100 btn btn-primary btn" type="submit" value="تایید پرداخت" name="receipt"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ urlpatterns = [
|
||||||
path('swagger/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
|
path('swagger/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
|
||||||
|
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
path('', include('apps.core.urls')),
|
||||||
path('wallet/', include('apps.wallet.urls')),
|
path('wallet/', include('apps.wallet.urls')),
|
||||||
path('users/', include('apps.users.urls')),
|
path('users/', include('apps.users.urls')),
|
||||||
path('oauth2/', include('oauth2_provider.urls', namespace='oauth2_provider')),
|
path('oauth2/', include('oauth2_provider.urls', namespace='oauth2_provider')),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue