referral tracking, wallet, transaction

This commit is contained in:
rizwanisready
2024-03-05 22:04:56 +05:30
parent f286e8b571
commit 3a1a05aa24
23 changed files with 580 additions and 57 deletions

View File

@@ -1,5 +1,5 @@
import re
from django.utils import timezone
from django.contrib.auth.hashers import make_password
from rest_framework import serializers
@@ -13,6 +13,7 @@ from manage_referrals.models import (
ReferralRecord,
)
from goodtimes import constants, date_utils
from manage_subscriptions.models import PrincipalSubscription, SubscriptionStatus
def clean_phone(number: str):
@@ -138,6 +139,7 @@ class ProfileSerializer(serializers.ModelSerializer):
email = serializers.CharField(read_only=True)
invite_count = serializers.SerializerMethodField(read_only=True)
principal_type_name = serializers.SerializerMethodField(read_only=True)
has_active_subscription = serializers.SerializerMethodField(read_only=True)
class Meta:
model = IAmPrincipal
@@ -150,6 +152,7 @@ class ProfileSerializer(serializers.ModelSerializer):
"email",
"invite_count",
"register_complete",
"has_active_subscription",
]
def update(self, instance, validated_data):
@@ -162,10 +165,7 @@ class ProfileSerializer(serializers.ModelSerializer):
def get_invite_count(self, obj):
if obj:
principal_type = self.context.get(
"principal_type"
) # Retrieve the principal_type from the context
return ReferralRecord.get_invite_count(obj, principal_type)
return ReferralRecord.get_invite_count(obj)
return 0
def get_principal_type_name(self, obj):
@@ -177,6 +177,19 @@ class ProfileSerializer(serializers.ModelSerializer):
return request.build_absolute_uri(image_field.url)
return ""
def get_has_active_subscription(self, obj):
today = timezone.now().date()
try:
last_active_subscription = PrincipalSubscription.objects.filter(
principal=obj,
cancelled=False,
status=SubscriptionStatus.ACTIVE,
end_date__gte=today,
).latest("end_date")
return True # If the query does not raise DoesNotExist, return True
except PrincipalSubscription.DoesNotExist:
return False # If no matching subscription is found, return False
def to_representation(self, instance):
data = super().to_representation(instance)
request = self.context.get("request")

View File

@@ -709,7 +709,6 @@ class GoogleLoginAPIView(APIView):
principal, created = IAmPrincipal.objects.update_or_create(
email=email,
username=email,
defaults=defaults,
)
principal_type_instance = IAmPrincipalType.objects.get(name=principal_type)
@@ -718,6 +717,7 @@ class GoogleLoginAPIView(APIView):
print("New Created")
default_password = f"GTMES{email[::-1]}"
principal.set_password(default_password)
principal.username = email
principal.principal_type = principal_type_instance # Assuming principal_type should only be set on creation
principal.principal_source = google_source
principal.save()

View File

@@ -1,5 +1,10 @@
from django import forms
from .models import ReferralRecord, ReferralRecordReward, GoodTimeCoins
from .models import (
ReferralRecord,
ReferralRecordReward,
GoodTimeCoins,
ReferralTracking,
)
class ReferralRecordForm(forms.ModelForm):
@@ -35,7 +40,32 @@ class GoodTimeCoinsForm(forms.ModelForm):
class Meta:
model = GoodTimeCoins
fields = ["value_in_pound", "comments"]
# widgets = {
# "start_date": forms.DateInput(attrs={"type": "date"}),
# "end_date": forms.DateInput(attrs={"type": "date"}),
# }
class ReferralTrackingForm(forms.ModelForm):
class Meta:
model = ReferralTracking
fields = [
"referral_record",
"referrer_subscription_id",
"referred_subscription_id",
"is_referrer_subscribed",
"ip_address",
"user_agent",
"device_model",
]
widgets = {
"referral_record": forms.Select(attrs={"class": "form-control"}),
"referrer_subscription_id": forms.NumberInput(
attrs={"class": "form-control"}
),
"referred_subscription_id": forms.NumberInput(
attrs={"class": "form-control"}
),
"is_referrer_subscribed": forms.CheckboxInput(
attrs={"class": "form-check-input"}
),
"ip_address": forms.TextInput(attrs={"class": "form-control"}),
"user_agent": forms.TextInput(attrs={"class": "form-control"}),
"device_model": forms.TextInput(attrs={"class": "form-control"}),
}

View File

@@ -117,15 +117,15 @@ class ReferralRecord(BaseModel):
return f"Referral ID: {self.id}, Referrar name: {self.referrer_principal.first_name}, Type: {self.principal_type.name}"
@classmethod
def filter_invite_records(cls, referrer_principal, principal_type):
def filter_invite_records(cls, referrer_principal):
record_instance = cls.objects.filter(
referrer_principal=referrer_principal, principal_type__name=principal_type
referrer_principal=referrer_principal,
)
return record_instance
@classmethod
def get_invite_count(cls, referrer_principal, principal_type):
filter_record = cls.filter_invite_records(referrer_principal, principal_type)
def get_invite_count(cls, referrer_principal):
filter_record = cls.filter_invite_records(referrer_principal)
return filter_record.count()

View File

@@ -67,4 +67,21 @@ urlpatterns = [
views.GTCoinsDeleteView.as_view(),
name="coin_delete",
),
# Referral Tracking
path("track/list/", views.ReferralTrackingView.as_view(), name="track_list"),
# path(
# "track/add/",
# views.ReferralTrackingCreateOrUpdateView.as_view(),
# name="track_add",
# ),
path(
"track/edit/<int:pk>/",
views.ReferralTrackingCreateOrUpdateView.as_view(),
name="track_edit",
),
path(
"track/delete/<int:pk>",
views.ReferralTrackingDeleteView.as_view(),
name="track_delete",
),
]

View File

@@ -9,8 +9,14 @@ from manage_referrals.forms import (
ReferralRecordForm,
ReferralRecordRewardForm,
GoodTimeCoinsForm,
ReferralTrackingForm,
)
from manage_referrals.models import (
ReferralRecord,
ReferralRecordReward,
GoodTimeCoins,
ReferralTracking,
)
from manage_referrals.models import ReferralRecord, ReferralRecordReward, GoodTimeCoins
from django.contrib import messages
@@ -336,3 +342,106 @@ class GTCoinsDeleteView(LoginRequiredMixin, generic.View):
messages.success(request, self.error_message)
return redirect(self.success_url)
class ReferralTrackingCreateOrUpdateView(LoginRequiredMixin, generic.View):
# Set the page_name and resource
page_name = resource_action.RESOURCE_MANAGE_REFERRALS
resource = resource_action.RESOURCE_MANAGE_REFERRALS
# Initialize the action as ACTION_CREATE (can change based on logic)
action = resource_action.ACTION_CREATE # Default action
template_name = "manage_referrals/track_add.html"
model = ReferralTracking
form_class = ReferralTrackingForm
success_url = reverse_lazy("manage_referrals:track_list")
error_message = "An error occurred while saving the data."
# Determine the success message dynamically based on whether it's an update or create
def get_success_message(self):
self.success_message = (
constants.RECORD_CREATED if not self.object else constants.RECORD_UPDATED
)
return self.success_message
# Get the object (if exists) based on URL parameter 'pk'
def get_object(self):
pk = self.kwargs.get("pk")
return get_object_or_404(self.model, pk=pk) if pk else None
# Add page_name and operation to the context
def get_context_data(self, **kwargs):
context = {
"page_name": self.page_name,
"operation": "Add" if not self.object else "Edit",
}
context.update(kwargs) # Include any additional context data passed to the view
return context
def get(self, request, *args, **kwargs):
self.object = self.get_object()
# If an object is found, change action to ACTION_UPDATE
if self.object is not None:
self.action = resource_action.ACTION_UPDATE
print("get method of article is called")
form = self.form_class(instance=self.object)
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
def post(self, request, args, *kwargs):
self.object = self.get_object()
# If an object is found, change action to ACTION_UPDATE
if self.object is not None:
self.action = resource_action.ACTION_UPDATE
print("post method is called")
form = self.form_class(request.POST, request.FILES, instance=self.object)
print("request with files", request.FILES)
if not form.is_valid():
print(form.errors)
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
form.save()
messages.success(self.request, self.get_success_message())
return redirect(self.success_url)
class ReferralTrackingView(LoginRequiredMixin, generic.ListView):
page_name = resource_action.RESOURCE_MANAGE_REFERRALS
resource = resource_action.RESOURCE_MANAGE_REFERRALS
action = resource_action.ACTION_READ
model = ReferralTracking
template_name = "manage_referrals/track_list.html"
context_object_name = "tracks"
def get_queryset(self):
return super().get_queryset().filter(active=True, deleted=False)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["page_name"] = self.page_name
return context
class ReferralTrackingDeleteView(LoginRequiredMixin, generic.View):
page_name = resource_action.RESOURCE_MANAGE_REFERRALS
resource = resource_action.RESOURCE_MANAGE_REFERRALS
action = resource_action.ACTION_DELETE
model = ReferralTracking
success_url = reverse_lazy("manage_referrals:track_list")
success_message = constants.RECORD_DELETED
error_message = constants.RECORD_NOT_FOUND
def get(self, request, pk):
try:
type_obj = self.model.objects.get(id=pk)
type_obj.deleted = True
type_obj.active = False
type_obj.save()
messages.success(request, self.success_message)
except self.model.DoesNotExist:
messages.success(request, self.error_message)
return redirect(self.success_url)

View File

@@ -8,4 +8,5 @@ from rest_framework_simplejwt.views import (
urlpatterns = [
path('buy-subscription/', views.CreatePrincipalSubscriptionApi.as_view(), name='buy_subscription'),
path('test-webhook/', views.StripeWebhookTest.as_view(), name='webhook_test'),
path('check-subscription/', views.LastActiveSubscriptionView.as_view(), name='check_subscription'),
]

View File

@@ -10,7 +10,11 @@ import stripe
from accounts.models import IAmPrincipal
import json
from goodtimes import constants, services
from manage_subscriptions.models import Subscription, PrincipalSubscription
from manage_subscriptions.models import (
Subscription,
PrincipalSubscription,
SubscriptionStatus,
)
from goodtimes.utils import ApiResponse
from accounts.resource_action import (
PRINCIPAL_TYPE_EVENT_USER,
@@ -206,3 +210,32 @@ class StripeWebhookTest(APIView):
message="Error processing event",
errors=str(e),
)
class LastActiveSubscriptionView(APIView):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request, *args, **kwargs):
today = timezone.now().date()
try:
last_active_subscription = PrincipalSubscription.objects.filter(
principal=request.user,
cancelled=False,
status=SubscriptionStatus.ACTIVE,
end_date__gte=today,
).latest("end_date")
serializer = PrincipalSubscriptionSerializer(last_active_subscription)
return ApiResponse.success(
status=status.HTTP_200_OK,
message=constants.SUCCESS,
data=serializer.data,
)
except PrincipalSubscription.DoesNotExist:
return ApiResponse.error(
status=status.HTTP_404_NOT_FOUND,
message="No Active Subscription Found",
errors="No Active Subscription Found",
)

View File

@@ -39,6 +39,7 @@ urlpatterns = [
views.PlanDeleteView.as_view(),
name="plan_delete",
),
# Principal Subscription
path("principal_subscription/list/", views.PrincipalSubscriptionView.as_view(), name="principal_subscriptions_list"),
path(
"principal_subscription/add/",

52
manage_wallets/forms.py Normal file
View File

@@ -0,0 +1,52 @@
from django import forms
from .models import Wallet, Transaction
class WalletForm(forms.ModelForm):
class Meta:
model = Wallet
fields = [
"principal",
"balance",
"deposit",
"earnings",
"coins",
"withdrawal_balance",
]
widgets = {
"principal": forms.Select(attrs={"class": "form-control"}),
"balance": forms.NumberInput(attrs={"class": "form-control"}),
"deposit": forms.NumberInput(attrs={"class": "form-control"}),
"earnings": forms.NumberInput(attrs={"class": "form-control"}),
"coins": forms.NumberInput(attrs={"class": "form-control"}),
"withdrawal_balance": forms.NumberInput(attrs={"class": "form-control"}),
}
class TransactionForm(forms.ModelForm):
class Meta:
model = Transaction
fields = [
"principal",
"principal_subscription",
"transaction_type",
"payment_method",
"transaction_status",
"amount",
"comment",
"order_id",
"product_id",
"reference_id",
]
widgets = {
"principal": forms.Select(attrs={"class": "form-control"}),
"principal_subscription": forms.Select(attrs={"class": "form-control"}),
"transaction_type": forms.Select(attrs={"class": "form-control"}),
"payment_method": forms.Select(attrs={"class": "form-control"}),
"transaction_status": forms.Select(attrs={"class": "form-control"}),
"amount": forms.NumberInput(attrs={"class": "form-control"}),
"comment": forms.TextInput(attrs={"class": "form-control"}),
"order_id": forms.TextInput(attrs={"class": "form-control"}),
"product_id": forms.TextInput(attrs={"class": "form-control"}),
"reference_id": forms.TextInput(attrs={"class": "form-control"}),
}

View File

@@ -11,6 +11,6 @@ urlpatterns = [
# for manage payment related url
path('peyment/', views.PaymentListView.as_view(), name='payment_list'),
path('payment/', views.PaymentListView.as_view(), name='payment_list'),
]

View File

@@ -16,7 +16,7 @@
<div class="col-lg-12">
<div class="row mb-2">
<div class="col">
<h3>Add Event</h3>
<h3>{{operation}} {{page_title}}</h3>
</div>
<div class="col text-end">
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">

View File

@@ -16,7 +16,7 @@
<div class="col-lg-12">
<div class="row mb-2">
<div class="col">
<h3>Add Event Category</h3>
<h3>{{operation}} {{page_title}}</h3>
</div>
<div class="col text-end">
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">

View File

@@ -16,7 +16,7 @@
<div class="col-lg-12">
<div class="row mb-2">
<div class="col">
<h3>Add Event</h3>
<h3>{{operation}} {{page_title}}</h3>
</div>
<div class="col text-end">
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">

View File

@@ -22,6 +22,7 @@
</button>
-->
<a class="btn btn-primary mb-2" href="{% url 'manage_referrals:reward_list' %}">Referral Rewards</a>
<a class="btn btn-primary mb-2" href="{% url 'manage_referrals:track_list' %}">Referral Tracking</a>
<a class="btn btn-primary mb-2" href="{% url 'manage_referrals:coin_list' %}">Good Time Coins</a>
</div>
</div>

View File

@@ -0,0 +1,135 @@
{% extends 'layout/base_template.html' %}
{% load static %}
{% block stylesheet %}
<!-- include required css cdn link through html here -->
{% include "cdn_through_html/filepond_cdn_css.html" %}
{% include "cdn_through_html/quill_cdn_css.html" %}
{% include "cdn_through_html/tagify_cdn_css.html" %}
{{form.media}}
{% endblock %}
{% block content %}
<div class="row layout-top-spacing">
<div class="col-lg-12">
<div class="row mb-2">
<div class="col">
<h3>Add Referral Track</h3>
</div>
<div class="col text-end">
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">
<i class="fa fa-arrow-left"></i>
Back
</button>
</div>
</div>
<div class="row layout-spacing">
<div class="col-lg-12">
<div class="statbox widget box box-shadow">
<div class="widget-content widget-content-area">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% include 'includes/dynamic_template_form.html' with form=form %}
<div class="mt-4 mb-0">
<div class="d-grid"><button class="btn btn-primary btn-block" type="submit">Submit</button></div>
</div>
{% comment %} <div class="mb-3">
<label for="title" class="form-label">Title</label>
<input type="text" class="form-control" id="title" aria-describedby="title">
<div id="emailHelp" class="form-text" style="color: grey;">We'll never share your email with anyone else.</div>
</div>
<div class="mb-3">
<label class="form-label">Description</label>
<div id="description"></div>
</div>
<div class="mb-3">
<label for="product-images">Image</label>
<div class="multiple-file-upload">
<div class="filepond--root filepond file-upload-multiple filepond--hopper" id="images" data-style-button-remove-item-position="left" data-style-button-process-item-position="right" data-style-load-indicator-position="right" data-style-progress-indicator-position="right" data-style-button-remove-item-align="false" style="height: 57px;"><input class="filepond--browser" type="file" id="filepond--browser-feeq8o6dj" name="filepond" aria-controls="filepond--assistant-feeq8o6dj" aria-labelledby="filepond--drop-label-feeq8o6dj" multiple=""><a class="filepond--credits" aria-hidden="true" href="https://pqina.nl/" target="_blank" rel="noopener noreferrer" style="transform: translateY(49px);">Powered by PQINA</a><div class="filepond--drop-label" style="transform: translate3d(0px, 0px, 0px); opacity: 1;"><label for="filepond--browser-feeq8o6dj" id="filepond--drop-label-feeq8o6dj" aria-hidden="true">Drag &amp; Drop your files or <span class="filepond--label-action" tabindex="0">Browse</span></label></div><div class="filepond--list-scroller" style="transform: translate3d(0px, 41px, 0px);"><ul class="filepond--list" role="list"></ul></div><div class="filepond--panel filepond--panel-root" data-scalable="true"><div class="filepond--panel-top filepond--panel-root"></div><div class="filepond--panel-center filepond--panel-root" style="transform: translate3d(0px, 8px, 0px) scale3d(1, 0.41, 1);"></div><div class="filepond--panel-bottom filepond--panel-root" style="transform: translate3d(0px, 49px, 0px);"></div></div><span class="filepond--assistant" id="filepond--assistant-feeq8o6dj" role="status" aria-live="polite" aria-relevant="additions"></span><div class="filepond--drip"></div><fieldset class="filepond--data"></fieldset></div>
</div>
</div>
<div class="mb-3">
<label for="tags">Tags</label>
<input id="tags" class="tags" value="">
</div>
<button type="submit" class="btn btn-primary">Submit</button> {% endcomment %}
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block javascript %}
<!-- include required css cdn link through html here -->
{% include "cdn_through_html/filepond_cdn_js.html" %}
{% include "cdn_through_html/quill_cdn_js.html" %}
{% include "cdn_through_html/tagify_cdn_js.html" %}
<script>
/**
* ===================================
* Blog Description Editor
* ===================================
*/
var quill = new Quill('#description', {
modules: {
toolbar: [
[{ header: [1, 2, false] }],
['bold', 'italic', 'underline'],
['image', 'code-block']
]
},
placeholder: 'Write description...',
theme: 'snow' // or 'bubble'
});
/**
* ====================
* File Pond
* ====================
*/
// We want to preview images, so we register
// the Image Preview plugin, We also register
// exif orientation (to correct mobile image
// orientation) and size validation, to prevent
// large files from being added
FilePond.registerPlugin(
FilePondPluginImagePreview,
FilePondPluginImageExifOrientation,
FilePondPluginFileValidateSize,
// FilePondPluginImageEdit
);
// Select the file input and use
// create() to turn it into a pond
var ecommerce = FilePond.create(document.querySelector('.file-upload-multiple'));
/**
* =====================
* Blog Tags
* =====================
*/
// The DOM element you wish to replace with Tagify
var input = document.querySelector('#id_tags');
// initialize Tagify on the above input node reference
new Tagify(input,{
originalInputValueFormat: valuesArr => valuesArr.map(item => item.value).join(', ')
})
</script>
{% endblock %}

View File

@@ -0,0 +1,140 @@
{% extends 'layout/base_template.html' %}
{% load static %}
{% block stylesheet %}
<!-- include required css cdn link through html here -->
{% include "cdn_through_html/datatable_cdn_css.html" %}
{% endblock %}
{% block content %}
<div class="row layout-top-spacing">
<div class="col-lg-12">
<div class="row">
<div class="col-sm-6">
<h3>Referral Tracking</h3>
</div>
<div class="col-sm-6 text-md-end">
<!--
<button class="btn btn-dark mb-2 me-md-4" onclick="history.back()">
<i class="fa fa-arrow-left"></i>
Back
</button>
-->
<a class="btn btn-primary mb-2" href="{% url 'manage_referrals:record_list' %}">Referral Record</a>
<a class="btn btn-primary mb-2" href="{% url 'manage_referrals:coin_list' %}">Good Time Coins</a>
</div>
</div>
<div class="row layout-spacing">
<div class="col-lg-12">
<div class="statbox widget box box-shadow">
<div class="widget-content widget-content-area">
<div id="style-3_wrapper" class="dataTables_wrapper container-fluid dt-bootstrap4 no-footer">
<div class="table-responsive">
<table id="style-3" class="table style-3 dt-table-hover dataTable no-footer" role="grid"
aria-describedby="style-3_info">
<thead>
<tr role="row">
<th class="checkbox-column sorting_asc" tabindex="0" aria-controls="style-3"
aria-sort="ascending" style="width: 69.2656px;"> Record Id </th>
<th class="checkbox-column sorting_asc" tabindex="0" aria-controls="style-3"
aria-sort="ascending" style="width: 69.2656px;"> Referral Record </th>
<th class="checkbox-column sorting_asc" tabindex="0" aria-controls="style-3"
aria-sort="ascending" style="width: 69.2656px;"> Referrer Subscription </th>
<th class="checkbox-column sorting_asc" tabindex="0" aria-controls="style-3"
aria-sort="ascending" style="width: 69.2656px;"> Referred Subscription </th>
<th class="checkbox-column sorting_asc" tabindex="0" aria-controls="style-3"
aria-sort="ascending" style="width: 69.2656px;"> Referrer Subscription Active </th>
<th class="sorting" tabindex="7" aria-controls="style-3"
style="width: 79.7969px;">Active</th>
<th class="dt-no-sorting sorting" tabindex="8" aria-controls="style-3"
style="width: 100.625px;">Action</th>
</tr>
</thead>
<tbody>
{% for data_obj in tracks %}
<tr role="row">
<td class="checkbox-column text-center sorting_1">{{data_obj.id}}</td>
<td>{{data_obj.referral_record}}</td>
<td>{{data_obj.referrer_subscription_id}}</td>
<td>{{data_obj.referred_subscription_id}}</td>
<td>{{data_obj.is_referrer_subscribed}}</td>
<td class="text-center">
<span
class="shadow-none badge {% if data_obj.active %}badge-primary{% else %}badge-danger{% endif %}">{{data_obj.active}}</span>
</td>
<td class="text-center">
<ul class="table-controls">
<li><a href="{% url 'manage_referrals:track_edit' data_obj.id %}"
class="bs-tooltip" data-bs-toggle="tooltip"
data-bs-placement="top" title="" data-original-title="Edit"
data-bs-original-title="Edit" aria-label="Edit"><svg
xmlns="http://www.w3.org/2000/svg" width="24"
height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round"
class="feather feather-edit-2 p-1 br-8 mb-1">
<path
d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z">
</path>
</svg></a></li>
<li><a href="{% url 'manage_referrals:track_delete' data_obj.id %}"
class="bs-tooltip" data-bs-toggle="tooltip"
data-bs-placement="top" title=""
data-original-title="Delete" data-bs-original-title="Delete"
aria-label="Delete"><svg xmlns="http://www.w3.org/2000/svg"
width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round"
class="feather feather-trash p-1 br-8 mb-1">
<polyline points="3 6 5 6 21 6"></polyline>
<path
d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2">
</path>
</svg></a></li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block javascript %}
<!-- include required js cdn link through html here -->
{% include "cdn_through_html/datatable_cdn_js.html" %}
<script>
c3 = $('#style-3').DataTable({
"dom": "<'dt--top-section'<'row'<'col-12 col-sm-6 d-flex justify-content-sm-start justify-content-center'l><'col-12 col-sm-6 d-flex justify-content-sm-end justify-content-center mt-sm-0 mt-3'f>>>" +
"<'table-responsive'tr>" +
"<'dt--bottom-section d-sm-flex justify-content-sm-between text-center'<'dt--pages-count mb-sm-0 mb-3'i><'dt--pagination'p>>",
"oLanguage": {
"oPaginate": { "sPrevious": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>', "sNext": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>' },
"sInfo": "Showing page PAGE of _PAGES_",
"sSearch": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
"sSearchPlaceholder": "Search...",
"sLengthMenu": "Results : _MENU_",
},
"stripeClasses": [],
"lengthMenu": [5, 10, 20, 50],
"pageLength": 10
});
multiCheck(c3);
</script>
{% endblock %}

View File

@@ -16,7 +16,7 @@
<div class="col-lg-12">
<div class="row mb-2">
<div class="col">
<h3>Add Plan</h3>
<h3>{{operation}} {{page_name}}</h3>
</div>
<div class="col text-end">
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">

View File

@@ -16,7 +16,7 @@
<div class="col-lg-12">
<div class="row mb-2">
<div class="col">
<h3>Add Principal Subscription</h3>
<h3>{{operation}} {{page_name}}</h3>
</div>
<div class="col text-end">
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">

View File

@@ -85,7 +85,7 @@
</td>
<td class="text-center">
<ul class="table-controls">
<li><a href="{% url 'manage_subscriptions:subscription_edit' data_obj.id %}" class="bs-tooltip"
<li><a href="{% url 'manage_subscriptions:principal_subscription_edit' data_obj.id %}" class="bs-tooltip"
data-bs-toggle="tooltip" data-bs-placement="top" title=""
data-original-title="Edit" data-bs-original-title="Edit"
aria-label="Edit"><svg xmlns="http://www.w3.org/2000/svg"
@@ -97,7 +97,7 @@
d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z">
</path>
</svg></a></li>
<li><a href="{% url 'manage_subscriptions:subscription_delete' data_obj.id %}" class="bs-tooltip"
<li><a href="{% url 'manage_subscriptions:principal_subscription_delete' data_obj.id %}" class="bs-tooltip"
data-bs-toggle="tooltip" data-bs-placement="top" title=""
data-original-title="Delete" data-bs-original-title="Delete"
aria-label="Delete"><svg xmlns="http://www.w3.org/2000/svg"

View File

@@ -16,7 +16,7 @@
<div class="col-lg-12">
<div class="row mb-2">
<div class="col">
<h3>Add Principal Subscription</h3>
<h3>{{operation}} {{page_name}}</h3>
</div>
<div class="col text-end">
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">

View File

@@ -15,11 +15,7 @@
<h3>Manage Payment</h3>
</div>
<div class="col text-end">
{% comment %} <button class="btn btn-dark mb-2 me-4" onclick="history.back()">
<i class="fa fa-arrow-left"></i>
Back
</button> {% endcomment %}
{% comment %} <a class="btn btn-primary mb-2 me-4" href="{% url 'manage_cms:newsletter_add' %}">Add Newsletter</a> {% endcomment %}
</div>
</div>
@@ -64,12 +60,16 @@
<tr role="row">
<td class="checkbox-column text-center sorting_1">{{transaction_obj.id}}</td>
<td>{{transaction_obj.principal.phone_no}}</td>
<td>{{transaction_obj.principal_type}}</td>
<td>{{transaction_obj.get_transaction_type_display}}</td>
<td>{{transaction_obj.get_transaction_status_display}}</td>
<td>{{transaction_obj.principal}}</td>
<td>{{transaction_obj.principal_subscription}}</td>
<td>{{transaction_obj.transaction_type}}</td>
<td>{{transaction_obj.payment_method}}</td>
<td>{{transaction_obj.transaction_status}}</td>
<td>{{transaction_obj.amount}}</td>
<td>{{transaction_obj.comment}}</td>
<td>{{transaction_obj.order_id}}</td>
<td>{{transaction_obj.product_id}}</td>
<td>{{transaction_obj.reference_id}}</td>
</tr>

View File

@@ -15,11 +15,7 @@
<h3>Manage Wallet</h3>
</div>
<div class="col text-end">
{% comment %} <button class="btn btn-dark mb-2 me-4" onclick="history.back()">
<i class="fa fa-arrow-left"></i>
Back
</button> {% endcomment %}
{% comment %} <a class="btn btn-primary mb-2 me-4" href="{% url 'manage_cms:newsletter_add' %}">Add Newsletter</a> {% endcomment %}
</div>
</div>
@@ -39,26 +35,23 @@
style="width: 69.2656px;"> Record Id </th>
<th class="text-center sorting" tabindex="0" aria-controls="style-3" rowspan="1"
colspan="1" aria-label="Image: activate to sort column ascending"
style="width: 44.2344px;">User</th>
style="width: 44.2344px;">Principal</th>
<th class="sorting" tabindex="0" aria-controls="style-3" rowspan="1" colspan="1"
aria-label="First Name: activate to sort column ascending"
style="width: 79.7969px;">Player Balance</th>
style="width: 79.7969px;">Balance</th>
<th class="sorting" tabindex="0" aria-controls="style-3" rowspan="1" colspan="1"
aria-label="Last Name: activate to sort column ascending"
style="width: 77.3281px;">Player Deposit</th>
style="width: 77.3281px;">Deposit</th>
<th class="sorting" tabindex="0" aria-controls="style-3" rowspan="1" colspan="1"
aria-label="Email: activate to sort column ascending"
style="width: 143.516px;">Player Bonus</th>
style="width: 143.516px;">Earnings</th>
<th class="sorting" tabindex="0" aria-controls="style-3" rowspan="1" colspan="1"
aria-label="Mobile No.: activate to sort column ascending"
style="width: 98.875px;">Merchant Balance</th>
<th class="text-center sorting" tabindex="0" aria-controls="style-3" rowspan="1"
colspan="1" aria-label="Status: activate to sort column ascending"
style="width: 76.625px;">Merchant Deposit</th>
style="width: 98.875px;">Coins</th>
<th class="text-center dt-no-sorting sorting" tabindex="0"
aria-controls="style-3" rowspan="1" colspan="1"
aria-label="Action: activate to sort column ascending"
style="width: 51.625px;">Merchant Bonus</th>
style="width: 51.625px;">Withdrawal Balance</th>
</tr>
</thead>
<tbody>
@@ -67,14 +60,12 @@
<tr role="row">
<td class="checkbox-column text-center sorting_1">{{wallet_obj.id}}</td>
<td>{{wallet_obj.principal.phone_no}}</td>
<td>{{wallet_obj.player_balance}}</td>
<td>{{wallet_obj.player_deposit}}</td>
<td>{{wallet_obj.player_bonus}}</td>
<td>{{wallet_obj.merchant_balance}}</td>
<td>{{wallet_obj.merchant_deposit}}</td>
<td>{{wallet_obj.merchant_bonus}}</td>
<td>{{wallet_obj.principal}}</td>
<td>{{wallet_obj.balance}}</td>
<td>{{wallet_obj.deposit}}</td>
<td>{{wallet_obj.earnings}}</td>
<td>{{wallet_obj.coins}}</td>
<td>{{wallet_obj.withdrawal_balance}}</td>
</tr>
{% endfor %}