diff --git a/event_topics/migrations/0001_initial.py b/event_topics/migrations/0001_initial.py deleted file mode 100644 index d8dbe80dfe..0000000000 --- a/event_topics/migrations/0001_initial.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 5.0 on 2023-12-16 06:11 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='EventTopic', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(blank=True, max_length=200, null=True)), - ('slug', models.CharField(max_length=200)), - ('system_image_url', models.URLField(blank=True, null=True)), - ('deleted_at', models.DateTimeField(blank=True, null=True)), - ], - ), - ] diff --git a/event_topics/migrations/0001_initial_squashed_0002_eventsubtopic.py b/event_topics/migrations/0001_initial_squashed_0002_eventsubtopic.py new file mode 100644 index 0000000000..7ff7f718fc --- /dev/null +++ b/event_topics/migrations/0001_initial_squashed_0002_eventsubtopic.py @@ -0,0 +1,34 @@ +# Generated by Django 5.0 on 2024-04-14 17:52 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + replaces = [('event_topics', '0001_initial'), ('event_topics', '0002_eventsubtopic')] + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='EventTopic', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, max_length=200, null=True)), + ('slug', models.CharField(max_length=200)), + ('system_image_url', models.URLField(blank=True, null=True)), + ('deleted_at', models.DateTimeField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name='EventSubTopic', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200, null=True)), + ('slug', models.CharField(max_length=200, null=True)), + ('event_topic_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='event_topics.eventtopic')), + ], + ), + ] diff --git a/event_topics/models.py b/event_topics/models.py index dd828ff748..e509736547 100644 --- a/event_topics/models.py +++ b/event_topics/models.py @@ -10,4 +10,13 @@ class EventTopic(models.Model): deleted_at = models.DateTimeField(null=True, blank=True) def __str__(self): - return self.name + return f"{self.name}" + + +class EventSubTopic(models.Model): + name = models.CharField(max_length=200, null=True) + slug = models.CharField(max_length=200, null=True) + event_topic_id = models.ForeignKey(EventTopic, on_delete=models.CASCADE, null=True) + + def __str__(self): + return f"{self.name}" diff --git a/events/__init__.py b/events/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/events/admin.py b/events/admin.py new file mode 100644 index 0000000000..92ef97e668 --- /dev/null +++ b/events/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin +from .models import Event, EventType, DiscountCode, Group, Exhibitors + +admin.site.register(Event) +admin.site.register(EventType) +admin.site.register(DiscountCode) +admin.site.register(Group) +admin.site.register(Exhibitors) diff --git a/events/apps.py b/events/apps.py new file mode 100644 index 0000000000..8c9099aa7e --- /dev/null +++ b/events/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class EventsConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "events" diff --git a/events/forms.py b/events/forms.py new file mode 100644 index 0000000000..fdc551524c --- /dev/null +++ b/events/forms.py @@ -0,0 +1,21 @@ +from django import forms +from events.models import Exhibitors + + +class ExhibitorForm(forms.ModelForm): + class Meta: + model = Exhibitors + fields = [ + "name", + "description", + "url", + "position", + "event_id" "logo_url", + "banner_url", + "video_url", + "slides_url", + "contact_email", + "contact_link", + "enable_video_room", + "thumbnail_image_url", + ] diff --git a/events/migrations/0001_initial_squashed_0003_exhibitors.py b/events/migrations/0001_initial_squashed_0003_exhibitors.py new file mode 100644 index 0000000000..2953b08b90 --- /dev/null +++ b/events/migrations/0001_initial_squashed_0003_exhibitors.py @@ -0,0 +1,192 @@ +# Generated by Django 5.0 on 2024-04-14 17:58 + +import django.contrib.postgres.fields.citext +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + replaces = [('events', '0001_initial'), ('events', '0002_alter_discountcode_code'), ('events', '0003_exhibitors')] + + dependencies = [ + ('event_topics', '0002_eventsubtopic'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='EventType', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200, null=True)), + ('slug', models.CharField(max_length=200, null=True)), + ('deleted_at', models.DateTimeField(null=True)), + ], + ), + migrations.CreateModel( + name='DiscountCode', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('code', django.contrib.postgres.fields.citext.CITextField(max_length=200, null=True)), + ('value', models.FloatField(null=True)), + ('type', models.CharField(max_length=200, null=True)), + ('is_active', models.BooleanField(null=True)), + ('tickets_number', models.IntegerField(null=True)), + ('min_quantity', models.IntegerField(null=True)), + ('max_quantity', models.IntegerField(null=True)), + ('valid_from', models.DateTimeField(null=True)), + ('valid_till', models.DateTimeField(null=True)), + ('created_at', models.DateTimeField(null=True)), + ('used_for', models.CharField(max_length=200, null=True)), + ('discount_url', models.CharField(max_length=200, null=True)), + ('deleted_at', models.DateTimeField(null=True)), + ('marketer_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Event', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('identifier', models.CharField(max_length=8)), + ('name', models.CharField(max_length=255)), + ('external_event_url', models.URLField(blank=True, null=True)), + ('logo_url', models.URLField(blank=True, null=True)), + ('starts_at', models.DateTimeField()), + ('ends_at', models.DateTimeField()), + ('timezone', models.CharField(default='UTC', max_length=50)), + ('online', models.BooleanField(default=False)), + ('latitude', models.FloatField(blank=True, null=True)), + ('longitude', models.FloatField(blank=True, null=True)), + ('location_name', models.CharField(blank=True, max_length=255, null=True)), + ('searchable_location_name', models.CharField(blank=True, max_length=255, null=True)), + ('public_stream_link', models.CharField(blank=True, max_length=255, null=True)), + ('stream_loop', models.BooleanField(default=False)), + ('stream_autoplay', models.BooleanField(default=False)), + ('is_featured', models.BooleanField(default=False)), + ('is_promoted', models.BooleanField(default=False)), + ('is_demoted', models.BooleanField(default=False)), + ('is_chat_enabled', models.BooleanField(default=False)), + ('is_videoroom_enabled', models.BooleanField(default=False)), + ('is_document_enabled', models.BooleanField(default=False)), + ('document_links', models.JSONField(blank=True, null=True)), + ('chat_room_id', models.CharField(blank=True, max_length=255, null=True)), + ('description', models.TextField(blank=True, null=True)), + ('after_order_message', models.TextField(blank=True, null=True)), + ('original_image_url', models.URLField(blank=True, null=True)), + ('thumbnail_image_url', models.URLField(blank=True, null=True)), + ('large_image_url', models.URLField(blank=True, null=True)), + ('show_remaining_tickets', models.BooleanField(default=False)), + ('icon_image_url', models.URLField(blank=True, null=True)), + ('owner_name', models.CharField(blank=True, max_length=255, null=True)), + ('is_map_shown', models.BooleanField(default=False)), + ('is_oneclick_signup_enabled', models.BooleanField(default=False)), + ('has_owner_info', models.BooleanField(default=False)), + ('owner_description', models.CharField(blank=True, max_length=255, null=True)), + ('is_sessions_speakers_enabled', models.BooleanField(default=False)), + ('is_cfs_enabled', models.BooleanField(default=False)), + ('privacy', models.CharField(default='public', max_length=10)), + ('state', models.CharField(default='draft', max_length=10)), + ('is_announced', models.BooleanField(default=False)), + ('ticket_url', models.CharField(blank=True, max_length=255, null=True)), + ('code_of_conduct', models.CharField(blank=True, max_length=255, null=True)), + ('schedule_published_on', models.DateTimeField(blank=True, null=True)), + ('is_ticketing_enabled', models.BooleanField(default=False)), + ('is_donation_enabled', models.BooleanField(default=False)), + ('is_ticket_form_enabled', models.BooleanField(default=True)), + ('is_badges_enabled', models.BooleanField(default=False)), + ('payment_country', models.CharField(blank=True, max_length=100, null=True)), + ('payment_currency', models.CharField(blank=True, max_length=100, null=True)), + ('paypal_email', models.CharField(blank=True, max_length=255, null=True)), + ('is_tax_enabled', models.BooleanField(default=False)), + ('is_billing_info_mandatory', models.BooleanField(default=False)), + ('can_pay_by_paypal', models.BooleanField(default=False)), + ('can_pay_by_stripe', models.BooleanField(default=False)), + ('can_pay_by_cheque', models.BooleanField(default=False)), + ('can_pay_by_bank', models.BooleanField(default=False)), + ('can_pay_by_invoice', models.BooleanField(default=False)), + ('can_pay_by_onsite', models.BooleanField(default=False)), + ('can_pay_by_omise', models.BooleanField(default=False)), + ('can_pay_by_alipay', models.BooleanField(default=False)), + ('can_pay_by_paytm', models.BooleanField(default=False)), + ('cheque_details', models.CharField(blank=True, max_length=255, null=True)), + ('bank_details', models.CharField(blank=True, max_length=255, null=True)), + ('onsite_details', models.CharField(blank=True, max_length=255, null=True)), + ('invoice_details', models.CharField(blank=True, max_length=255, null=True)), + ('created_at', models.DateTimeField(null=True)), + ('pentabarf_url', models.CharField(blank=True, max_length=255, null=True)), + ('ical_url', models.CharField(blank=True, max_length=255, null=True)), + ('xcal_url', models.CharField(blank=True, max_length=255, null=True)), + ('is_sponsors_enabled', models.BooleanField(default=False)), + ('refund_policy', models.CharField(blank=True, max_length=255, null=True)), + ('is_stripe_linked', models.BooleanField(default=False)), + ('completed_order_sales', models.IntegerField(default=0)), + ('placed_order_sales', models.IntegerField(default=0)), + ('pending_order_sales', models.IntegerField(default=0)), + ('completed_order_tickets', models.IntegerField(default=0)), + ('placed_order_tickets', models.IntegerField(default=0)), + ('pending_order_tickets', models.IntegerField(default=0)), + ('discount_code_id', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='events.discountcode')), + ('event_sub_topic_id', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='event_topics.eventsubtopic')), + ('event_topic_id', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='event_topics.eventtopic')), + ('event_type_id', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='events.eventtype')), + ], + ), + migrations.AddField( + model_name='discountcode', + name='event_id', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='events.event'), + ), + migrations.CreateModel( + name='Group', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200, null=True)), + ('created_at', models.DateTimeField(null=True)), + ('modified_at', models.DateTimeField(null=True)), + ('social_links', models.JSONField(null=True)), + ('about', models.TextField(null=True)), + ('banner_url', models.CharField(max_length=200, null=True)), + ('logo_url', models.CharField(max_length=200, null=True)), + ('deleted_at', models.DateTimeField(null=True)), + ('follower_count', models.IntegerField(default=0)), + ('thumbnail_image_url', models.URLField(blank=True, null=True)), + ('is_promoted', models.BooleanField(default=False)), + ('user_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.AddField( + model_name='event', + name='group_id', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.group'), + ), + migrations.AlterField( + model_name='discountcode', + name='code', + field=models.TextField(max_length=200, null=True), + ), + migrations.CreateModel( + name='Exhibitors', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('modified_at', models.DateTimeField(auto_now=True)), + ('name', models.CharField(max_length=200, null=True)), + ('description', models.CharField(blank=True, max_length=200, null=True)), + ('url', models.CharField(blank=True, max_length=200, null=True)), + ('position', models.IntegerField(default=0)), + ('logo_url', models.CharField(blank=True, max_length=200, null=True)), + ('banner_url', models.CharField(blank=True, max_length=200, null=True)), + ('video_url', models.CharField(blank=True, max_length=200, null=True)), + ('slides_url', models.URLField(blank=True, null=True)), + ('social_links', models.JSONField(blank=True, null=True)), + ('status', models.CharField(blank=True, default='pending', max_length=2147483647, null=True)), + ('contact_email', models.EmailField(blank=True, max_length=254, null=True)), + ('contact_link', models.URLField(blank=True, null=True)), + ('enable_video_room', models.BooleanField(default=False)), + ('thumbnail_image_url', models.URLField(blank=True, null=True)), + ('event', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.event')), + ], + ), + ] diff --git a/events/migrations/__init__.py b/events/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/events/models.py b/events/models.py new file mode 100644 index 0000000000..f987bc7f17 --- /dev/null +++ b/events/models.py @@ -0,0 +1,162 @@ +from django.db import models +from users.models import CustomUser +from event_topics.models import EventTopic, EventSubTopic + + +class EventType(models.Model): + name = models.CharField(max_length=200, null=True) + slug = models.CharField(max_length=200, null=True) + deleted_at = models.DateTimeField(null=True) + + def __str__(self): + return f"{self.name}" + + +class Group(models.Model): + name = models.CharField(max_length=200, null=True) + user_id = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=True) + created_at = models.DateTimeField(null=True) + modified_at = models.DateTimeField(null=True) + social_links = models.JSONField(null=True) + about = models.TextField(null=True) + banner_url = models.CharField(max_length=200, null=True) + logo_url = models.CharField(max_length=200, null=True) + deleted_at = models.DateTimeField(null=True) + follower_count = models.IntegerField(default=0) + thumbnail_image_url = models.URLField(null=True, blank=True) + is_promoted = models.BooleanField(default=False) + + def __str__(self): + return f"{self.name}" + + +class DiscountCode(models.Model): + code = models.TextField(max_length=200, null=True) + value = models.FloatField(null=True) + type = models.CharField(max_length=200, null=True) + is_active = models.BooleanField(null=True) + tickets_number = models.IntegerField(null=True) + min_quantity = models.IntegerField(null=True) + max_quantity = models.IntegerField(null=True) + valid_from = models.DateTimeField(null=True) + valid_till = models.DateTimeField(null=True) + event_id = models.ForeignKey("Event", on_delete=models.CASCADE, null=True) + created_at = models.DateTimeField(null=True) + marketer_id = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=True) + used_for = models.CharField(max_length=200, null=True) + discount_url = models.CharField(max_length=200, null=True) + deleted_at = models.DateTimeField(null=True) + + def __str__(self): + return f"{self.code}" + +class Event(models.Model): + identifier = models.CharField(max_length=8) + name = models.CharField(max_length=255, null=False) + external_event_url = models.URLField(blank=True, null=True) + logo_url = models.URLField(blank=True, null=True) + starts_at = models.DateTimeField(null=False) + ends_at = models.DateTimeField(null=False) + timezone = models.CharField(max_length=50, null=False, default="UTC") + online = models.BooleanField(default=False) + latitude = models.FloatField(blank=True, null=True) + longitude = models.FloatField(blank=True, null=True) + location_name = models.CharField(max_length=255, blank=True, null=True) + searchable_location_name = models.CharField(max_length=255, blank=True, null=True) + public_stream_link = models.CharField(max_length=255, blank=True, null=True) + stream_loop = models.BooleanField(default=False) + stream_autoplay = models.BooleanField(default=False) + is_featured = models.BooleanField(default=False) + is_promoted = models.BooleanField(default=False) + is_demoted = models.BooleanField(default=False) + is_chat_enabled = models.BooleanField(default=False) + is_videoroom_enabled = models.BooleanField(default=False) + is_document_enabled = models.BooleanField(default=False) + document_links = models.JSONField(blank=True, null=True) + chat_room_id = models.CharField(max_length=255, blank=True, null=True) + description = models.TextField(blank=True, null=True) + after_order_message = models.TextField(blank=True, null=True) + original_image_url = models.URLField(blank=True, null=True) + thumbnail_image_url = models.URLField(blank=True, null=True) + large_image_url = models.URLField(blank=True, null=True) + show_remaining_tickets = models.BooleanField(default=False) + icon_image_url = models.URLField(blank=True, null=True) + owner_name = models.CharField(max_length=255, blank=True, null=True) + is_map_shown = models.BooleanField(default=False) + is_oneclick_signup_enabled = models.BooleanField(default=False) + has_owner_info = models.BooleanField(default=False) + owner_description = models.CharField(max_length=255, blank=True, null=True) + is_sessions_speakers_enabled = models.BooleanField(default=False) + is_cfs_enabled = models.BooleanField(default=False) + privacy = models.CharField(max_length=10, default="public") + state = models.CharField(max_length=10, default="draft") + is_announced = models.BooleanField(default=False) + ticket_url = models.CharField(max_length=255, blank=True, null=True) + code_of_conduct = models.CharField(max_length=255, blank=True, null=True) + schedule_published_on = models.DateTimeField(blank=True, null=True) + is_ticketing_enabled = models.BooleanField(default=False) + is_donation_enabled = models.BooleanField(default=False) + is_ticket_form_enabled = models.BooleanField(default=True) + is_badges_enabled = models.BooleanField(default=False) + payment_country = models.CharField(max_length=100, blank=True, null=True) + payment_currency = models.CharField(max_length=100, blank=True, null=True) + paypal_email = models.CharField(max_length=255, blank=True, null=True) + is_tax_enabled = models.BooleanField(default=False) + is_billing_info_mandatory = models.BooleanField(default=False) + can_pay_by_paypal = models.BooleanField(default=False) + can_pay_by_stripe = models.BooleanField(default=False) + can_pay_by_cheque = models.BooleanField(default=False) + can_pay_by_bank = models.BooleanField(default=False) + can_pay_by_invoice = models.BooleanField(default=False) + can_pay_by_onsite = models.BooleanField(default=False) + can_pay_by_omise = models.BooleanField(default=False) + can_pay_by_alipay = models.BooleanField(default=False) + can_pay_by_paytm = models.BooleanField(default=False) + cheque_details = models.CharField(max_length=255, blank=True, null=True) + bank_details = models.CharField(max_length=255, blank=True, null=True) + onsite_details = models.CharField(max_length=255, blank=True, null=True) + invoice_details = models.CharField(max_length=255, blank=True, null=True) + created_at = models.DateTimeField(null=True) + pentabarf_url = models.CharField(max_length=255, blank=True, null=True) + ical_url = models.CharField(max_length=255, blank=True, null=True) + xcal_url = models.CharField(max_length=255, blank=True, null=True) + is_sponsors_enabled = models.BooleanField(default=False) + refund_policy = models.CharField(max_length=255, blank=True, null=True) + is_stripe_linked = models.BooleanField(default=False) + completed_order_sales = models.IntegerField(default=0) + placed_order_sales = models.IntegerField(default=0) + pending_order_sales = models.IntegerField(default=0) + completed_order_tickets = models.IntegerField(default=0) + placed_order_tickets = models.IntegerField(default=0) + pending_order_tickets = models.IntegerField(default=0) + discount_code_id = models.ForeignKey(DiscountCode, on_delete=models.CASCADE, null=True, blank=True) + event_type_id = models.ForeignKey(EventType, on_delete=models.CASCADE, null=True, blank=True) + event_topic_id = models.ForeignKey(EventTopic, on_delete=models.CASCADE, null=True, blank=True) + event_sub_topic_id = models.ForeignKey(EventSubTopic, on_delete=models.CASCADE, null=True, blank=True) + group_id = models.ForeignKey(Group, on_delete=models.SET_NULL, null=True, blank=True) + + def __str__(self): + return f"{self.name}" + + +class Exhibitors(models.Model): + created_at = models.DateTimeField(auto_now_add=True) + modified_at = models.DateTimeField(auto_now=True) + name = models.CharField(max_length=200, null=True) + description = models.CharField(max_length=200, blank=True, null=True) + url = models.CharField(max_length=200, blank=True, null=True) + position = models.IntegerField(default=0) + logo_url = models.CharField(max_length=200, blank=True, null=True) + banner_url = models.CharField(max_length=200, blank=True, null=True) + video_url = models.CharField(max_length=200, blank=True, null=True) + slides_url = models.URLField(null=True, blank=True) + social_links = models.JSONField(null=True, blank=True) + status = models.CharField(max_length=2147483647, null=True, blank=True, default="pending") + contact_email = models.EmailField(null=True, blank=True) + contact_link = models.URLField(null=True, blank=True) + enable_video_room = models.BooleanField(default=False) + thumbnail_image_url = models.URLField(null=True, blank=True) + event = models.ForeignKey(Event, null=True, on_delete=models.SET_NULL) + + def __str__(self): + return f"{self.name}" diff --git a/events/tests.py b/events/tests.py new file mode 100644 index 0000000000..7ce503c2dd --- /dev/null +++ b/events/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/events/views.py b/events/views.py new file mode 100644 index 0000000000..91ea44a218 --- /dev/null +++ b/events/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/open_event_api/settings.py b/open_event_api/settings.py index c164044073..eee93deb09 100644 --- a/open_event_api/settings.py +++ b/open_event_api/settings.py @@ -54,6 +54,7 @@ "event_topics.apps.EventTopicsConfig", "notification_contents.apps.NotificationContentsConfig", "video_channels.apps.VideoChannelsConfig", + "events.apps.EventsConfig", ] MIDDLEWARE = [