added withdrawal logic
This commit is contained in:
@@ -34,6 +34,8 @@ def compute_resource_action_constants():
|
||||
'RESOURCE_MANAGE_PAYMENT': resource_action.RESOURCE_MANAGE_PAYMENT,
|
||||
'RESOURCE_MANAGE_EVENTS': resource_action.RESOURCE_MANAGE_EVENTS,
|
||||
'RESOURCE_MANAGE_VENUES': resource_action.RESOURCE_MANAGE_VENUES,
|
||||
'RESOURCE_MANAGE_WITHDRAWALS': resource_action.RESOURCE_MANAGE_WITHDRAWALS,
|
||||
'RESOURCE_MANAGE_BANK_ACCOUNTS': resource_action.RESOURCE_MANAGE_BANK_ACCOUNTS,
|
||||
'RESOURCE_MANAGE_CONTACT_US': resource_action.RESOURCE_MANAGE_CONTACT_US,
|
||||
'RESOURCE_MANAGE_CMS': resource_action.RESOURCE_MANAGE_CMS,
|
||||
'RESOURCE_MANAGE_REPORTS': resource_action.RESOURCE_MANAGE_REPORTS,
|
||||
|
||||
@@ -26,6 +26,8 @@ from accounts.resource_action import (
|
||||
RESOURCE_PRINCIPAL_SUBSCRIPTIONS,
|
||||
RESOURCE_MANAGE_REFERRALS,
|
||||
RESOURCE_MANAGE_FEEDBACK,
|
||||
RESOURCE_MANAGE_WITHDRAWALS,
|
||||
RESOURCE_MANAGE_BANK_ACCOUNTS
|
||||
)
|
||||
# this variable store the data of model principaltype, action, resource
|
||||
fixture_data = [
|
||||
@@ -308,4 +310,28 @@ fixture_data = [
|
||||
"action": [1, 2, 3, 4],
|
||||
},
|
||||
},
|
||||
{
|
||||
"model": "accounts.iamappresource",
|
||||
"pk": 16,
|
||||
"fields": {
|
||||
"name": RESOURCE_MANAGE_WITHDRAWALS,
|
||||
"label": RESOURCE_MANAGE_WITHDRAWALS,
|
||||
"slug": RESOURCE_MANAGE_WITHDRAWALS,
|
||||
"created_on": "2023-09-28T16:17:42.815",
|
||||
"modified_on": "2023-09-28T16:17:42.815",
|
||||
"action": [1, 2, 3, 4],
|
||||
},
|
||||
},
|
||||
{
|
||||
"model": "accounts.iamappresource",
|
||||
"pk": 17,
|
||||
"fields": {
|
||||
"name": RESOURCE_MANAGE_BANK_ACCOUNTS,
|
||||
"label": RESOURCE_MANAGE_BANK_ACCOUNTS,
|
||||
"slug": RESOURCE_MANAGE_BANK_ACCOUNTS,
|
||||
"created_on": "2023-09-28T16:17:42.815",
|
||||
"modified_on": "2023-09-28T16:17:42.815",
|
||||
"action": [1, 2, 3, 4],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
@@ -340,9 +340,43 @@
|
||||
"model": "accounts.iamappresource",
|
||||
"pk": 15,
|
||||
"fields": {
|
||||
"name": "principal_subscription",
|
||||
"label": "principal_subscription",
|
||||
"slug": "principal_subscription",
|
||||
"name": "principal_subscriptions",
|
||||
"label": "principal_subscriptions",
|
||||
"slug": "principal_subscriptions",
|
||||
"created_on": "2023-09-28T16:17:42.815",
|
||||
"modified_on": "2023-09-28T16:17:42.815",
|
||||
"action": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "accounts.iamappresource",
|
||||
"pk": 16,
|
||||
"fields": {
|
||||
"name": "manage_withdrawals",
|
||||
"label": "manage_withdrawals",
|
||||
"slug": "manage_withdrawals",
|
||||
"created_on": "2023-09-28T16:17:42.815",
|
||||
"modified_on": "2023-09-28T16:17:42.815",
|
||||
"action": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "accounts.iamappresource",
|
||||
"pk": 17,
|
||||
"fields": {
|
||||
"name": "manage_bank_accounts",
|
||||
"label": "manage_bank_accounts",
|
||||
"slug": "manage_bank_accounts",
|
||||
"created_on": "2023-09-28T16:17:42.815",
|
||||
"modified_on": "2023-09-28T16:17:42.815",
|
||||
"action": [
|
||||
|
||||
@@ -26,6 +26,8 @@ RESOURCE_PRINCIPAL_SUBSCRIPTIONS = "principal_subscriptions"
|
||||
RESOURCE_MANAGE_FEEDBACK = "manage_feedback"
|
||||
RESOURCE_MANAGE_REFERRALS = "manage_referrals"
|
||||
RESOURCE_MANAGE_NOTIFICATIONS = "manage_notifications"
|
||||
RESOURCE_MANAGE_WITHDRAWALS = "manage_withdrawals"
|
||||
RESOURCE_MANAGE_BANK_ACCOUNTS = "manage_bank_accounts"
|
||||
|
||||
|
||||
# These constants are used solely for managing the active and inactive state of pages
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Generated by Django 5.0.2 on 2024-04-04 07:14
|
||||
|
||||
import uuid
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("manage_referrals", "0007_alter_referraltracking_ip_address_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="referralrecordreward",
|
||||
name="unique_token",
|
||||
field=models.UUIDField(
|
||||
blank=True, default=uuid.uuid4, editable=False, null=True
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -1,3 +1,4 @@
|
||||
import uuid
|
||||
from django.db import models
|
||||
import random
|
||||
import string
|
||||
@@ -136,6 +137,9 @@ class ReferralRecordReward(BaseModel):
|
||||
Subscription, on_delete=models.CASCADE, related_name="subscription_reward"
|
||||
)
|
||||
coins = models.PositiveBigIntegerField(default=1)
|
||||
unique_token = models.UUIDField(
|
||||
default=uuid.uuid4, editable=False, null=True, blank=True
|
||||
)
|
||||
value = models.DecimalField(max_digits=14, decimal_places=2)
|
||||
|
||||
class Meta:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from django.db import models
|
||||
from accounts.models import BaseModel, IAmPrincipal, IAmPrincipalType
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# Create your models here.
|
||||
|
||||
|
||||
@@ -30,9 +31,9 @@ class Subscription(BaseModel):
|
||||
|
||||
|
||||
class SubscriptionStatus(models.TextChoices):
|
||||
ACTIVE = 'active', _('Active')
|
||||
EXPIRED = 'expired', _('Expired')
|
||||
INACTIVE = 'inactive', _('Inactive')
|
||||
ACTIVE = "active", _("Active")
|
||||
EXPIRED = "expired", _("Expired")
|
||||
INACTIVE = "inactive", _("Inactive")
|
||||
|
||||
|
||||
class PrincipalSubscription(BaseModel):
|
||||
@@ -57,10 +58,14 @@ class PrincipalSubscription(BaseModel):
|
||||
grace_period_end_date = models.DateField(null=True, blank=True)
|
||||
stripe_customer_id = models.CharField(max_length=255, null=True, blank=True)
|
||||
payment_intent_id = models.CharField(max_length=255, null=True, blank=True)
|
||||
payment_intent_client_secret = models.CharField(max_length=255, null=True, blank=True)
|
||||
payment_intent_client_secret = models.CharField(
|
||||
max_length=255, null=True, blank=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "principal_subscription"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.subscription} - {self.principal.first_name}"
|
||||
|
||||
|
||||
|
||||
@@ -20,33 +20,37 @@ class TransactionSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.Transaction
|
||||
fields = [
|
||||
'id',
|
||||
'principal',
|
||||
'principal_subscription',
|
||||
'transaction_type',
|
||||
'payment_method',
|
||||
'transaction_status',
|
||||
'amount',
|
||||
'coin',
|
||||
'comment',
|
||||
'order_id',
|
||||
'product_id',
|
||||
'reference_id',
|
||||
"id",
|
||||
"principal",
|
||||
"principal_subscription",
|
||||
"transaction_type",
|
||||
"payment_method",
|
||||
"transaction_status",
|
||||
"amount",
|
||||
"coin",
|
||||
"comment",
|
||||
"order_id",
|
||||
"product_id",
|
||||
"reference_id",
|
||||
]
|
||||
extra_kwargs = {
|
||||
'principal': {'read_only': True},
|
||||
'order_id': {'required': False},
|
||||
'product_id': {'required': False},
|
||||
'reference_id': {'required': False},
|
||||
"principal": {"read_only": True},
|
||||
"order_id": {"required": False},
|
||||
"product_id": {"required": False},
|
||||
"reference_id": {"required": False},
|
||||
}
|
||||
|
||||
def to_representation(self, instance):
|
||||
# Customize the representation of the serializer, if necessary
|
||||
representation = super().to_representation(instance)
|
||||
# For example, to display a human-readable version of the transaction type:
|
||||
representation['transaction_type_display'] = instance.get_transaction_type_display()
|
||||
representation['payment_method_display'] = instance.get_payment_method_display()
|
||||
representation['transaction_status_display'] = instance.get_transaction_status_display()
|
||||
representation["transaction_type_display"] = (
|
||||
instance.get_transaction_type_display()
|
||||
)
|
||||
representation["payment_method_display"] = instance.get_payment_method_display()
|
||||
representation["transaction_status_display"] = (
|
||||
instance.get_transaction_status_display()
|
||||
)
|
||||
return representation
|
||||
|
||||
|
||||
@@ -65,3 +69,28 @@ class MerchantDepositSerializer(serializers.Serializer):
|
||||
]
|
||||
)
|
||||
amount = serializers.DecimalField(max_digits=14, decimal_places=2)
|
||||
|
||||
|
||||
class PrincipalBankAccountSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.PrincipalBankAccount
|
||||
fields = ["first_name", "last_name", "account_no", "sort_code"]
|
||||
|
||||
def create(self, validated_data):
|
||||
# Set 'principal', 'created_by' from 'request.user'.
|
||||
user = self.context["request"].user
|
||||
validated_data["principal"] = user
|
||||
validated_data["created_by"] = user
|
||||
return super().create(validated_data)
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
# Set 'modified_by' from 'request.user' during update.
|
||||
user = self.context["request"].user
|
||||
instance.modified_by = user
|
||||
return super().update(instance, validated_data)
|
||||
|
||||
|
||||
class WithdrawalRequestSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.WithdrawalRequest
|
||||
fields = ["notes"]
|
||||
|
||||
@@ -15,4 +15,6 @@ urlpatterns = [
|
||||
path("get-transaction/", views.TransactionView.as_view(), name="transactions"),
|
||||
|
||||
path("create-stripe-connect/", views.CreateStripeConnectAccount.as_view(), name="stripe_connect"),
|
||||
path("add-bank-details/", views.PrincipalBankAccountCreateAPIView.as_view(), name="add_bank_account"),
|
||||
path('withdrawal-request/', views.WithdrawalRequestCreateAPI.as_view(), name='withdrawal-request-create'),
|
||||
]
|
||||
|
||||
@@ -11,6 +11,7 @@ from goodtimes import services, constants
|
||||
from decimal import Decimal
|
||||
from manage_wallets import models
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from . import serializers
|
||||
from goodtimes.utils import ApiResponse
|
||||
|
||||
@@ -322,3 +323,70 @@ class CreateStripeConnectAccount(APIView):
|
||||
"message": "Link Sent",
|
||||
}
|
||||
return ApiResponse.success(**intent_response)
|
||||
|
||||
|
||||
class PrincipalBankAccountCreateAPIView(APIView):
|
||||
authentication_classes = [JWTAuthentication]
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
serializer = serializers.PrincipalBankAccountSerializer(
|
||||
data=request.data, context={"request": request}
|
||||
)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
intent_response = {
|
||||
"data": serializer.data,
|
||||
"status": status.HTTP_200_OK,
|
||||
"message": constants.SUCCESS,
|
||||
}
|
||||
return ApiResponse.success(**intent_response)
|
||||
exception_response = {
|
||||
"status": status.HTTP_400_BAD_REQUEST,
|
||||
"message": constants.FAILURE,
|
||||
"errors": serializer.errors,
|
||||
}
|
||||
return ApiResponse.error(**exception_response)
|
||||
|
||||
|
||||
class WithdrawalRequestCreateAPI(APIView):
|
||||
authentication_classes = [JWTAuthentication]
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
user = request.user
|
||||
wallet = models.Wallet.objects.filter(principal=user).first()
|
||||
|
||||
# Check if the user has a wallet and sufficient coins
|
||||
if wallet is None or wallet.coins <= 0:
|
||||
return ApiResponse.error(
|
||||
errors="Insufficient balance or no wallet found.",
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
message=constants.FAILURE,
|
||||
)
|
||||
print("Request.DATA: ", request.data)
|
||||
serializer = serializers.WithdrawalRequestSerializer(data=request.data)
|
||||
|
||||
if serializer.is_valid():
|
||||
notes = serializer.validated_data.get("notes") or "No Notes by User"
|
||||
# Save the withdrawal request with notes (either provided or default)
|
||||
serializer.save(
|
||||
principal=user,
|
||||
created_on=timezone.now(),
|
||||
coins=wallet.coins,
|
||||
notes=notes,
|
||||
)
|
||||
# Reset the wallet's coins to 0
|
||||
wallet.coins = 0
|
||||
wallet.save()
|
||||
return ApiResponse.success(
|
||||
data=serializer.data,
|
||||
status=status.HTTP_201_CREATED,
|
||||
message=constants.SUCCESS,
|
||||
)
|
||||
else:
|
||||
return ApiResponse.error(
|
||||
errors=serializer.errors,
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
message=constants.FAILURE,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
# Generated by Django 5.0.2 on 2024-04-04 07:14
|
||||
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("manage_wallets", "0006_stripeconnectaccount"),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="PrincipalBankAccount",
|
||||
fields=[
|
||||
("active", models.BooleanField(default=True)),
|
||||
("deleted", models.BooleanField(default=False)),
|
||||
("created_on", models.DateTimeField(auto_now_add=True)),
|
||||
("modified_on", models.DateTimeField(auto_now=True)),
|
||||
(
|
||||
"id",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid4,
|
||||
editable=False,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
("first_name", models.CharField(max_length=255)),
|
||||
("last_name", models.CharField(max_length=255)),
|
||||
("account_no", models.CharField(max_length=255)),
|
||||
("sort_code", models.CharField(max_length=255)),
|
||||
("is_verified", models.BooleanField(default=False)),
|
||||
(
|
||||
"created_by",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="%(class)s_created",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
(
|
||||
"modified_by",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="%(class)s_modified",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
(
|
||||
"principal",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"db_table": "bank_account",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="WithdrawalRequest",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("active", models.BooleanField(default=True)),
|
||||
("deleted", models.BooleanField(default=False)),
|
||||
("created_on", models.DateTimeField(auto_now_add=True)),
|
||||
("modified_on", models.DateTimeField(auto_now=True)),
|
||||
(
|
||||
"amount",
|
||||
models.DecimalField(decimal_places=2, default=0.0, max_digits=14),
|
||||
),
|
||||
(
|
||||
"ref_image",
|
||||
models.ImageField(blank=True, null=True, upload_to="withdrawal"),
|
||||
),
|
||||
(
|
||||
"ref_id",
|
||||
models.CharField(
|
||||
blank=True, max_length=255, null=True, unique=True
|
||||
),
|
||||
),
|
||||
("notes", models.TextField(blank=True, null=True)),
|
||||
("reply", models.TextField(blank=True, null=True)),
|
||||
(
|
||||
"status",
|
||||
models.CharField(
|
||||
choices=[
|
||||
("submitted", "Submitted"),
|
||||
("review", "Review"),
|
||||
("processing", "Under Process"),
|
||||
("transferred", "Transferred"),
|
||||
("dispute", "Dispute"),
|
||||
("denied", "Denied"),
|
||||
],
|
||||
default="submitted",
|
||||
max_length=20,
|
||||
),
|
||||
),
|
||||
(
|
||||
"created_by",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="%(class)s_created",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
(
|
||||
"modified_by",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="%(class)s_modified",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
(
|
||||
"principal",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="withdrawal_requests",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 5.0.2 on 2024-04-04 09:43
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("manage_wallets", "0007_principalbankaccount_withdrawalrequest"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="withdrawalrequest",
|
||||
name="coin",
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
migrations.AlterModelTable(
|
||||
name="withdrawalrequest",
|
||||
table="withdraw_request",
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.0.2 on 2024-04-04 11:07
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("manage_wallets", "0008_withdrawalrequest_coin_alter_withdrawalrequest_table"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="transaction",
|
||||
old_name="coin",
|
||||
new_name="coins",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="withdrawalrequest",
|
||||
old_name="coin",
|
||||
new_name="coins",
|
||||
),
|
||||
]
|
||||
@@ -1,3 +1,4 @@
|
||||
import uuid
|
||||
from django.db import models
|
||||
from accounts.models import BaseModel, IAmPrincipal, IAmPrincipalType
|
||||
from django.db.models.signals import post_save
|
||||
@@ -72,7 +73,7 @@ class Transaction(BaseModel):
|
||||
default=TransactionStatus.INITIATE,
|
||||
)
|
||||
amount = models.DecimalField(max_digits=14, decimal_places=2, default=0.00)
|
||||
coin = models.IntegerField(default=0)
|
||||
coins = models.IntegerField(default=0)
|
||||
comment = models.CharField(max_length=200, null=True, blank=True)
|
||||
order_id = models.CharField(unique=True, max_length=255, null=True, blank=True)
|
||||
product_id = models.CharField(unique=True, max_length=255, null=True, blank=True)
|
||||
@@ -102,3 +103,49 @@ class StripeConnectAccount(BaseModel):
|
||||
|
||||
def __str__(self):
|
||||
return f"principal: {self.principal}, type: {self.stripe_connect_id}"
|
||||
|
||||
|
||||
class PrincipalBankAccount(BaseModel):
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
principal = models.ForeignKey(IAmPrincipal, on_delete=models.CASCADE)
|
||||
first_name = models.CharField(max_length=255)
|
||||
last_name = models.CharField(max_length=255)
|
||||
account_no = models.CharField(max_length=255)
|
||||
sort_code = models.CharField(max_length=255)
|
||||
is_verified = models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
db_table = "bank_account"
|
||||
|
||||
def __str__(self):
|
||||
return f"principal: {self.principal}, account_no: {self.account_no}"
|
||||
|
||||
|
||||
class WithdrawalRequest(BaseModel):
|
||||
STATUS_CHOICES = [
|
||||
("submitted", "Submitted"),
|
||||
("review", "Review"),
|
||||
("processing", "Under Process"),
|
||||
("transferred", "Transferred"),
|
||||
("dispute", "Dispute"),
|
||||
("denied", "Denied"),
|
||||
]
|
||||
# Update this line to reference IAmPrincipal
|
||||
principal = models.ForeignKey(
|
||||
IAmPrincipal, on_delete=models.CASCADE, related_name="withdrawal_requests"
|
||||
)
|
||||
coins = models.IntegerField(default=0)
|
||||
amount = models.DecimalField(max_digits=14, decimal_places=2, default=0.00)
|
||||
ref_image = models.ImageField(upload_to="withdrawal", null=True, blank=True)
|
||||
ref_id = models.CharField(unique=True, max_length=255, null=True, blank=True)
|
||||
notes = models.TextField(null=True, blank=True)
|
||||
reply = models.TextField(null=True, blank=True)
|
||||
status = models.CharField(
|
||||
max_length=20, choices=STATUS_CHOICES, default="submitted"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "withdraw_request"
|
||||
|
||||
def __str__(self):
|
||||
return f"Withdrawal Request by {self.principal.get_full_name()} on {self.created_on.strftime('%Y-%m-%d')}"
|
||||
|
||||
@@ -4,13 +4,13 @@ from . import views
|
||||
app_name = "manage_wallets"
|
||||
|
||||
urlpatterns = [
|
||||
|
||||
# for manage wallet related url
|
||||
path('wallet/', views.WalletListView.as_view(), name='wallet_list'),
|
||||
|
||||
|
||||
|
||||
path("wallet/", views.WalletListView.as_view(), name="wallet_list"),
|
||||
# for manage payment related url
|
||||
path('payment/', views.PaymentListView.as_view(), name='payment_list'),
|
||||
|
||||
path("payment/", views.PaymentListView.as_view(), name="payment_list"),
|
||||
# for manage account related url
|
||||
path("bank-accounts/", views.BankAccountListView.as_view(), name="account_list"),
|
||||
# for manage withdraw related url
|
||||
path("withdrawals/", views.WithdrawalListView.as_view(), name="withdrawal_list"),
|
||||
path("update-status/", views.StatusUpdateView.as_view(), name="update_status"),
|
||||
]
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import render, redirect
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.urls import reverse_lazy
|
||||
from accounts import resource_action
|
||||
from django.views import generic
|
||||
from .models import Wallet, Transaction
|
||||
from django.contrib import messages
|
||||
from goodtimes import constants
|
||||
from .models import PrincipalBankAccount, Wallet, Transaction, WithdrawalRequest
|
||||
|
||||
"""Wallet Related VIew"""
|
||||
|
||||
@@ -32,3 +35,62 @@ class PaymentListView(LoginRequiredMixin, generic.TemplateView):
|
||||
context["page_name"] = self.page_name
|
||||
context["transaction_objs"] = Transaction.objects.filter(deleted=False)
|
||||
return context
|
||||
|
||||
|
||||
"""Withdrawals Related View"""
|
||||
|
||||
|
||||
class WithdrawalListView(LoginRequiredMixin, generic.TemplateView):
|
||||
page_name = resource_action.RESOURCE_MANAGE_WITHDRAWALS
|
||||
template_name = "manage_wallets/withdrawal_list.html"
|
||||
model = WithdrawalRequest
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["page_name"] = self.page_name
|
||||
context["withdrawal_objs"] = WithdrawalRequest.objects.filter(deleted=False)
|
||||
return context
|
||||
|
||||
|
||||
"""Bank Accounts Related View"""
|
||||
|
||||
|
||||
class BankAccountListView(LoginRequiredMixin, generic.TemplateView):
|
||||
page_name = resource_action.RESOURCE_MANAGE_WITHDRAWALS
|
||||
template_name = "manage_wallets/account_list.html"
|
||||
model = PrincipalBankAccount
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["page_name"] = self.page_name
|
||||
context["account_objs"] = PrincipalBankAccount.objects.filter(deleted=False)
|
||||
return context
|
||||
|
||||
|
||||
class StatusUpdateView(LoginRequiredMixin, generic.View):
|
||||
page_name = resource_action.RESOURCE_MANAGE_WITHDRAWALS
|
||||
model = WithdrawalRequest
|
||||
success_message = constants.DATA_SAVED
|
||||
success_url = reverse_lazy("manage_wallets:withdrawal_list")
|
||||
|
||||
def post(self, request):
|
||||
id = request.POST.get("id")
|
||||
message = request.POST.get("message")
|
||||
status = request.POST.get("status")
|
||||
print("Request.POST: ", request.POST)
|
||||
if id or message:
|
||||
try:
|
||||
instance = self.model.objects.get(id=id)
|
||||
instance.reply = message
|
||||
instance.status = status
|
||||
instance.save()
|
||||
messages.success(request, self.success_message)
|
||||
except self.model.DoesNotExist:
|
||||
messages.error(request, "Contact Us entry not found")
|
||||
except Exception as e:
|
||||
messages.error(request, str(e))
|
||||
else:
|
||||
messages.error(request, "Missing 'id' or 'message' in the request")
|
||||
|
||||
# Redirect to the desired URL after form submission
|
||||
return redirect(self.success_url)
|
||||
|
||||
@@ -106,6 +106,22 @@
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu {% if page_name == resource_context.RESOURCE_MANAGE_BANK_ACCOUNTS %}active{% endif %}">
|
||||
<a href="{% url 'manage_wallets:account_list'%}" aria-expanded="false" class="dropdown-toggle">
|
||||
<div class="">
|
||||
<span class="material-symbols-outlined">currency_rupee</span>
|
||||
<span>Manage Accounts</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu {% if page_name == resource_context.RESOURCE_MANAGE_WITHDRAWALS %}active{% endif %}">
|
||||
<a href="{% url 'manage_wallets:withdrawal_list'%}" aria-expanded="false" class="dropdown-toggle">
|
||||
<div class="">
|
||||
<span class="material-symbols-outlined">currency_rupee</span>
|
||||
<span>Manage Withdrawals</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu {% if page_name == resource_context.RESOURCE_MANAGE_SUBSCRIPTIONS %}active{% endif %}">
|
||||
<a href="{% url 'manage_subscriptions:subscription_list'%}" aria-expanded="false"
|
||||
class="dropdown-toggle">
|
||||
|
||||
@@ -149,10 +149,10 @@
|
||||
{% csrf_token %}
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="id" value="" id="contactUs">
|
||||
{% comment %} <div class="col-12">
|
||||
<label for="subject" class="form-label">Subject</label>
|
||||
<input type="text" class="form-control" name="subject" id="subject">
|
||||
</div> {% endcomment %}
|
||||
<div class="col-12">
|
||||
<label for="status" class="form-label">Status</label>
|
||||
<input type="text" class="form-control" name="status" id="status">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label for="message" class="form-label">Message</label>
|
||||
<textarea id="message" class="form-control" name="message" rows="4" cols="50"></textarea>
|
||||
|
||||
113
templates/manage_wallets/account_list.html
Normal file
113
templates/manage_wallets/account_list.html
Normal file
@@ -0,0 +1,113 @@
|
||||
{% 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 mb-2">
|
||||
<div class="col">
|
||||
<h3>Manage Accounts</h3>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
|
||||
</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 text-center sorting_asc" tabindex="0"
|
||||
aria-controls="style-3" rowspan="1" colspan="1" aria-sort="ascending"
|
||||
aria-label=" Record Id : activate to sort column descending"
|
||||
style="width: 69.2656px;"> UCC 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;">Principal</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;">Principal Type</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;">Account No</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;">First Name</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;">Last Name</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;">Is Verified</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;">Submitted</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for account_obj in account_objs %}
|
||||
<tr role="row">
|
||||
<td class="checkbox-column text-center sorting_1">{{account_obj.id}}</td>
|
||||
|
||||
<td>{{account_obj.principal}}</td>
|
||||
<td>{{account_obj.principal.principal_type}}</td>
|
||||
<td>{{account_obj.account_no}}</td>
|
||||
<td>{{account_obj.first_name}}</td>
|
||||
<td>{{account_obj.last_name}}</td>
|
||||
<td>{{account_obj.is_verified}}</td>
|
||||
<td>{{account_obj.created_on}}</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_",
|
||||
},
|
||||
"order": [[ 7, "desc" ]],
|
||||
"stripeClasses": [],
|
||||
"lengthMenu": [5, 10, 20, 50],
|
||||
"pageLength": 10
|
||||
});
|
||||
|
||||
multiCheck(c3);
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
231
templates/manage_wallets/withdrawal_list.html
Normal file
231
templates/manage_wallets/withdrawal_list.html
Normal file
@@ -0,0 +1,231 @@
|
||||
{% 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" %}
|
||||
{% include "cdn_through_html/animate_cdn_css.html" %}
|
||||
{% include "cdn_through_html/modal_cdn_css.html" %}
|
||||
{% include "cdn_through_html/tabs_cdn_css.html" %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="row layout-top-spacing">
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>Manage Withdrawals</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="">Add Newsletter</a> {% endcomment %}
|
||||
</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="contact-us_wrapper" class="dataTables_wrapper container-fluid dt-bootstrap4 no-footer">
|
||||
<div class="table-responsive">
|
||||
<table id="contact-us" class="table style-3 dt-table-hover dataTable no-footer"
|
||||
role="grid" aria-describedby="style-3_info">
|
||||
<thead>
|
||||
<tr role="row">
|
||||
<th class="text-center" tabindex="0" aria-controls="style-3" rowspan="1"
|
||||
colspan="1" style="width: 69.2656px;"> Record Id </th>
|
||||
<th tabindex="1" aria-controls="style-3" rowspan="1" colspan="1"
|
||||
style="width: 44.2344px;">Principal</th>
|
||||
<th tabindex="2" aria-controls="style-3" rowspan="1" colspan="1"
|
||||
style="width: 79.7969px;">Coins</th>
|
||||
<th tabindex="3" aria-controls="style-3" rowspan="1" colspan="1"
|
||||
style="width: 77.3281px;">Amount</th>
|
||||
<th tabindex="4" aria-controls="style-3" rowspan="1" colspan="1"
|
||||
style="width: 143.516px;">Submitted</th>
|
||||
<th tabindex="5" aria-controls="style-3" rowspan="1" colspan="1"
|
||||
style="width: 98.875px;">Reply / Update</th>
|
||||
<th tabindex="7" aria-controls="style-3" rowspan="1" colspan="1"
|
||||
style="width: 51.625px;">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for withdrawal_obj in withdrawal_objs%}
|
||||
<tr role="row">
|
||||
<td class="text-center"> {{withdrawal_obj.id}} </td>
|
||||
<td>{{withdrawal_obj.principal}}</td>
|
||||
<td>{{withdrawal_obj.coins}}</td>
|
||||
<td>{{withdrawal_obj.amount}}</td>
|
||||
<td>{{withdrawal_obj.created_on}}</td>
|
||||
<td class="text-center">
|
||||
<button type="button" class="btn btn-info mb-2 me-4"
|
||||
data-bs-toggle="modal" data-bs-target="#tabsModalMessageReply"
|
||||
onclick="MessageModal('{{withdrawal_obj.notes}}','{{withdrawal_obj.reply}}')">
|
||||
View
|
||||
</button>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<button type="button" class="btn btn-success mb-2 me-4"
|
||||
data-bs-toggle="modal" data-bs-target="#replyFormModal"
|
||||
onclick="ReplyModal('{{withdrawal_obj.id}}','{{withdrawal_obj.status}}')">
|
||||
Reply
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Message/ reply modal -->
|
||||
<div class="modal fade" id="tabsModalMessageReply" tabindex="-1" role="dialog" aria-labelledby="tabsModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="tabsModalLabel">Message / Reply</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="simple-pill">
|
||||
|
||||
<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="pills-message-tab" data-bs-toggle="pill"
|
||||
data-bs-target="#pills-message" type="button" role="tab" aria-controls="pills-message"
|
||||
aria-selected="true">Message</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="pills-reply-tab" data-bs-toggle="pill"
|
||||
data-bs-target="#pills-reply" type="button" role="tab" aria-controls="pills-reply"
|
||||
aria-selected="false">Reply</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content" id="pills-tabContent">
|
||||
<div class="tab-pane fade show active" id="pills-message" role="tabpanel"
|
||||
aria-labelledby="pills-message-tab" tabindex="0">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<p class="mt-3" id="messageData"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="tab-pane fade" id="pills-reply" role="tabpanel" aria-labelledby="pills-reply-tab"
|
||||
tabindex="0">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<p class="mt-3" id="replyData"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-light-dark" data-bs-dismiss="modal">Discard</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- reply column modal-->
|
||||
<div class="modal fade inputForm-modal" id="replyFormModal" tabindex="-1" role="dialog"
|
||||
aria-labelledby="inputFormModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
|
||||
<div class="modal-header" id="inputFormModalLabel">
|
||||
<h5 class="modal-title">Reply</b></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-hidden="true"></button>
|
||||
</div>
|
||||
<form class="mt-0" method="POST" action="{% url 'manage_wallets:update_status' %}">
|
||||
{% csrf_token %}
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="id" value="" id="contactUs">
|
||||
<div class="col-12">
|
||||
<label for="status">Status</label>
|
||||
<select id="status" name="status" class="form-control">
|
||||
<option value="submitted">Submitted</option>
|
||||
<option value="review">Review</option>
|
||||
<option value="processing">Under Process</option>
|
||||
<option value="transferred">Transferred</option>
|
||||
<option value="dispute">Dispute</option>
|
||||
<option value="denied">Denied</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label for="message" class="form-label">Message</label>
|
||||
<textarea id="message" class="form-control" name="message" rows="4" cols="50"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-2 mb-2 btn-no-effect"
|
||||
data-bs-dismiss="modal">Send</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock content %}
|
||||
|
||||
|
||||
{% block javascript %}
|
||||
<!-- include required js cdn link through html here -->
|
||||
{% include "cdn_through_html/datatable_cdn_js.html" %}
|
||||
|
||||
<script>
|
||||
contact_us = $('#contact-us').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
|
||||
});
|
||||
|
||||
// message modal show and set data
|
||||
function MessageModal(message, reply) {
|
||||
console.log("trigger")
|
||||
// Set the data in the modal content
|
||||
$("#messageData").text(message);
|
||||
$("#replyData").text(reply);
|
||||
|
||||
// Show the modal
|
||||
$('#tabsModalMessageReply').modal('show');
|
||||
}
|
||||
|
||||
// reply modal show and set data
|
||||
function ReplyModal(contact_us_id, status) {
|
||||
console.log("trigger")
|
||||
// Set the data in the modal content
|
||||
$("#contactUs").val(contact_us_id);
|
||||
$("#status").val(status);
|
||||
|
||||
// Show the modal
|
||||
$('#replyFormModal').modal('show');
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user