Merge pull request #495 from MicroPyramid/new_release

new release
This commit is contained in:
Ashwin Kumar 2023-01-31 23:18:54 +05:30 committed by GitHub
commit cb44710c7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
518 changed files with 60135 additions and 731 deletions

2
.gitignore vendored
View file

@ -24,4 +24,4 @@ media
.sass-cache
server.log
.vscode
static
staticfiles

View file

@ -1,4 +1,5 @@
onCreate:
- sudo rm /etc/apt/sources.list.d/nodesource.list*
- sudo apt-get update -y
- sudo apt install python-is-python3 xvfb libfontconfig wkhtmltopdf libpq-dev python3-dev python3-pip build-essential libssl-dev libffi-dev python3-venv redis-server redis-tools virtualenv zsh python3-virtualenv -y
- |
@ -21,4 +22,4 @@ onStart:
. ../venv/bin/activate
WS_DOMAIN=`cat /home/ubuntu/runcode/ws-url-domain.txt`
printf "\nGO TO THIS URL TO VIEW PAGE \033[4;34m https://8000-${WS_DOMAIN}\033[0;30m\n\n"
python manage.py runserver
python manage.py runserver

View file

@ -18,7 +18,7 @@ This is divided into three parts
- Open below link to create django-crm workspace on [RunCode](https://runcode.io/ "RunCode"). It will cretae django-crm API
[![RunCode](https://runcode-app-public.s3.amazonaws.com/images/dark_btn.png)](https://runcode.io/)
[![RunCode](https://runcode-app-public.s3.amazonaws.com/images/dark_btn.png)](https://runcode.io)
- After running API, Go to Frontend UI [React CRM](https://github.com/MicroPyramid/react-crm "React CRM") project to cretae new workpsace with runcode.
@ -106,7 +106,7 @@ python manage.py runserver
## Start celery worker in another terminal window
celery -A tasks worker --loglevel=INFO
celery -A crm worker --loglevel=INFO
### Useful tools and packages
@ -114,6 +114,7 @@ celery -A tasks worker --loglevel=INFO
pipdeptree # to see pip dependancy tree
black # to format code to meet python coding standards
pip-check -H # to see upgradable packages
isort # to sort imports in python
```
### Community

View file

@ -1,7 +1,7 @@
# Generated by Django 2.1.2 on 2019-01-28 07:07
from django.db import migrations, models
import phonenumber_field.modelfields
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.1.2 on 2019-01-28 07:07
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.1.5 on 2019-02-12 08:04
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.1.7 on 2019-04-30 08:13
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.2.3 on 2019-08-09 11:29
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.2.10 on 2020-04-23 10:20
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2 on 2021-09-13 13:48
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2.7 on 2021-10-06 07:21
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,15 +1,15 @@
import arrow
from django.db import models
from django.utils.translation import pgettext_lazy
from django.utils.translation import gettext_lazy as _
from common.models import Org, Profile
from common.utils import INDCHOICES, COUNTRIES
from phonenumber_field.modelfields import PhoneNumberField
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
from django.utils.translation import pgettext_lazy
from phonenumber_field.modelfields import PhoneNumberField
from common import utils
from common.models import Org, Profile
from common.utils import COUNTRIES, INDCHOICES
from contacts.models import Contact
from teams.models import Teams
from common import utils
class Tags(models.Model):

View file

@ -1,13 +1,11 @@
from rest_framework import serializers
from accounts.models import Account, Email, Tags
from common.serializer import (
ProfileSerializer,
AttachmentsSerializer,
OrganizationSerializer,
)
from common.serializer import (AttachmentsSerializer, OrganizationSerializer,
ProfileSerializer)
from contacts.serializer import ContactSerializer
from leads.serializer import LeadSerializer
from teams.serializer import TeamsSerializer
from contacts.serializer import ContactSerializer
class TagsSerailizer(serializers.ModelSerializer):

View file

@ -4,11 +4,8 @@ from django.test import TestCase
from django.test.utils import override_settings
from accounts.models import Email
from accounts.tasks import (
send_email,
send_email_to_assigned_user,
send_scheduled_emails,
)
from accounts.tasks import (send_email, send_email_to_assigned_user,
send_scheduled_emails)
from accounts.tests import AccountCreateTest

View file

@ -1,4 +1,5 @@
from django.urls import path
from accounts import views
app_name = "api_accounts"

View file

@ -1,46 +1,34 @@
from django.db.models import Q
from accounts.models import Account, Tags
from accounts.tasks import send_email_to_assigned_user, send_email
from accounts import swagger_params
from accounts.serializer import (
AccountSerializer,
AccountCreateSerializer,
)
from common.models import Profile, Attachments, Comment
# from common.custom_auth import JSONWebTokenAuthentication
from common.serializer import (
ProfileSerializer,
CommentSerializer,
AttachmentsSerializer,
)
from common.utils import (
CASE_TYPE,
COUNTRIES,
CURRENCY_CODES,
INDCHOICES,
PRIORITY_CHOICE,
STATUS_CHOICE,
)
from django.shortcuts import get_object_or_404
from contacts.models import Contact
from opportunity.models import SOURCES, STAGES, Opportunity
from cases.serializer import CaseSerializer
from contacts.serializer import ContactSerializer
from tasks.serializer import TaskSerializer
from opportunity.serializer import OpportunitySerializer
from invoices.serializer import InvoiceSerailizer
from accounts.serializer import EmailSerializer, TagsSerailizer
from teams.models import Teams
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.pagination import LimitOffsetPagination
from drf_yasg.utils import swagger_auto_schema
import json
from django.db.models import Q
from django.shortcuts import get_object_or_404
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from accounts import swagger_params
from accounts.models import Account, Tags
from accounts.serializer import (AccountCreateSerializer, AccountSerializer,
EmailSerializer, TagsSerailizer)
from accounts.tasks import send_email, send_email_to_assigned_user
from cases.serializer import CaseSerializer
from common.models import Attachments, Comment, Profile
# from common.custom_auth import JSONWebTokenAuthentication
from common.serializer import (AttachmentsSerializer, CommentSerializer,
ProfileSerializer)
from common.utils import (CASE_TYPE, COUNTRIES, CURRENCY_CODES, INDCHOICES,
PRIORITY_CHOICE, STATUS_CHOICE)
from contacts.models import Contact
from contacts.serializer import ContactSerializer
from invoices.serializer import InvoiceSerailizer
from opportunity.models import SOURCES, STAGES, Opportunity
from opportunity.serializer import OpportunitySerializer
from tasks.serializer import TaskSerializer
from teams.models import Teams
class AccountsListView(APIView, LimitOffsetPagination):
@ -49,11 +37,7 @@ class AccountsListView(APIView, LimitOffsetPagination):
model = Account
def get_context_data(self, **kwargs):
params = (
self.request.query_params
if len(self.request.data) == 0
else self.request.data
)
params = request.post_data
queryset = self.model.objects.filter(org=self.request.org).order_by("-id")
if self.request.profile.role != "ADMIN" and not self.request.profile.is_admin:
queryset = queryset.filter(
@ -130,7 +114,7 @@ class AccountsListView(APIView, LimitOffsetPagination):
tags=["Accounts"], manual_parameters=swagger_params.account_post_params
)
def post(self, request, *args, **kwargs):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
serializer = AccountCreateSerializer(
data=params, request_obj=request, account=True
)
@ -202,7 +186,7 @@ class AccountDetailView(APIView):
tags=["Accounts"], manual_parameters=swagger_params.account_post_params
)
def put(self, request, pk, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
account_object = self.get_object(pk=pk)
if account_object.org != request.org:
return Response(
@ -413,11 +397,7 @@ class AccountDetailView(APIView):
tags=["Accounts"], manual_parameters=swagger_params.account_detail_get_params
)
def post(self, request, pk, **kwargs):
params = (
self.request.query_params
if len(self.request.data) == 0
else self.request.data
)
params = request.post_data
context = {}
self.account_obj = Account.objects.get(pk=pk)
if self.account_obj.org != request.org:
@ -484,7 +464,7 @@ class AccountCommentView(APIView):
tags=["Accounts"], manual_parameters=swagger_params.account_comment_edit_params
)
def put(self, request, pk, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
obj = self.get_object(pk)
if (
request.profile.role == "ADMIN"
@ -574,7 +554,7 @@ class AccountCreateMailView(APIView):
tags=["Accounts"], manual_parameters=swagger_params.account_mail_params
)
def post(self, request, pk, *args, **kwargs):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
scheduled_later = params.get("scheduled_later")
scheduled_date_time = params.get("scheduled_date_time")
account = Account.objects.filter(id=pk).first()

View file

@ -1,7 +1,7 @@
# Generated by Django 2.1.2 on 2019-01-28 07:07
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.1.2 on 2019-01-28 07:07
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.1.5 on 2019-02-12 08:04
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.2.10 on 2020-04-27 12:13
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.1.7 on 2021-03-23 12:17
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2 on 2021-09-13 13:48
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2.7 on 2021-10-06 07:21
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,12 +1,13 @@
import arrow
from django.db import models
from django.utils.translation import pgettext_lazy
from django.utils.translation import gettext_lazy as _
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.utils.translation import pgettext_lazy
from accounts.models import Account
from contacts.models import Contact
from common.models import Org, Profile
from common.utils import CASE_TYPE, PRIORITY_CHOICE, STATUS_CHOICE
from contacts.models import Contact
from planner.models import Event
from teams.models import Teams

View file

@ -1,9 +1,10 @@
from rest_framework import serializers
from cases.models import Case
from common.serializer import ProfileSerializer, OrganizationSerializer
from teams.serializer import TeamsSerializer
from accounts.serializer import AccountSerializer
from cases.models import Case
from common.serializer import OrganizationSerializer, ProfileSerializer
from contacts.serializer import ContactSerializer
from teams.serializer import TeamsSerializer
class CaseSerializer(serializers.ModelSerializer):

View file

@ -1,4 +1,5 @@
from django.urls import path
from cases import views
app_name = "api_cases"

View file

@ -1,38 +1,27 @@
from django.db.models import Q
import json
from django.db.models import Q
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from cases.models import Case
from cases.tasks import send_email_to_assigned_user
from cases import swagger_params
from cases.serializer import (
CaseSerializer,
CaseCreateSerializer,
)
from accounts.models import Account
from accounts.serializer import AccountSerializer
from cases import swagger_params
from cases.models import Case
from cases.serializer import CaseCreateSerializer, CaseSerializer
from cases.tasks import send_email_to_assigned_user
from common.models import Attachments, Comment, Profile
# from common.custom_auth import JSONWebTokenAuthentication
from common.serializer import (
CommentSerializer,
AttachmentsSerializer,
)
from common.utils import (
STATUS_CHOICE,
PRIORITY_CHOICE,
CASE_TYPE,
)
from common.serializer import AttachmentsSerializer, CommentSerializer
from common.utils import CASE_TYPE, PRIORITY_CHOICE, STATUS_CHOICE
from contacts.models import Contact
from contacts.serializer import ContactSerializer
from teams.models import Teams
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.pagination import LimitOffsetPagination
from drf_yasg.utils import swagger_auto_schema
import json
class CaseListView(APIView, LimitOffsetPagination):
@ -41,11 +30,7 @@ class CaseListView(APIView, LimitOffsetPagination):
model = Case
def get_context_data(self, **kwargs):
params = (
self.request.query_params
if len(self.request.data) == 0
else self.request.data
)
params = request.post_data
queryset = self.model.objects.filter(org=self.request.org).order_by("-id")
accounts = Account.objects.filter(org=self.request.org).order_by("-id")
contacts = Contact.objects.filter(org=self.request.org).order_by("-id")
@ -108,7 +93,7 @@ class CaseListView(APIView, LimitOffsetPagination):
tags=["Cases"], manual_parameters=swagger_params.cases_create_post_params
)
def post(self, request, *args, **kwargs):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
serializer = CaseCreateSerializer(data=params, request_obj=request)
if serializer.is_valid():
cases_obj = serializer.save(
@ -174,7 +159,7 @@ class CaseDetailView(APIView):
tags=["Cases"], manual_parameters=swagger_params.cases_create_post_params
)
def put(self, request, pk, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
cases_object = self.get_object(pk=pk)
if cases_object.org != request.org:
return Response(
@ -351,11 +336,7 @@ class CaseDetailView(APIView):
tags=["Cases"], manual_parameters=swagger_params.cases_detail_get_params
)
def post(self, request, pk, **kwargs):
params = (
self.request.query_params
if len(self.request.data) == 0
else self.request.data
)
params = request.post_data
self.cases_obj = Case.objects.get(pk=pk)
if self.cases_obj.org != request.org:
return Response(
@ -416,7 +397,7 @@ class CaseCommentView(APIView):
tags=["Cases"], manual_parameters=swagger_params.cases_comment_edit_params
)
def put(self, request, pk, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
obj = self.get_object(pk)
if (
request.profile.role == "ADMIN"

0
cms/__init__.py Normal file
View file

3
cms/admin.py Normal file
View file

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
cms/apps.py Normal file
View file

@ -0,0 +1,6 @@
from django.apps import AppConfig
class CmsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'cms'

221
cms/blocks.py Normal file
View file

@ -0,0 +1,221 @@
from django.db import models
from modelcluster.models import ClusterableModel
from wagtail.blocks import CharBlock, ListBlock, RichTextBlock, TextBlock
from wagtail.core import blocks
from wagtail.core.blocks import StructBlock
from wagtail.core.models import Orderable
from wagtail.fields import RichTextField
from wagtail.images.blocks import ImageChooserBlock
from wagtail.snippets.blocks import SnippetChooserBlock
from wagtail.snippets.models import register_snippet
class RightImageLeftText(blocks.StructBlock):
heading = blocks.CharBlock(required=False)
paragraph = blocks.RichTextBlock(required=False)
image = ImageChooserBlock()
links = blocks.ListBlock(
blocks.StructBlock(
[
("cta_url", blocks.URLBlock(required=False)),
("cta_page", blocks.PageChooserBlock(required=False)),
(
"cta_text",
blocks.CharBlock(required=False, default="Submit", max_length="50"),
),
("cta_image", ImageChooserBlock(required=False)),
]
)
)
class Meta:
template = "cms/streams/right_image_left_content.html"
icon = "image"
label = "Right Image Left Content"
class AboutApp(blocks.StructBlock):
heading = blocks.CharBlock(required=False)
paragraph = blocks.RichTextBlock(required=False)
image = ImageChooserBlock()
sub_heading = blocks.CharBlock(required=False)
sub_paragraph = blocks.RichTextBlock(required=False)
cta_url = blocks.URLBlock(required=False)
cta_page = blocks.PageChooserBlock(required=False)
cta_text = blocks.CharBlock(required=False, default="Submit", max_length="50")
links = blocks.ListBlock(
blocks.StructBlock(
[
("text", blocks.CharBlock(required=False)),
]
)
)
class Meta:
template = "cms/streams/aboutapp.html"
icon = "image"
label = "About App"
class Count(blocks.StructBlock):
links = blocks.ListBlock(
blocks.StructBlock(
[
("count", blocks.CharBlock(required=False, default=85)),
("count_value", blocks.CharBlock(required=False)),
("text", blocks.CharBlock(required=False)),
]
)
)
class Meta:
template = "cms/streams/count.html"
icon = "image"
label = "Count"
class AppFeatures(blocks.StructBlock):
heading = blocks.CharBlock(required=False)
description = blocks.RichTextBlock(required=False)
cards = blocks.ListBlock(
blocks.StructBlock(
[
("icon", blocks.CharBlock(required=False)),
("card_heading", blocks.CharBlock(required=False)),
("card_description", blocks.CharBlock(required=False)),
]
)
)
class Meta:
template = "cms/streams/app_features.html"
icon = "image"
label = "App Features"
class Pricing(blocks.StructBlock):
heading = blocks.CharBlock(required=False)
description = blocks.RichTextBlock(required=False)
cards = blocks.ListBlock(
blocks.StructBlock(
[
("card_heading", blocks.CharBlock(required=False)),
("card_price", blocks.CharBlock(required=False)),
("card_description", blocks.RichTextBlock(required=False)),
("cta_url", blocks.URLBlock(required=False)),
("cta_page", blocks.PageChooserBlock(required=False)),
(
"cta_text",
blocks.CharBlock(
required=False, default="Choose Plan", max_length="50"
),
),
]
)
)
class Meta:
template = "cms/streams/pricing.html"
icon = "image"
label = "Pricing"
class Carousel(blocks.StructBlock):
sliders = blocks.ListBlock(
blocks.StructBlock(
[
("description", blocks.RichTextBlock(required=False)),
("image", ImageChooserBlock()),
("author", blocks.CharBlock(required=False)),
("role", blocks.CharBlock(required=False)),
]
)
)
class Meta:
template = "cms/streams/carousel.html"
icon = "image"
label = "Carousel"
class LeftImageRightText(blocks.StructBlock):
heading = blocks.CharBlock(required=False)
paragraph = blocks.RichTextBlock(required=False)
image = ImageChooserBlock()
links = blocks.ListBlock(
blocks.StructBlock(
[
("cta_url", blocks.URLBlock(required=False)),
("cta_page", blocks.PageChooserBlock(required=False)),
(
"cta_text",
blocks.CharBlock(required=False, default="Submit", max_length="50"),
),
("cta_image", ImageChooserBlock(required=False)),
]
)
)
class Meta:
template = "cms/streams/left_image_right_content.html"
icon = "image"
label = "Left Image Right Content"
class HomeBlog(blocks.StructBlock):
heading = blocks.CharBlock(required=False)
description = blocks.RichTextBlock(required=False)
cards = blocks.ListBlock(
blocks.StructBlock(
[
("image", ImageChooserBlock()),
("blog_tag", blocks.CharBlock(required=False)),
("blog_heading", blocks.CharBlock(required=False)),
("cta_url", blocks.URLBlock(required=False)),
("cta_page", blocks.PageChooserBlock(required=False)),
(
"cta_text",
blocks.CharBlock(
required=False, default="Read More", max_length="50"
),
),
]
)
)
class Meta:
template = "cms/streams/home_blog.html"
icon = "image"
label = "Home Blog"
class BlogContentTitleBlock(CharBlock):
title = CharBlock(required=True, help_text="add your title")
class Meta:
template = "cms/streams/blog/content_title.html"
label = "Content Title"
class BlogCodeBlock(TextBlock):
code = CharBlock(required=True, help_text="add your title")
class Meta:
template = "cms/streams/blog/code_block.html"
label = "Code Block"
class BlogRichTextBlock(RichTextBlock):
text = CharBlock(required=True, help_text="add your title")
class Meta:
template = "cms/streams/blog/rich_text.html"
label = "Rich Text"
class BlogImageBlock(ImageChooserBlock):
image = ImageChooserBlock(required=True, help_text="add your title")
class Meta:
template = "cms/streams/blog/image.html"
label = "Image"

View file

@ -0,0 +1,91 @@
# Generated by Django 4.1.1 on 2022-10-11 12:11
import django.db.models.deletion
import django_extensions.db.fields
import modelcluster.fields
import wagtail.blocks
import wagtail.fields
import wagtail.images.blocks
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('wagtailcore', '0077_alter_revision_user'),
('wagtailimages', '0024_index_image_file_hash'),
]
operations = [
migrations.CreateModel(
name='HomePage',
fields=[
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
('content', wagtail.fields.StreamField([('right_image_left_content', wagtail.blocks.StructBlock([('heading', wagtail.blocks.CharBlock(required=False)), ('paragraph', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock()), ('links', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('cta_url', wagtail.blocks.URLBlock(required=False)), ('cta_page', wagtail.blocks.PageChooserBlock(required=False)), ('cta_text', wagtail.blocks.CharBlock(default='Submit', max_length='50', required=False)), ('cta_image', wagtail.images.blocks.ImageChooserBlock(required=False))])))])), ('aboutapp', wagtail.blocks.StructBlock([('heading', wagtail.blocks.CharBlock(required=False)), ('paragraph', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock()), ('sub_heading', wagtail.blocks.CharBlock(required=False)), ('sub_paragraph', wagtail.blocks.RichTextBlock(required=False)), ('cta_url', wagtail.blocks.URLBlock(required=False)), ('cta_page', wagtail.blocks.PageChooserBlock(required=False)), ('cta_text', wagtail.blocks.CharBlock(default='Submit', max_length='50', required=False)), ('links', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('text', wagtail.blocks.CharBlock(required=False))])))])), ('count', wagtail.blocks.StructBlock([('links', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('count', wagtail.blocks.CharBlock(default=85, required=False)), ('count_value', wagtail.blocks.CharBlock(required=False)), ('text', wagtail.blocks.CharBlock(required=False))])))])), ('appfeatures', wagtail.blocks.StructBlock([('heading', wagtail.blocks.CharBlock(required=False)), ('description', wagtail.blocks.RichTextBlock(required=False)), ('cards', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('icon', wagtail.blocks.CharBlock(required=False)), ('card_heading', wagtail.blocks.CharBlock(required=False)), ('card_description', wagtail.blocks.CharBlock(required=False))])))])), ('pricing', wagtail.blocks.StructBlock([('heading', wagtail.blocks.CharBlock(required=False)), ('description', wagtail.blocks.RichTextBlock(required=False)), ('cards', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('card_heading', wagtail.blocks.CharBlock(required=False)), ('card_price', wagtail.blocks.CharBlock(required=False)), ('card_description', wagtail.blocks.RichTextBlock(required=False)), ('cta_url', wagtail.blocks.URLBlock(required=False)), ('cta_page', wagtail.blocks.PageChooserBlock(required=False)), ('cta_text', wagtail.blocks.CharBlock(default='Choose Plan', max_length='50', required=False))])))])), ('carousel', wagtail.blocks.StructBlock([('sliders', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('description', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock()), ('author', wagtail.blocks.CharBlock(required=False)), ('role', wagtail.blocks.CharBlock(required=False))])))])), ('leftimagerighttext', wagtail.blocks.StructBlock([('heading', wagtail.blocks.CharBlock(required=False)), ('paragraph', wagtail.blocks.RichTextBlock(required=False)), ('image', wagtail.images.blocks.ImageChooserBlock()), ('links', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('cta_url', wagtail.blocks.URLBlock(required=False)), ('cta_page', wagtail.blocks.PageChooserBlock(required=False)), ('cta_text', wagtail.blocks.CharBlock(default='Submit', max_length='50', required=False)), ('cta_image', wagtail.images.blocks.ImageChooserBlock(required=False))])))])), ('homeblog', wagtail.blocks.StructBlock([('heading', wagtail.blocks.CharBlock(required=False)), ('description', wagtail.blocks.RichTextBlock(required=False)), ('cards', wagtail.blocks.ListBlock(wagtail.blocks.StructBlock([('image', wagtail.images.blocks.ImageChooserBlock()), ('blog_tag', wagtail.blocks.CharBlock(required=False)), ('blog_heading', wagtail.blocks.CharBlock(required=False)), ('cta_url', wagtail.blocks.URLBlock(required=False)), ('cta_page', wagtail.blocks.PageChooserBlock(required=False)), ('cta_text', wagtail.blocks.CharBlock(default='Read More', max_length='50', required=False))])))]))], null=True, use_json_field=True)),
],
options={
'abstract': False,
},
bases=('wagtailcore.page',),
),
migrations.CreateModel(
name='Menu',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100, verbose_name='link_title')),
('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MenuItem',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
('link_title', models.CharField(blank=True, max_length=50, null=True, verbose_name='link_title')),
('link_url', models.CharField(blank=True, max_length=500)),
('open_in_new_tab', models.BooleanField(blank=True, default=False)),
('link_page', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.page')),
('page', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='menu_items', to='cms.menu')),
],
options={
'ordering': ['sort_order'],
'abstract': False,
},
),
migrations.CreateModel(
name='SubMenuItem',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
('link_title', models.CharField(blank=True, max_length=50, null=True, verbose_name='link_title')),
('link_url', models.CharField(blank=True, max_length=500)),
('open_in_new_tab', models.BooleanField(blank=True, default=False)),
('link_page', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.page')),
('page', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='sub_menu_items', to='cms.menuitem')),
],
options={
'ordering': ['sort_order'],
'abstract': False,
},
),
migrations.CreateModel(
name='SiteSettings',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('github', models.URLField(blank=True, help_text='Github URL', null=True)),
('twitter', models.URLField(blank=True, help_text='Twitter URL', null=True)),
('linkedin', models.URLField(blank=True, help_text='linkedin URL', null=True)),
('sitemap', models.URLField(blank=True, help_text='Sitemap rss.xml', null=True)),
('logo', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image')),
('site', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, to='wagtailcore.site')),
],
options={
'abstract': False,
},
),
]

View file

@ -0,0 +1,41 @@
# Generated by Django 4.1.1 on 2022-10-31 06:50
from django.db import migrations, models
import django.db.models.deletion
import wagtail.contrib.routable_page.models
import wagtail.fields
class Migration(migrations.Migration):
dependencies = [
('wagtailcore', '0077_alter_revision_user'),
('cms', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='BlogDetailPage',
fields=[
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
('excerpt', wagtail.fields.RichTextField()),
('show_legend', models.BooleanField(default=False)),
('content', wagtail.fields.StreamField([], use_json_field=None)),
],
options={
'abstract': False,
},
bases=('wagtailcore.page',),
),
migrations.CreateModel(
name='BlogListPage',
fields=[
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
('intro', wagtail.fields.RichTextField(blank=True)),
],
options={
'abstract': False,
},
bases=(wagtail.contrib.routable_page.models.RoutablePageMixin, 'wagtailcore.page'),
),
]

View file

@ -0,0 +1,24 @@
# Generated by Django 4.1.1 on 2022-10-31 09:01
import cms.blocks
from django.db import migrations
import wagtail.fields
class Migration(migrations.Migration):
dependencies = [
('cms', '0002_blogdetailpage_bloglistpage'),
]
operations = [
migrations.RemoveField(
model_name='blogdetailpage',
name='show_legend',
),
migrations.AlterField(
model_name='blogdetailpage',
name='content',
field=wagtail.fields.StreamField([('content_title', cms.blocks.BlogContentTitleBlock()), ('code', cms.blocks.BlogCodeBlock()), ('rich_text', cms.blocks.BlogRichTextBlock()), ('image', cms.blocks.BlogImageBlock())], use_json_field=None),
),
]

View file

293
cms/models.py Normal file
View file

@ -0,0 +1,293 @@
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db import models
from django.utils.translation import gettext_lazy as _
from django_extensions.db.fields import AutoSlugField
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
from wagtail.admin.edit_handlers import (FieldPanel, InlinePanel,
MultiFieldPanel, PageChooserPanel)
from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
from wagtail.core import blocks
from wagtail.core.fields import StreamField
from wagtail.core.models import Orderable, Page
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.snippets.models import register_snippet
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
from wagtail.fields import RichTextField
from django.shortcuts import render
from cms import blocks
class HomePage(Page):
content = StreamField(
[
("right_image_left_content", blocks.RightImageLeftText()),
("aboutapp", blocks.AboutApp()),
("count", blocks.Count()),
("appfeatures", blocks.AppFeatures()),
("pricing", blocks.Pricing()),
("carousel", blocks.Carousel()),
("leftimagerighttext", blocks.LeftImageRightText()),
("homeblog", blocks.HomeBlog()),
],
null=True,
blank=False,
use_json_field=True,
)
content_panels = Page.content_panels + [FieldPanel("content")]
# class BlogCategory(models.Model):
# name = models.CharField(max_length=255)
# slug = models.SlugField(max_length=255)
# def __str__(self):
# return self.name
# panels = [FieldPanel("name"), FieldPanel("slug")]
# class Meta:
# ordering = ["name"]
# register_snippet(BlogCategory)
class BlogListPage(RoutablePageMixin, Page):
template = "cms/blog/blog_list_page.html"
max_count = 1
intro = RichTextField(blank=True)
@route(r"^(?P<page_num>\d+)")
def get_context(self, request, *args, **kwargs):
# Update context to include only published posts, ordered by reverse-chron
# request.session.clear()
context = super().get_context(request, *args, **kwargs)
all_posts = (
BlogDetailPage.objects.live().public().order_by("-first_published_at")
)
paginator = Paginator(all_posts, 1)
page = int(kwargs.get("page_num", 1))
try:
posts = paginator.page(page)
except PageNotAnInteger:
posts = paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_pages)
# context["category_count"] = BlogCategory.objects.annotate(
# num_posts=Count("blogdetailpage")
# )
context["posts"] = posts
# context["categories"] = BlogCategory.objects.all()
if kwargs.get("page_num"):
return render(request, "cms/blog/blog_list_page.html", context)
else:
return context
# @route(r"^category/(?P<cat_slug>[-\w]*)/$", name="category_view")
# def category_view(self, request, cat_slug):
# context = self.get_context(request)
# category = BlogCategory.objects.get(slug=cat_slug)
# category_posts = (
# BlogDetailPage.objects.live().public().filter(category=category)
# )
# paginator = Paginator(category_posts, 10)
# # page = int(kwargs.get('page_num', 1))
# page = 1
# try:
# category_posts = paginator.page(page)
# except PageNotAnInteger:
# category_posts = paginator.page(1)
# except EmptyPage:
# category_posts = paginator.page(paginator.num_pages)
# context["category_posts"] = category_posts
# context["current_category"] = category
# return render(request, "blog/blog_category.html", context)
# content_panels = Page.content_panels + [
# FieldPanel("intro", classname="full"),
# ]
class BlogDetailPage(Page):
template = "cms/blog/blog_detail_page.html"
excerpt = RichTextField()
# show_legend = models.BooleanField(default=False)
# category = models.ForeignKey(BlogCategory, null=True, on_delete=models.SET_NULL)
content = StreamField(
[
("content_title", blocks.BlogContentTitleBlock()),
("code", blocks.BlogCodeBlock()),
("rich_text", blocks.BlogRichTextBlock()),
("image", blocks.BlogImageBlock()),
],
null=True,
blank=False,
use_json_field=True,
)
content_panels = Page.content_panels + [
# FieldPanel("category"),
# FieldPanel("show_legend"),
FieldPanel("excerpt"),
FieldPanel("content"),
]
# ============================ Navigation Menu ===============================================
@register_snippet
class Menu(ClusterableModel):
"""The main menu clusterable model."""
title = models.CharField(_("link_title"), max_length=100)
slug = AutoSlugField(populate_from="title", editable=True)
panels = [
MultiFieldPanel(
[
FieldPanel("title"),
FieldPanel("slug"),
],
heading="Menu",
),
InlinePanel("menu_items", label="Menu Item"),
]
def __str__(self):
return self.title
class MenuItem(Orderable, ClusterableModel):
"""The First level menu of the Navigationbar."""
link_title = models.CharField(_("link_title"), blank=True, null=True, max_length=50)
link_url = models.CharField(max_length=500, blank=True)
link_page = models.ForeignKey(
"wagtailcore.Page",
null=True,
blank=True,
related_name="+",
on_delete=models.CASCADE,
)
open_in_new_tab = models.BooleanField(default=False, blank=True)
page = ParentalKey("Menu", related_name="menu_items")
panels = [
MultiFieldPanel(
[
FieldPanel("link_title"),
FieldPanel("link_url"),
PageChooserPanel("link_page"),
FieldPanel("open_in_new_tab"),
],
heading="MenuItem",
),
InlinePanel("sub_menu_items", label="Sub Menu Item"),
]
@property
def link(self):
if self.link_page:
return self.link_page.url
elif self.link_url:
return self.link_url
return "#"
@property
def title(self):
if self.link_page and not self.link_title:
return self.link_page.title
elif self.link_title:
return self.link_title
return "Missing Title"
class SubMenuItem(Orderable):
"""The Second level menu of the Navigationbar."""
link_title = models.CharField(_("link_title"), blank=True, null=True, max_length=50)
link_url = models.CharField(max_length=500, blank=True)
link_page = models.ForeignKey(
"wagtailcore.Page",
null=True,
blank=True,
related_name="+",
on_delete=models.CASCADE,
)
open_in_new_tab = models.BooleanField(default=False, blank=True)
page = ParentalKey("MenuItem", related_name="sub_menu_items")
panels = [
MultiFieldPanel(
[
FieldPanel("link_title"),
FieldPanel("link_url"),
PageChooserPanel("link_page"),
FieldPanel("open_in_new_tab"),
],
heading="SubMenuItem",
),
]
@property
def link(self):
if self.link_page:
return self.link_page.url
elif self.link_url:
return self.link_url
return "#"
@property
def title(self):
if self.link_page and not self.link_title:
return self.link_page.title
elif self.link_title:
return self.link_title
return "Missing Title"
@register_setting
class SiteSettings(BaseSiteSetting):
"""Site settings for our custom website."""
logo = models.ForeignKey(
"wagtailimages.Image",
null=True,
blank=True,
default=None,
on_delete=models.SET_NULL,
related_name="+",
)
github = models.URLField(blank=True, null=True, help_text="Github URL")
twitter = models.URLField(blank=True, null=True, help_text="Twitter URL")
linkedin = models.URLField(blank=True, null=True, help_text="linkedin URL")
sitemap = models.URLField(blank=True, null=True, help_text="Sitemap rss.xml")
panels = [
MultiFieldPanel(
[
FieldPanel("github"),
FieldPanel("twitter"),
FieldPanel("linkedin"),
FieldPanel("sitemap"),
FieldPanel("logo"),
],
heading="Site Settings",
)
]

View file

@ -0,0 +1,10 @@
from django import template
from ..models import Menu
register = template.Library()
@register.simple_tag()
def get_menu(slug):
return Menu.objects.get(slug=slug)

3
cms/tests.py Normal file
View file

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
cms/views.py Normal file
View file

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

View file

@ -1,5 +1,6 @@
from django.contrib import admin
from common.models import User, Address, Comment, Comment_Files
from common.models import Address, Comment, Comment_Files, User
# Register your models here.

View file

@ -1,10 +1,11 @@
from rest_framework.response import Response
from rest_framework import status
from django.contrib.auth import logout
from common.models import Org, Profile, User
from django.conf import settings
from django.core.exceptions import ValidationError
import jwt
from django.conf import settings
from django.contrib.auth import logout
from django.core.exceptions import ValidationError
from rest_framework import status
from rest_framework.response import Response
from common.models import Org, Profile, User
def set_profile_request(request, org, token):

View file

@ -0,0 +1,14 @@
class SwaggerMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request,*args,**kwargs):
request.body # just add this line BEFORE get_response
request.post_data=request.GET if len(request.POST) == 0 else request.POST # for swagger
if request.post_data=={} and request.body: #<--- for raw data (import)
request.post_data=json.loads(request.body)
response = self.get_response(request)
return response

View file

@ -1,10 +1,11 @@
# Generated by Django 2.1.2 on 2019-01-28 07:07
import common.models
from django.conf import settings
import django.contrib.auth.models
from django.db import migrations, models
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import common.models
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.1.2 on 2019-01-28 07:07
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,9 +1,10 @@
# Generated by Django 2.1.5 on 2019-01-28 07:28
import common.models
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import common.models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.1.5 on 2019-01-29 08:02
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.1.5 on 2019-02-08 07:09
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.1.5 on 2019-02-12 08:04
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.1.7 on 2019-02-14 05:51
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.1.5 on 2019-02-13 13:09
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.1.7 on 2019-05-08 10:10
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.1.7 on 2019-05-24 05:43
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.1.7 on 2019-06-04 13:00
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.2.2 on 2019-06-24 12:46
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.2.2 on 2019-07-22 09:13
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.2.10 on 2020-04-01 04:11
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.2.10 on 2020-04-27 11:40
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.0.6 on 2020-06-09 06:33
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.1 on 2021-01-13 11:24
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 3.2 on 2021-04-18 05:42
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2 on 2021-06-18 07:33
from django.db import migrations
import phonenumber_field.modelfields
from django.db import migrations
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 3.2.5 on 2021-07-30 07:58
from django.db import migrations, models
import django.db.models.deletion
import phonenumber_field.modelfields
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,9 +1,9 @@
# Generated by Django 3.2 on 2021-09-13 13:48
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import phonenumber_field.modelfields
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2.7 on 2021-10-06 07:21
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 3.2.8 on 2022-01-20 07:48
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2.11 on 2022-02-02 14:53
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,24 +1,25 @@
import arrow
import binascii
import datetime
import os
import time
import arrow
from django.contrib.auth.models import (AbstractBaseUser, PermissionsMixin,
UserManager)
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, UserManager
from phonenumber_field.modelfields import PhoneNumberField
from common.templatetags.common_tags import (
is_document_file_image,
is_document_file_audio,
is_document_file_video,
is_document_file_pdf,
is_document_file_code,
is_document_file_text,
is_document_file_sheet,
is_document_file_zip,
)
from common.utils import COUNTRIES, ROLES
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from common.templatetags.common_tags import (is_document_file_audio,
is_document_file_code,
is_document_file_image,
is_document_file_pdf,
is_document_file_sheet,
is_document_file_text,
is_document_file_video,
is_document_file_zip)
from common.utils import COUNTRIES, ROLES
def img_url(self, filename):

View file

@ -1,20 +1,14 @@
import re
from django.contrib.auth.hashers import check_password
from rest_framework import serializers
from django.contrib.auth import authenticate
from rest_framework_simplejwt.tokens import AccessToken, RefreshToken
from common.models import (
User,
Org,
Comment,
Address,
Attachments,
Document,
APISettings,
Profile,
)
from django.utils.http import urlsafe_base64_decode
from django.contrib.auth.hashers import check_password
from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_decode
from rest_framework import serializers
from rest_framework_simplejwt.tokens import AccessToken, RefreshToken
from common.models import (Address, APISettings, Attachments, Comment,
Document, Org, Profile, User)
class LoginSealizer(serializers.Serializer):

View file

@ -1,13 +1,13 @@
import datetime
from celery import Celery
from celery import Celery
from django.conf import settings
from django.contrib.auth.tokens import default_token_generator
from django.core.mail import EmailMessage
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.contrib.auth.tokens import default_token_generator
from common.models import Comment, Profile, User
from common.token_generator import account_activation_token

View file

@ -5,14 +5,10 @@ from django.test.utils import override_settings
from accounts.tests import AccountCreateTest
from cases.tests import CaseCreation
from common.models import User, Comment
from common.tasks import (
resend_activation_link_to_user,
send_email_to_new_user,
send_email_user_delete,
send_email_user_mentions,
send_email_user_status,
)
from common.models import Comment, User
from common.tasks import (resend_activation_link_to_user,
send_email_to_new_user, send_email_user_delete,
send_email_user_mentions, send_email_user_status)
from common.tests import ObjectsCreation
from contacts.tests import ContactObjectsCreation
from events.tests import EventObjectTest

View file

@ -1,7 +1,6 @@
from django.contrib.auth.tokens import PasswordResetTokenGenerator
# from django.utils import six
import six
from django.contrib.auth.tokens import PasswordResetTokenGenerator
class TokenGenerator(PasswordResetTokenGenerator):

View file

@ -1,7 +1,8 @@
from django.urls import path
from common import views
from rest_framework_simplejwt import views as jwt_views
from common import views
app_name = "api_common"

View file

@ -1,64 +1,53 @@
import json
from multiprocessing import context
from re import template
import requests
from django.conf import settings
from django.db import transaction
from common import serializer
from drf_yasg.utils import swagger_auto_schema
from django.shortcuts import get_object_or_404, render
from rest_framework import status
from django.views import View
from rest_framework.authtoken.models import Token
from accounts.serializer import AccountSerializer
from contacts.serializer import ContactSerializer
from opportunity.serializer import OpportunitySerializer
from django.http.response import JsonResponse
from leads.serializer import LeadSerializer
from teams.serializer import TeamsSerializer
from common.serializer import *
from cases.serializer import CaseSerializer
from accounts.models import Account, Contact
from django.contrib.auth import authenticate, login
from opportunity.models import Opportunity
from accounts.models import Tags
from cases.models import Case
from leads.models import Lead
from teams.models import Teams
from common.utils import ROLES
from django.views.decorators.csrf import csrf_exempt
from common.serializer import (
RegisterOrganizationSerializer,
CreateUserSerializer,
PasswordChangeSerializer,
)
from django.views.decorators.http import require_http_methods
from common.models import User, Org, Document, APISettings, Profile
from common.tasks import (
resend_activation_link_to_user,
send_email_to_new_user,
send_email_user_delete,
send_email_to_reset_password,
)
from django.utils.translation import gettext as _
from rest_framework.views import APIView
from rest_framework.response import Response
# from rest_framework_jwt.serializers import jwt_encode_handler
from common.utils import jwt_payload_handler
from rest_framework.permissions import IsAuthenticated
from rest_framework.pagination import LimitOffsetPagination
##from common.custom_auth import JSONWebTokenAuthentication
from common import swagger_params
from django.contrib.auth.hashers import make_password
from django.db import transaction
from django.db.models import Q
import json
from django.http.response import JsonResponse
from django.shortcuts import get_object_or_404, render
from django.utils import timezone
from django.utils.encoding import force_str
from django.utils.http import urlsafe_base64_decode
from django.utils.translation import gettext as _
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.authtoken.models import Token
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from accounts.models import Account, Contact, Tags
from accounts.serializer import AccountSerializer
from cases.models import Case
from cases.serializer import CaseSerializer
##from common.custom_auth import JSONWebTokenAuthentication
from common import serializer, swagger_params
from common.models import APISettings, Document, Org, Profile, User
from common.serializer import *
from common.serializer import (CreateUserSerializer, PasswordChangeSerializer,
RegisterOrganizationSerializer)
from common.tasks import (resend_activation_link_to_user,
send_email_to_new_user, send_email_to_reset_password,
send_email_user_delete)
from common.token_generator import account_activation_token
from django.utils import timezone
from common.utils import COUNTRIES
from django.contrib.auth.hashers import make_password
# from rest_framework_jwt.serializers import jwt_encode_handler
from common.utils import COUNTRIES, ROLES, jwt_payload_handler
from contacts.serializer import ContactSerializer
from leads.models import Lead
from leads.serializer import LeadSerializer
from opportunity.models import Opportunity
from opportunity.serializer import OpportunitySerializer
from teams.models import Teams
from teams.serializer import TeamsSerializer
class GetTeamsAndUsersView(APIView):
@ -135,7 +124,7 @@ class UserDetailView(APIView):
tags=["Users"], manual_parameters=swagger_params.user_update_params
)
def put(self, request, pk, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
profile = self.get_object(pk)
address_obj = profile.address
if (
@ -220,7 +209,7 @@ class ChangePasswordView(APIView):
manual_parameters=swagger_params.change_password_params,
)
def post(self, request, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
context = {"user": request.user}
serializer = PasswordChangeSerializer(data=params, context=context)
if serializer.is_valid():
@ -291,7 +280,7 @@ class LoginView(APIView):
manual_parameters=swagger_params.login_page_params,
)
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer = self.serializer_class(data=request.post_data) #<------
serializer.is_valid(raise_exception=True)
return Response(
{
@ -313,11 +302,11 @@ class RegistrationView(APIView):
)
def post(self, request, format=None):
serializer = self.serializer_class(data=request.data)
serializer = self.serializer_class(data=request.post_data)
if serializer.is_valid():
user_obj = serializer.save()
password = request.data.get("password")
password = request.post_data.get("password")
user_obj.password = make_password(password)
user_obj.save()
# sending mail for confirm password
@ -351,9 +340,9 @@ class OrgProfileCreateView(APIView):
manual_parameters=swagger_params.post_org_creation_page_params,
)
def post(self, request, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
serializer = self.serializer_class(data=request.data)
serializer = self.serializer_class(data=request.post_data)
if serializer.is_valid():
org_obj = serializer.save()
@ -430,7 +419,7 @@ class UsersListView(APIView, LimitOffsetPagination):
status=status.HTTP_403_FORBIDDEN,
)
else:
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
if params:
user_serializer = CreateUserSerializer(data=params, org=request.org)
address_serializer = BillingAddressSerializer(data=params)
@ -484,11 +473,7 @@ class UsersListView(APIView, LimitOffsetPagination):
status=status.HTTP_403_FORBIDDEN,
)
queryset = Profile.objects.filter(org=request.org).order_by("-id")
params = (
self.request.query_params
if len(self.request.data) == 0
else self.request.data
)
params = request.post_data
if params:
if params.get("email"):
queryset = queryset.filter(user__email__icontains=params.get("email"))
@ -548,11 +533,7 @@ class DocumentListView(APIView, LimitOffsetPagination):
model = Document
def get_context_data(self, **kwargs):
params = (
self.request.query_params
if len(self.request.data) == 0
else self.request.data
)
params = request.post_data
queryset = self.model.objects.filter(org=self.request.org).order_by("-id")
if self.request.user.is_superuser or self.request.profile.role == "ADMIN":
queryset = queryset
@ -650,7 +631,7 @@ class DocumentListView(APIView, LimitOffsetPagination):
tags=["documents"], manual_parameters=swagger_params.document_create_params
)
def post(self, request, *args, **kwargs):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
serializer = DocumentCreateSerializer(data=params, request_obj=request)
if serializer.is_valid():
doc = serializer.save(
@ -768,7 +749,7 @@ class DocumentDetailView(APIView):
)
def put(self, request, pk, format=None):
self.object = self.get_object(pk)
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
if not self.object:
return Response(
{"error": True, "errors": "Document does not exist"},
@ -830,7 +811,7 @@ class ForgotPasswordView(APIView):
tags=["Auth"], manual_parameters=swagger_params.forgot_password_params
)
def post(self, request, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
serializer = ForgotPasswordSerializer(data=params)
if serializer.is_valid():
user = get_object_or_404(User, email=params.get("email"))
@ -859,7 +840,7 @@ class ResetPasswordView(APIView):
tags=["Auth"], manual_parameters=swagger_params.reset_password_params
)
def post(self, request, uid, token, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
try:
uid = force_str(urlsafe_base64_decode(uid))
user_obj = User.objects.get(pk=uid)
@ -907,7 +888,7 @@ class UserStatusView(APIView):
},
status=status.HTTP_403_FORBIDDEN,
)
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
profiles = Profile.objects.filter(org=request.org)
profile = profiles.get(id=pk)
@ -960,11 +941,7 @@ class DomainList(APIView):
tags=["Settings"], manual_parameters=swagger_params.api_setting_create_params
)
def post(self, request, *args, **kwargs):
params = (
self.request.query_params
if len(self.request.data) == 0
else self.request.data
)
params = request.post_data
assign_to_list = []
if params.get("lead_assigned_to"):
assign_to_list = json.loads(params.get("lead_assigned_to"))
@ -1010,11 +987,7 @@ class DomainDetailView(APIView):
)
def put(self, request, pk, **kwargs):
api_setting = self.get_object(pk)
params = (
self.request.query_params
if len(self.request.data) == 0
else self.request.data
)
params = request.post_data
assign_to_list = []
if params.get("lead_assigned_to"):
assign_to_list = json.loads(params.get("lead_assigned_to"))
@ -1135,7 +1108,7 @@ class ResendActivationLinkView(APIView):
tags=["Auth"], manual_parameters=swagger_params.forgot_password_params
)
def post(self, request, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
user = get_object_or_404(User, email=params.get("email"))
if user.is_active:
return Response(

View file

@ -1,4 +1,5 @@
from django.contrib import admin
from contacts.models import Contact
admin.site.register(Contact)

View file

@ -1,9 +1,9 @@
# Generated by Django 2.1.2 on 2019-01-28 07:07
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import phonenumber_field.modelfields
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.1.5 on 2019-02-12 08:04
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.2.10 on 2020-04-23 10:29
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2.5 on 2021-07-16 10:24
from django.db import migrations, models
import phonenumber_field.modelfields
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2 on 2021-09-13 13:48
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,11 +1,11 @@
import arrow
from django.db import models
from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from common.models import Address, Org, Profile
from phonenumber_field.modelfields import PhoneNumberField
from teams.models import Teams
from common.utils import COUNTRIES
from teams.models import Teams
class Contact(models.Model):

View file

@ -1,11 +1,8 @@
from rest_framework import serializers
from common.serializer import (AttachmentsSerializer, BillingAddressSerializer,
OrganizationSerializer, ProfileSerializer)
from contacts.models import Contact
from common.serializer import (
ProfileSerializer,
BillingAddressSerializer,
AttachmentsSerializer,
OrganizationSerializer,
)
from teams.serializer import TeamsSerializer

View file

@ -1,4 +1,5 @@
from django.urls import path
from contacts import views
app_name = "api_contacts"

View file

@ -1,27 +1,25 @@
from rest_framework import status
from common.models import Attachments, Comment, Profile
from contacts.models import Contact, Profile
from teams.models import Teams
import json
from django.db.models import Q
from django.shortcuts import get_object_or_404
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.views import APIView
from common.models import Attachments, Comment, Profile
from common.serializer import (AttachmentsSerializer, BillingAddressSerializer,
CommentSerializer)
from common.utils import COUNTRIES
# from common.custom_auth import JSONWebTokenAuthentication
from contacts import swagger_params
from contacts.models import Contact, Profile
from contacts.serializer import *
from rest_framework.views import APIView
from common.utils import COUNTRIES
from common.serializer import (
CommentSerializer,
AttachmentsSerializer,
BillingAddressSerializer,
)
from tasks.serializer import TaskSerializer
from contacts.tasks import send_email_to_assigned_user
import json
from tasks.serializer import TaskSerializer
from teams.models import Teams
class ContactsListView(APIView, LimitOffsetPagination):
@ -30,11 +28,7 @@ class ContactsListView(APIView, LimitOffsetPagination):
model = Contact
def get_context_data(self, **kwargs):
params = (
self.request.query_params
if len(self.request.data) == 0
else self.request.data
)
params = request.post_data
queryset = self.model.objects.filter(org=self.request.org).order_by("-id")
if self.request.profile.role != "ADMIN" and not self.request.profile.is_admin:
queryset = queryset.filter(
@ -91,7 +85,7 @@ class ContactsListView(APIView, LimitOffsetPagination):
tags=["contacts"], manual_parameters=swagger_params.contact_create_post_params
)
def post(self, request, *args, **kwargs):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
contact_serializer = CreateContactSerializer(data=params, request_obj=request)
address_serializer = BillingAddressSerializer(data=params)
@ -154,7 +148,7 @@ class ContactDetailView(APIView):
tags=["contacts"], manual_parameters=swagger_params.contact_create_post_params
)
def put(self, request, pk, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
contact_obj = self.get_object(pk=pk)
address_obj = contact_obj.address
if contact_obj.org != request.org:
@ -343,11 +337,7 @@ class ContactDetailView(APIView):
tags=["contacts"], manual_parameters=swagger_params.contact_detail_get_params
)
def post(self, request, pk, **kwargs):
params = (
self.request.query_params
if len(self.request.data) == 0
else self.request.data
)
params = request.post_data
context = {}
self.contact_obj = Contact.objects.get(pk=pk)
if self.request.profile.role != "ADMIN" and not self.request.profile.is_admin:
@ -407,7 +397,7 @@ class ContactCommentView(APIView):
tags=["contacts"], manual_parameters=swagger_params.contact_comment_edit_params
)
def put(self, request, pk, format=None):
params = request.query_params if len(request.data) == 0 else request.data
params = request.post_data
obj = self.get_object(pk)
if (
request.profile.role == "ADMIN"

View file

@ -1,5 +1,7 @@
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
# set the default Django settings module for the 'celery' program.

View file

@ -1,4 +1,5 @@
import os
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration

View file

@ -1,8 +1,9 @@
import os
from dotenv import load_dotenv
from corsheaders.defaults import default_headers
from datetime import timedelta
from corsheaders.defaults import default_headers
from dotenv import load_dotenv
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@ -18,6 +19,25 @@ DEBUG = True
ALLOWED_HOSTS = ["*"]
INSTALLED_APPS = [
'wagtail.contrib.forms',
'wagtail.contrib.redirects',
'wagtail.embeds',
'wagtail.sites',
'wagtail.users',
'wagtail.snippets',
'wagtail.documents',
'wagtail.images',
'wagtail.search',
'wagtail.admin',
'wagtail',
'cms',
'wagtail.contrib.settings',
'modelcluster',
'taggit',
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.messages",
@ -54,6 +74,9 @@ MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
# "common.custom_auth.TokenAuthMiddleware",
"common.middleware.get_company.GetProfileAndOrg",
'wagtail.contrib.redirects.middleware.RedirectMiddleware',
'common.middleware.swagger_post.SwaggerMiddleware',
]
ROOT_URLCONF = "crm.urls"
@ -73,6 +96,8 @@ TEMPLATES = [
"django.contrib.messages.context_processors.messages",
"common.context_processors.common.app_name",
# "django_settings_export.settings_export",
'wagtail.contrib.settings.context_processors.settings',
],
},
},
@ -126,8 +151,12 @@ USE_TZ = True
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
AUTH_USER_MODEL = "common.User"
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = "/static/"
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
ENV_TYPE = os.environ["ENV_TYPE"]
print(">>> ENV_TYPE", ENV_TYPE)
@ -208,6 +237,9 @@ LOGGING = {
APPLICATION_NAME = "bottlecrm"
WAGTAIL_SITE_NAME = 'bottlecrm'
WAGTAILADMIN_BASE_URL = "https://bottlecrm.com"
SETTINGS_EXPORT = ["APPLICATION_NAME"]
@ -231,6 +263,7 @@ SWAGGER_SETTINGS = {
CORS_ALLOW_HEADERS = default_headers + ("org",)
CORS_ORIGIN_ALLOW_ALL = True
CSRF_TRUSTED_ORIGINS = ['https://*.runcode.io', 'http://*']
SECURE_HSTS_SECONDS = 3600
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
@ -240,6 +273,7 @@ SECURE_CONTENT_TYPE_NOSNIFF = True
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
# STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
DOMAIN_NAME = os.getenv("DOMAIN_NAME")
@ -267,3 +301,4 @@ JWT_ALGO = "HS256"
DOMAIN_NAME = os.environ["DOMAIN_NAME"]
SWAGGER_ROOT_URL = os.environ["SWAGGER_ROOT_URL"]

View file

@ -1,13 +1,17 @@
import os
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.auth import views
from django.urls import include, path, re_path as url
from django.urls import include, path
from django.urls import re_path as url
from django.views.generic import TemplateView
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from drf_yasg.views import get_schema_view
from rest_framework import permissions
from wagtail import urls as wagtail_urls
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.documents import urls as wagtaildocs_urls
openapi_info = openapi.Info(
title="Crm API",
@ -47,10 +51,20 @@ urlpatterns = [
path(
"logout/", views.LogoutView.as_view(), {"next_page": "/login/"}, name="logout"
),
path('admin/', include(wagtailadmin_urls)),
path('documents/', include(wagtaildocs_urls)),
path('', include(wagtail_urls))
]
if settings.DEBUG:
urlpatterns = urlpatterns + static(
settings.MEDIA_URL, document_root=settings.MEDIA_ROOT
)
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# urlpatterns = urlpatterns + static(
# settings.MEDIA_URL, document_root=settings.MEDIA_ROOT
# )

View file

@ -1,7 +1,7 @@
import os
import sys
from django.core.wsgi import get_wsgi_application
from django.core.wsgi import get_wsgi_application
PROJECT_DIR = os.path.abspath(__file__)
sys.path.append(PROJECT_DIR)

View file

@ -1,4 +1,5 @@
from django.contrib import admin
from emails.models import Email
# Register your models here.

View file

@ -1,4 +1,5 @@
from django import forms
from .models import Email

View file

@ -1,4 +1,5 @@
from rest_framework import serializers
from emails.models import Email

View file

@ -1,8 +1,8 @@
from django.test import TestCase
from django.test import Client
from common.models import User, Org
from emails.models import Email
from django.test import Client, TestCase
from common.models import Org, User
from emails.forms import EmailForm
from emails.models import Email
class UserCreation(TestCase):

View file

@ -1,7 +1,8 @@
from django.conf.urls import url
from . import views
from django.conf.urls.static import static
from django.conf import settings
from django.conf.urls import url
from django.conf.urls.static import static
from . import views
app_name = "emails"

View file

@ -1,12 +1,12 @@
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from emails.models import Email
from emails.forms import EmailForm
from datetime import datetime, timedelta
from django.core.mail import EmailMessage
from datetime import datetime
from datetime import timedelta
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from emails.forms import EmailForm
from emails.models import Email
def emails_list(request):

View file

@ -1,8 +1,8 @@
# Generated by Django 2.1.7 on 2019-06-03 05:58
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 2.2.10 on 2020-04-24 08:40
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2 on 2021-09-13 13:48
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
import arrow
from django.db import models
from django.utils.translation import gettext_lazy as _
from common.models import Org, Profile
from contacts.models import Contact
from teams.models import Teams

View file

@ -1,15 +1,13 @@
from rest_framework import serializers
from events.models import Event
from common.serializer import (
ProfileSerializer,
AttachmentsSerializer,
CommentSerializer,
OrganizationSerializer,
)
from contacts.serializer import ContactSerializer
from teams.serializer import TeamsSerializer
from datetime import datetime, timedelta
from rest_framework import serializers
from common.serializer import (AttachmentsSerializer, CommentSerializer,
OrganizationSerializer, ProfileSerializer)
from contacts.serializer import ContactSerializer
from events.models import Event
from teams.serializer import TeamsSerializer
class EventSerializer(serializers.ModelSerializer):
created_by = ProfileSerializer()

View file

@ -2,6 +2,7 @@ from celery import Celery
from django.conf import settings
from django.core.mail import EmailMessage
from django.template.loader import render_to_string
from common.models import Profile
from events.models import Event

Some files were not shown because too many files have changed in this diff Show more