notifications 14-03-2024 13:48
This commit is contained in:
@@ -37,6 +37,7 @@ def compute_resource_action_constants():
|
||||
'RESOURCE_MANAGE_CMS': resource_action.RESOURCE_MANAGE_CMS,
|
||||
'RESOURCE_MANAGE_REPORTS': resource_action.RESOURCE_MANAGE_REPORTS,
|
||||
'RESOURCE_MANAGE_SUBSCRIPTIONS': resource_action.RESOURCE_MANAGE_SUBSCRIPTIONS,
|
||||
'RESOURCE_MANAGE_NOTIFICATIONS': resource_action.RESOURCE_MANAGE_NOTIFICATIONS,
|
||||
'RESOURCE_MANAGE_REFERRALS': resource_action.RESOURCE_MANAGE_REFERRALS,
|
||||
'RESOURCE_MANAGE_FEEDBACK': resource_action.RESOURCE_MANAGE_FEEDBACK,
|
||||
'RESOURCE_IAM_PRINCIPAL': resource_action.RESOURCE_IAM_PRINCIPAL,
|
||||
|
||||
@@ -15,7 +15,7 @@ from manage_referrals.models import (
|
||||
ReferralTracking,
|
||||
)
|
||||
from manage_subscriptions.models import PrincipalSubscription, Subscription
|
||||
from manage_wallets.models import TransactionStatus, Wallet, Transaction
|
||||
from manage_wallets.models import TransactionStatus, TransactionType, Wallet, Transaction
|
||||
from goodtimes.utils import CapacityError, RandomGenerator
|
||||
from manage_events.models import (
|
||||
Event,
|
||||
@@ -281,6 +281,16 @@ class PaymentProcessingService:
|
||||
wallet, created = Wallet.objects.get_or_create(principal=referrer_principal)
|
||||
wallet.coins += 1
|
||||
wallet.save()
|
||||
Transaction.objects.create(
|
||||
principal=referrer_principal,
|
||||
transaction_type=TransactionType.CREDIT,
|
||||
payment_method="",
|
||||
transaction_status=TransactionStatus.SUCCESS,
|
||||
amount=0,
|
||||
coin=1,
|
||||
comment="Referral reward",
|
||||
# Populate other fields as necessary, such as `order_id`, `product_id`, or `reference_id` if applicable
|
||||
)
|
||||
|
||||
def _handle_failure(self):
|
||||
# Implement any necessary logic to handle a failed payment
|
||||
|
||||
@@ -64,7 +64,7 @@ LOCAL_APPS = [
|
||||
"manage_referrals",
|
||||
"manage_cms",
|
||||
"manage_communications", # for contact us, and feedback
|
||||
"manage_notifications",
|
||||
"manage_notifications.apps.ManageNotificationsConfig",
|
||||
"chat",
|
||||
]
|
||||
|
||||
|
||||
@@ -54,7 +54,8 @@ urlpatterns = [
|
||||
path("api/subscriptions/", include("manage_subscriptions.api.urls")),
|
||||
|
||||
path("notifications/", include("manage_notifications.urls")),
|
||||
|
||||
path("api/notifications/", include("manage_notifications.api.urls")),
|
||||
|
||||
# path('', include('manage_notifications.urls')),
|
||||
# path('api/', include("accounts.api.urls")),
|
||||
]
|
||||
|
||||
@@ -1,3 +1,32 @@
|
||||
from django.contrib import admin
|
||||
from .models import PushNotification, IAmPrincipalNotificationSettings
|
||||
|
||||
# Register your models here.
|
||||
|
||||
class PushNotificationAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"title",
|
||||
"notification_category",
|
||||
"principal_type",
|
||||
"banner_image",
|
||||
"message",
|
||||
)
|
||||
search_fields = ("title", "notification_category", "principal_type")
|
||||
list_filter = ("notification_category", "principal_type")
|
||||
|
||||
|
||||
admin.site.register(PushNotification, PushNotificationAdmin)
|
||||
|
||||
|
||||
class IAmPrincipalNotificationSettingsAdmin(admin.ModelAdmin):
|
||||
list_display = ("id", "principal", "notification_category", "is_enabled")
|
||||
search_fields = ("principal__first_name", "notification_category")
|
||||
list_filter = ("notification_category", "is_enabled")
|
||||
raw_id_fields = (
|
||||
"principal",
|
||||
) # This is useful if you have many users and a dropdown becomes impractical
|
||||
|
||||
|
||||
admin.site.register(
|
||||
IAmPrincipalNotificationSettings, IAmPrincipalNotificationSettingsAdmin
|
||||
)
|
||||
|
||||
13
manage_notifications/api/serializers.py
Normal file
13
manage_notifications/api/serializers.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from rest_framework import serializers
|
||||
from manage_notifications.models import IAmPrincipalNotificationSettings, NotificationCategoryChoices
|
||||
|
||||
|
||||
class IAmPrincipalNotificationSettingsSerializer(serializers.ModelSerializer):
|
||||
notification_category_display = serializers.SerializerMethodField()
|
||||
|
||||
def get_notification_category_display(self, obj):
|
||||
return obj.get_notification_category_display()
|
||||
|
||||
class Meta:
|
||||
model = IAmPrincipalNotificationSettings
|
||||
fields = ['id', 'notification_category', 'notification_category_display', 'is_enabled']
|
||||
17
manage_notifications/api/urls.py
Normal file
17
manage_notifications/api/urls.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
app_name = "manage_notifications_api"
|
||||
|
||||
urlpatterns = [
|
||||
path(
|
||||
"toggle-notification-setting/",
|
||||
views.NotificationSettingToggle.as_view(),
|
||||
name="toggle-notification-setting",
|
||||
),
|
||||
path(
|
||||
"user-notifications/",
|
||||
views.UserNotificationsAPIView.as_view(),
|
||||
name="user-notifications",
|
||||
),
|
||||
]
|
||||
75
manage_notifications/api/views.py
Normal file
75
manage_notifications/api/views.py
Normal file
@@ -0,0 +1,75 @@
|
||||
from rest_framework import status
|
||||
from rest_framework.views import APIView
|
||||
from django.conf import settings
|
||||
from manage_notifications.api.serializers import (
|
||||
IAmPrincipalNotificationSettingsSerializer,
|
||||
)
|
||||
from manage_notifications.models import (
|
||||
IAmPrincipalNotificationSettings,
|
||||
NotificationCategoryChoices,
|
||||
)
|
||||
from goodtimes import constants
|
||||
from goodtimes.utils import ApiResponse
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework_simplejwt.authentication import JWTAuthentication
|
||||
|
||||
|
||||
class NotificationSettingToggle(APIView):
|
||||
authentication_classes = [JWTAuthentication]
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
notification_category = request.data.get("notification_category")
|
||||
enable = request.data.get("enable", True)
|
||||
|
||||
if (
|
||||
not notification_category
|
||||
or notification_category not in NotificationCategoryChoices.values
|
||||
):
|
||||
return ApiResponse.error(
|
||||
errors="Invalid notification category",
|
||||
message=constants.FAILURE,
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
# Assuming IAmPrincipal model has a user field that relates to Django's User model
|
||||
# You might need to adjust the query depending on your user-principal relationship
|
||||
notification_setting, created = (
|
||||
IAmPrincipalNotificationSettings.objects.get_or_create(
|
||||
principal=request.user,
|
||||
notification_category=notification_category,
|
||||
defaults={"is_enabled": enable},
|
||||
)
|
||||
)
|
||||
|
||||
if not created:
|
||||
notification_setting.is_enabled = enable
|
||||
notification_setting.save()
|
||||
|
||||
return ApiResponse.success(
|
||||
data=f"{notification_category}: { enable}.",
|
||||
message=constants.SUCCESS,
|
||||
status=status.HTTP_200_OK,
|
||||
)
|
||||
|
||||
|
||||
class UserNotificationsAPIView(APIView):
|
||||
authentication_classes = [JWTAuthentication]
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
# Assuming your IAmPrincipal model has a user field linking to the User model
|
||||
principal = request.user
|
||||
notifications = (
|
||||
IAmPrincipalNotificationSettings.objects.filter(principal=principal)
|
||||
.exclude(notification_category=NotificationCategoryChoices.GENERAL)
|
||||
.exclude(notification_category=NotificationCategoryChoices.PROMOTIONS)
|
||||
)
|
||||
serializer = IAmPrincipalNotificationSettingsSerializer(
|
||||
notifications, many=True
|
||||
)
|
||||
return ApiResponse.success(
|
||||
data=serializer.data,
|
||||
message=constants.SUCCESS,
|
||||
status=status.HTTP_200_OK,
|
||||
)
|
||||
@@ -4,3 +4,7 @@ from django.apps import AppConfig
|
||||
class ManageNotificationsConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "manage_notifications"
|
||||
|
||||
def ready(self):
|
||||
# Import signal handlers here
|
||||
from . import signals
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from django import forms
|
||||
from .models import PushNotification, NotificationCategory, PrincipalType
|
||||
from .models import NotificationCategoryChoices, PushNotification
|
||||
|
||||
|
||||
class PushNotificationForm(forms.ModelForm):
|
||||
@@ -15,3 +15,11 @@ class PushNotificationForm(forms.ModelForm):
|
||||
widgets = {
|
||||
"message": forms.Textarea(attrs={"rows": 4}),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PushNotificationForm, self).__init__(*args, **kwargs)
|
||||
# Limit choices for notification_category to GENERAL and PROMOTIONS only
|
||||
self.fields["notification_category"].choices = [
|
||||
(NotificationCategoryChoices.GENERAL, "General"),
|
||||
(NotificationCategoryChoices.PROMOTIONS, "Promotions"),
|
||||
]
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# Generated by Django 5.0.2 on 2024-03-13 19:07
|
||||
|
||||
import django.utils.timezone
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("manage_notifications", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="pushnotification",
|
||||
name="notification_category",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("general", "General"),
|
||||
("transaction", "Transaction"),
|
||||
("referral", "Referral"),
|
||||
("subscription", "Subscription"),
|
||||
("event", "Event"),
|
||||
("promotions", "Promotions"),
|
||||
],
|
||||
max_length=50,
|
||||
),
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="notificationsettings",
|
||||
name="category",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="notificationsettings",
|
||||
name="created_by",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="notificationsettings",
|
||||
name="modified_by",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name="iamprincipalnotificationsettings",
|
||||
name="notification_setting",
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="iamprincipalnotificationsettings",
|
||||
name="notification_category",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("general", "General"),
|
||||
("transaction", "Transaction"),
|
||||
("referral", "Referral"),
|
||||
("subscription", "Subscription"),
|
||||
("event", "Event"),
|
||||
("promotions", "Promotions"),
|
||||
],
|
||||
default=django.utils.timezone.now,
|
||||
max_length=50,
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name="NotificationCategory",
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name="NotificationSettings",
|
||||
),
|
||||
]
|
||||
@@ -1,16 +1,18 @@
|
||||
from django.db import models
|
||||
from accounts.models import BaseModel, IAmPrincipal, IAmPrincipalType
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from manage_wallets.models import Wallet
|
||||
|
||||
|
||||
# Create your models here.
|
||||
class NotificationCategory(BaseModel):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
class Meta:
|
||||
db_table = "notification_settings_category"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"name : {self.name}"
|
||||
class NotificationCategoryChoices(models.TextChoices):
|
||||
GENERAL = "general", "General"
|
||||
TRANSACTION = "transaction", "Transaction"
|
||||
REFERRAL = "referral", "Referral"
|
||||
SUBSCRIPTION = "subscription", "Subscription"
|
||||
EVENT = "event", "Event"
|
||||
PROMOTIONS = "promotions", "Promotions"
|
||||
|
||||
|
||||
class PrincipalType(models.TextChoices):
|
||||
@@ -21,10 +23,9 @@ class PrincipalType(models.TextChoices):
|
||||
|
||||
class PushNotification(BaseModel):
|
||||
title = models.CharField(max_length=255)
|
||||
notification_category = models.ForeignKey(
|
||||
NotificationCategory,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="push_category",
|
||||
notification_category = models.CharField(
|
||||
max_length=50,
|
||||
choices=NotificationCategoryChoices.choices,
|
||||
)
|
||||
banner_image = models.ImageField(
|
||||
upload_to="push_notification_images/", blank=True, null=True
|
||||
@@ -39,27 +40,13 @@ class PushNotification(BaseModel):
|
||||
return self.title
|
||||
|
||||
|
||||
class NotificationSettings(BaseModel):
|
||||
name = models.CharField(max_length=100)
|
||||
category = models.ForeignKey(
|
||||
NotificationCategory,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="notification_category",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "notification_settings"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"name: {self.name}"
|
||||
|
||||
|
||||
class IAmPrincipalNotificationSettings(BaseModel):
|
||||
principal = models.ForeignKey(
|
||||
IAmPrincipal, on_delete=models.CASCADE, related_name="notifications_principal"
|
||||
)
|
||||
notification_setting = models.ForeignKey(
|
||||
NotificationSettings, on_delete=models.CASCADE
|
||||
notification_category = models.CharField(
|
||||
max_length=50,
|
||||
choices=NotificationCategoryChoices.choices,
|
||||
)
|
||||
is_enabled = models.BooleanField(default=True)
|
||||
|
||||
@@ -67,4 +54,4 @@ class IAmPrincipalNotificationSettings(BaseModel):
|
||||
db_table = "iam_principal_notification_settings"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.principal.first_name} - {self.notification_setting.name}"
|
||||
return f"{self.principal.first_name} - {self.notification_category}"
|
||||
|
||||
16
manage_notifications/signals.py
Normal file
16
manage_notifications/signals.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from manage_wallets.models import Wallet
|
||||
from .models import IAmPrincipalNotificationSettings, NotificationCategoryChoices
|
||||
|
||||
@receiver(post_save, sender=Wallet)
|
||||
def create_default_notification_settings(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
principal = instance.principal
|
||||
# Assuming NotificationCategoryChoices is a list of tuples as choices for the field
|
||||
for category in NotificationCategoryChoices:
|
||||
IAmPrincipalNotificationSettings.objects.create(
|
||||
principal=principal,
|
||||
notification_category=category.value, # Assuming category is a tuple and the value is at index 0
|
||||
is_enabled=True
|
||||
)
|
||||
@@ -1,88 +1,69 @@
|
||||
# import requests
|
||||
# from django.conf import settings
|
||||
|
||||
# def onesignal_send_notification(notification):
|
||||
# onesignal_app_id = settings.ONE_SIGNAL_APP_ID
|
||||
# onesignal_rest_api_key = settings.ONE_SIGNAL_API_KEY
|
||||
|
||||
# headers = {
|
||||
# "Content-Type": "application/json; charset=utf-8",
|
||||
# "Authorization": f"Basic {onesignal_rest_api_key}"
|
||||
# }
|
||||
|
||||
# # Determine player IDs based on notification_category and principal_type
|
||||
# player_ids = []
|
||||
|
||||
# if notification.principal_type == PrincipalType.BOTH:
|
||||
# # Get player IDs for both event_user and event_manager
|
||||
# from .models import IAmPrincipal # Assuming your IAmPrincipal model is in the same app
|
||||
|
||||
# event_user_principals = IAmPrincipal.objects.filter(iam_principal_type__name=PrincipalType.EVENT_USER)
|
||||
# event_manager_principals = IAmPrincipal.objects.filter(iam_principal_type__name=PrincipalType.EVENT_MANAGER)
|
||||
|
||||
# for principal in event_user_principals:
|
||||
# # Assuming you have a field in IAmPrincipal that stores the player ID (e.g., 'one_signal_player_id')
|
||||
# player_ids.append(principal.one_signal_player_id)
|
||||
|
||||
# for principal in event_manager_principals:
|
||||
# player_ids.append(principal.one_signal_player_id)
|
||||
|
||||
# else:
|
||||
# # Handle filtering for EVENT_USER or EVENT_MANAGER as needed (similar logic as above)
|
||||
|
||||
# # Construct the notification payload
|
||||
# data = {
|
||||
# "app_id": onesignal_app_id,
|
||||
# "headings": {"en": notification.title},
|
||||
# "contents": {"en": notification.message},
|
||||
# "include_player_ids": player_ids, # Include the filtered player IDs
|
||||
# # Add other optional notification data according to OneSignal documentation
|
||||
# }
|
||||
|
||||
# if notification.banner_image:
|
||||
# # Include image URL if provided (requires additional OneSignal configuration)
|
||||
# data["large_icon"] = notification.banner_image.url # Assuming you have a URL property for the image field
|
||||
|
||||
# # Send the notification request to OneSignal
|
||||
# response = requests.post("https://onesignal.com/api/v1/notifications", headers=headers, json=data)
|
||||
|
||||
# if response.status_code == 200:
|
||||
# print("Notification sent successfully!")
|
||||
# else:
|
||||
# print(f"Error sending notification: {response.text}")
|
||||
|
||||
|
||||
import json
|
||||
import requests
|
||||
from onesignal_sdk.client import Client as OneSignalClient
|
||||
from django.conf import settings
|
||||
from .models import IAmPrincipalNotificationSettings, NotificationSettings, IAmPrincipal
|
||||
from .models import IAmPrincipalNotificationSettings, IAmPrincipal, PrincipalType
|
||||
|
||||
|
||||
def send_notification(notification_type, title, message, image_url=None):
|
||||
def onesignal_send_notification(
|
||||
title, message, image_url="http://127.0.0.1:8000/", eligible_principals=None
|
||||
):
|
||||
onesignal_app_id = settings.ONE_SIGNAL_APP_ID
|
||||
onesignal_rest_api_key = settings.ONE_SIGNAL_API_KEY
|
||||
|
||||
headers = {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"Authorization": f"Basic {onesignal_rest_api_key}",
|
||||
}
|
||||
|
||||
if not eligible_principals:
|
||||
return None # Or handle this scenario as needed
|
||||
|
||||
# Extract OneSignal player IDs
|
||||
# player_ids = eligible_principals.values_list("player_id", flat=True)
|
||||
|
||||
# Construct the notification payload
|
||||
data = {
|
||||
"app_id": onesignal_app_id,
|
||||
"headings": {"en": title},
|
||||
"contents": {"en": message},
|
||||
"include_player_ids": eligible_principals, # Include the filtered player IDs
|
||||
# Add other optional notification data according to OneSignal documentation
|
||||
}
|
||||
|
||||
if image_url:
|
||||
# Include image URL if provided (requires additional OneSignal configuration)
|
||||
data["large_icon"] = (
|
||||
str(image_url.url)
|
||||
)
|
||||
|
||||
# data = json.dumps(data)
|
||||
print("Data: ", data)
|
||||
|
||||
# Send the notification request to OneSignal
|
||||
response = requests.post(
|
||||
"https://onesignal.com/api/v1/notifications", headers=headers, json=data
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
print("Notification sent successfully!")
|
||||
return True # Indicate success
|
||||
else:
|
||||
print(f"Error sending notification: {response.text}")
|
||||
return False # Indicate failure
|
||||
|
||||
|
||||
def send_notification(title, message, image_url=None, eligible_principals=None):
|
||||
# Initialize OneSignal client
|
||||
onesignal_client = OneSignalClient(
|
||||
app_id=settings.ONE_SIGNAL_APP_ID, rest_api_key=settings.ONE_SIGNAL_API_KEY
|
||||
)
|
||||
|
||||
# Find all users who have enabled this type of notification
|
||||
notification_setting = NotificationSettings.objects.filter(
|
||||
name=notification_type
|
||||
).first()
|
||||
if not notification_setting:
|
||||
print("Notification type does not exist.")
|
||||
return
|
||||
|
||||
user_ids = IAmPrincipalNotificationSettings.objects.filter(
|
||||
notification_setting=notification_setting, is_enabled=True
|
||||
).values_list("principal__id", flat=True)
|
||||
|
||||
principals = (
|
||||
IAmPrincipal.objects.filter(id__in=user_ids)
|
||||
.exclude(player_id__isnull=True)
|
||||
.exclude(player_id__exact="")
|
||||
)
|
||||
if not eligible_principals:
|
||||
return None # Or handle this scenario as needed
|
||||
|
||||
# Extract OneSignal player IDs
|
||||
player_ids = principals.values_list("player_id", flat=True)
|
||||
player_ids = eligible_principals.values_list("player_id", flat=True)
|
||||
|
||||
# Prepare notification payload
|
||||
notification_payload = {
|
||||
@@ -99,3 +80,45 @@ def send_notification(notification_type, title, message, image_url=None):
|
||||
print(response.status_code, response.body)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def get_eligible_principals_for_notification(push_notification):
|
||||
principal_type = push_notification.principal_type
|
||||
notification_category = push_notification.notification_category
|
||||
|
||||
if principal_type == PrincipalType.BOTH:
|
||||
# If BOTH is selected, fetch users categorized under both EVENT_USER and EVENT_MANAGER
|
||||
event_user_principals = IAmPrincipal.objects.filter(
|
||||
principal_type__name=PrincipalType.EVENT_USER,
|
||||
notifications_principal__notification_category=notification_category,
|
||||
notifications_principal__is_enabled=True,
|
||||
)
|
||||
|
||||
event_manager_principals = IAmPrincipal.objects.filter(
|
||||
principal_type__name=PrincipalType.EVENT_MANAGER,
|
||||
notifications_principal__notification_category=notification_category,
|
||||
notifications_principal__is_enabled=True,
|
||||
)
|
||||
|
||||
# Combine the QuerySets. Use | operator for OR query (union) and distinct() to avoid duplicates.
|
||||
eligible_principals = (
|
||||
event_user_principals | event_manager_principals
|
||||
).distinct()
|
||||
|
||||
elif principal_type == PrincipalType.EVENT_USER:
|
||||
# Fetch only EVENT_USER principals
|
||||
eligible_principals = IAmPrincipal.objects.filter(
|
||||
principal_type__name=PrincipalType.EVENT_USER,
|
||||
notifications_principal__notification_category=notification_category,
|
||||
notifications_principal__is_enabled=True,
|
||||
)
|
||||
|
||||
elif principal_type == PrincipalType.EVENT_MANAGER:
|
||||
# Fetch only EVENT_MANAGER principals
|
||||
eligible_principals = IAmPrincipal.objects.filter(
|
||||
principal_type__name=PrincipalType.EVENT_MANAGER,
|
||||
notifications_principal__notification_category=notification_category,
|
||||
notifications_principal__is_enabled=True,
|
||||
)
|
||||
|
||||
return eligible_principals
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import json
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse_lazy
|
||||
from django.views import generic
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib import messages
|
||||
from django.core.serializers import serialize
|
||||
from accounts import resource_action
|
||||
from goodtimes import constants
|
||||
from manage_notifications.forms import PushNotificationForm
|
||||
from manage_notifications.models import PushNotification
|
||||
from manage_notifications.utils import (
|
||||
get_eligible_principals_for_notification,
|
||||
onesignal_send_notification,
|
||||
)
|
||||
|
||||
# Create your views here.
|
||||
|
||||
@@ -68,14 +74,43 @@ class PushNotificationsCreateOrUpdateView(LoginRequiredMixin, generic.View):
|
||||
print(form.errors)
|
||||
context = self.get_context_data(form=form)
|
||||
return render(request, self.template_name, context=context)
|
||||
|
||||
push_notification = form.instance
|
||||
eligible_principals = get_eligible_principals_for_notification(
|
||||
push_notification
|
||||
)
|
||||
print("eligible_principals: ", eligible_principals)
|
||||
eligible_principals_json = serialize('json', eligible_principals)
|
||||
eligible_principals_list = json.loads(eligible_principals_json)
|
||||
player_ids = [principal['fields']['player_id'] for principal in eligible_principals_list]
|
||||
# Send notification
|
||||
title = push_notification.title
|
||||
message = push_notification.message
|
||||
image_url = push_notification.banner_image
|
||||
onesignal_send_notification(title, message, image_url, player_ids)
|
||||
print(onesignal_send_notification)
|
||||
# if onesignal_send_notification(
|
||||
# push_notification.title,
|
||||
# push_notification.message,
|
||||
# None,
|
||||
# eligible_principals,
|
||||
# ):
|
||||
# form.save()
|
||||
# messages.success(request, self.get_success_message())
|
||||
# return redirect(self.success_url)
|
||||
# else:
|
||||
# messages.error(request, "Failed to send notification. Form not saved.")
|
||||
# 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())
|
||||
messages.success(request, self.get_success_message())
|
||||
return redirect(self.success_url)
|
||||
|
||||
|
||||
class PushNotificationView(LoginRequiredMixin, generic.ListView):
|
||||
page_name = resource_action.RESOURCE_MANAGE_EVENTS
|
||||
resource = resource_action.RESOURCE_MANAGE_EVENTS
|
||||
page_name = resource_action.RESOURCE_MANAGE_NOTIFICATIONS
|
||||
resource = resource_action.RESOURCE_MANAGE_NOTIFICATIONS
|
||||
action = resource_action.ACTION_READ
|
||||
model = PushNotification
|
||||
template_name = "manage_notifications/notification_list.html"
|
||||
@@ -87,4 +122,4 @@ class PushNotificationView(LoginRequiredMixin, generic.ListView):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["page_name"] = self.page_name
|
||||
return context
|
||||
return context
|
||||
|
||||
@@ -415,7 +415,7 @@ def create_checkout_session(request):
|
||||
transaction = Transaction.objects.create(
|
||||
principal=request.user,
|
||||
principal_subscription=None, # Since the subscription is not created yet
|
||||
transaction_type=TransactionType.DEPOSIT, # or PAYMENT, as applicable
|
||||
transaction_type=TransactionType.PAYMENT, # or PAYMENT, as applicable
|
||||
payment_method=PaymentMethod.CARD, # Assuming CARD for this example
|
||||
transaction_status=TransactionStatus.INITIATE,
|
||||
amount=subscription.amount, # Fetching amount from the Subscription object
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# Generated by Django 5.0.2 on 2024-03-13 19:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("manage_wallets", "0004_alter_wallet_coins"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="transaction",
|
||||
name="coin",
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="transaction",
|
||||
name="payment_method",
|
||||
field=models.CharField(
|
||||
choices=[("card", "Card"), ("upi", "UPI"), ("coin", "Coin")],
|
||||
max_length=10,
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="transaction",
|
||||
name="transaction_type",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("payment", "Payment"),
|
||||
("deposit", "Deposit"),
|
||||
("withdraw", "Withdraw"),
|
||||
("credit", "Credit"),
|
||||
],
|
||||
max_length=10,
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -34,6 +34,7 @@ class TransactionType(models.TextChoices):
|
||||
PAYMENT = "payment", "Payment"
|
||||
DEPOSIT = "deposit", "Deposit"
|
||||
WITHDRAW = "withdraw", "Withdraw"
|
||||
CREDIT = "credit", "Credit"
|
||||
|
||||
|
||||
class TransactionStatus(models.TextChoices):
|
||||
@@ -45,6 +46,7 @@ class TransactionStatus(models.TextChoices):
|
||||
class PaymentMethod(models.TextChoices):
|
||||
CARD = "card", "Card"
|
||||
UPI = "upi", "UPI"
|
||||
COIN = "coin", "Coin"
|
||||
|
||||
|
||||
class Transaction(BaseModel):
|
||||
@@ -70,6 +72,7 @@ class Transaction(BaseModel):
|
||||
default=TransactionStatus.INITIATE,
|
||||
)
|
||||
amount = models.DecimalField(max_digits=14, decimal_places=2, default=0.00)
|
||||
coin = 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)
|
||||
|
||||
@@ -173,15 +173,15 @@
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu">
|
||||
<!-- <li class="menu">
|
||||
<a href="./app-calendar.html" aria-expanded="false" class="dropdown-toggle">
|
||||
<div class="">
|
||||
<span class="material-symbols-outlined">account_circle</span>
|
||||
<span>My Profile</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu">
|
||||
</li> -->
|
||||
<li class="menu {% if page_name == resource_context.RESOURCE_MANAGE_NOTIFICATIONS %}active{% endif %}">
|
||||
<a href="{% url 'manage_notifications:notification_list'%}" aria-expanded="false" class="dropdown-toggle">
|
||||
<div class="">
|
||||
<span class="material-symbols-outlined">notifications</span>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h3>{{operation}} {{page_name}}</h3>
|
||||
<h3>Send Notifications</h3>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<button class="btn btn-dark mb-2 me-4" onclick="history.back()">
|
||||
@@ -30,7 +30,7 @@
|
||||
<div class="statbox widget box box-shadow">
|
||||
<div class="widget-content widget-content-area">
|
||||
|
||||
<form method="POST" novalidate>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{% include 'includes/dynamic_template_form.html' with form=form %}
|
||||
<div class="mt-4 mb-0">
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="col-lg-12">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<h3>Manage Plans</h3>
|
||||
<h3>Manage Notifications</h3>
|
||||
</div>
|
||||
<div class="col-sm-6 text-md-end">
|
||||
<!--
|
||||
@@ -71,7 +71,7 @@
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<ul class="table-controls">
|
||||
<li><a href="{% url 'manage_subscriptions:notification_edit' data_obj.id %}" class="bs-tooltip"
|
||||
<li><a href="{% url 'manage_notifications:notification_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"
|
||||
|
||||
Reference in New Issue
Block a user