From 07caee661b7e28b42e0bf30041497be14ef9d180 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Tue, 10 Oct 2017 13:24:39 +0530 Subject: [PATCH] Enhancements (#10) * accounts section code updated and functionality issues fixed * updated all modules from app --- accounts/tests.py | 23 +- cases/tests.py | 28 +- common/forms.py | 5 - common/tests.py | 4 +- common/views.py | 2 +- contacts/forms.py | 45 +- contacts/tests.py | 160 +- contacts/urls.py | 15 +- contacts/views.py | 291 +-- leads/forms.py | 55 +- leads/tests.py | 35 +- leads/urls.py | 18 +- leads/views.py | 491 ++--- oppurtunity/forms.py | 28 +- oppurtunity/tests.py | 23 +- oppurtunity/urls.py | 19 +- oppurtunity/views.py | 382 ++-- planner/tests.py | 12 +- static/js/contacts/view_contact.js | 101 + static/js/opportunities/view_opportunity.js | 101 + templates/accounts/accounts.html | 296 ++- templates/contacts/contacts.html | 216 +-- templates/contacts/create_contact.html | 264 ++- templates/contacts/view_contact.html | 1647 ++--------------- templates/leads/create_lead.html | 191 +- templates/leads/leads.html | 275 ++- templates/leads/view_leads.html | 488 +++-- templates/nav_menu.html | 10 +- templates/oppurtunity/create_opportunity.html | 157 +- templates/oppurtunity/opportunity.html | 273 ++- templates/oppurtunity/view_opportunity.html | 929 ++-------- 31 files changed, 2370 insertions(+), 4214 deletions(-) create mode 100644 static/js/contacts/view_contact.js create mode 100644 static/js/opportunities/view_opportunity.js diff --git a/accounts/tests.py b/accounts/tests.py index 26a07e4d..bca408b5 100644 --- a/accounts/tests.py +++ b/accounts/tests.py @@ -1,7 +1,7 @@ from django.test import TestCase from common.models import * from accounts.models import Account -from common.models import User +from django.contrib.auth.models import User # Create your tests here. @@ -9,17 +9,18 @@ from common.models import User class AccountCreateTest(object): def setUp(self): - self.user = User.objects.create(username='uday', email='u@mp.com') - self.user.set_password('uday2293') - self.user.save() - + self.country = Country.objects.create( + iso_3166_1_a2="IN", iso_3166_1_a3="IND", iso_3166_1_numeric="01", printable_name="INDIA", name="INDIA", is_shipping_country="True") self.address = Address.objects.create( - street="KPHB", city="HYDERABAD", state="ANDHRA PRADESH", postcode="500073", country='IN') + street="KPHB", city="HYDERABAD", state="ANDHRA PRADESH", postcode="500073", country=Country.objects.get(pk=1)) self.account = Account.objects.create( name="Uday", email="udayteja@micropyramid.com", phone="8333855552", billing_address=self.address, - shipping_address=self.address, website="www.uday.com", created_by=self.user, - industry="SOFTWARE", description="Yes.. Testing Done") - self.client.login(email='u@mp.com', password='uday2293') + shipping_address=self.address, website="www.uday.com", account_type="PARTNER", + sis_code="UDAYMP2016", industry="SOFTWARE", description="Yes.. Testing Done") + self.user = User.objects.create(username='uday') + self.user.set_password('uday2293') + self.user.save() + self.client.login(username='uday', password='uday2293') class AccountsCreateUrlTestCase(AccountCreateTest, TestCase): @@ -27,7 +28,7 @@ class AccountsCreateUrlTestCase(AccountCreateTest, TestCase): response = self.client.get('/accounts/create/', { 'name': "Uday", 'email': "udayteja@micropyramid.com", 'phone': "", 'billing_address': self.address, 'shipping_address': self.address, 'website': "www.uday.com", 'account_type': "PARTNER", - 'industry': "SOFTWARE", 'description': "Yes.. Testing Done"}) + 'sis_code': "UDAYMP2016", 'industry': "SOFTWARE", 'description': "Yes.. Testing Done"}) self.assertEqual(response.status_code, 200) def test_account_create_html(self): @@ -62,7 +63,7 @@ class AccountsViewTestCase(AccountCreateTest, TestCase): self.accounts = Account.objects.all() response = self.client.get('/accounts/1/view/') self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['account_record'].id, 1) + self.assertEqual(response.context['ac'].id, 1) self.assertTemplateUsed(response, 'accounts/view_account.html') diff --git a/cases/tests.py b/cases/tests.py index 44f72aeb..bdf27858 100644 --- a/cases/tests.py +++ b/cases/tests.py @@ -3,32 +3,34 @@ from cases.models import Case from contacts.models import Contact from accounts.models import Account from django.test import Client -from common.models import Address +from common.models import Country, Address from django.core.urlresolvers import reverse -from common.models import User +from django.contrib.auth.models import User class CaseCreation(object): def setUp(self): + self.country = Country.objects.create(iso_3166_1_a2="IN", iso_3166_1_a3="IN", iso_3166_1_numeric="IN", + printable_name="India", + name="India", is_shipping_country="True") self.address = Address.objects.create(street="6th phase", city="hyderabad", postcode="506344", - country='IN') - self.user = User.objects.create(username='raghu', email='r@mp.com') - self.user.set_password('raghu') - self.user.save() - + country=Country.objects.get(pk=1)) self.account = Account.objects.create(name="account", email="account@gmail.com", phone="12345", billing_address=self.address, shipping_address=self.address, website="www.account.com", - industry="IT", - description="account", created_by=self.user) - self.contacts = Contact.objects.create(first_name="contact", + account_type="account", sis_code="12345", industry="IT", + description="account") + self.contacts = Contact.objects.create(name="contact", email="contact@gmail.com", phone="12345", - account=self.account, description="contact", address=self.address, created_by=self.user) + account=self.account, description="contact", address=self.address) # self.comment = Comments.objects.create(comment="new", caseid=self.case.id, comment_) - self.client.login(email='r@mp.com', password='raghu') + self.user = User.objects.create(username='raghu') + self.user.set_password('raghu') + self.user.save() + self.client.login(username='raghu', password='raghu') self.case = Case.objects.create(name="raghu", case_type="Problem", status="New", account=self.account, priority="Low", description="something", teams="Sales", - created_by=self.user) + userid=User.objects.get(pk=1)) class CaseCreateTestCase(CaseCreation, TestCase): diff --git a/common/forms.py b/common/forms.py index e3e4e677..e5c75adb 100644 --- a/common/forms.py +++ b/common/forms.py @@ -1,10 +1,5 @@ from django import forms from common.models import Address -from oppurtunity.models import Opportunity -from cases.models import Case -from leads.models import Lead -from contacts.models import Contact -from accounts.models import Account class BillingAddressForm(forms.ModelForm): diff --git a/common/tests.py b/common/tests.py index ec5eb79a..8e155206 100644 --- a/common/tests.py +++ b/common/tests.py @@ -1,6 +1,8 @@ from django.test import TestCase from django.test import Client -from common.models import User +from common.forms import PersonForm +from common.models import Person +from django.contrib.auth.models import User class TestHomePage(TestCase): diff --git a/common/views.py b/common/views.py index de609437..6d0e7112 100644 --- a/common/views.py +++ b/common/views.py @@ -6,7 +6,7 @@ from django.contrib.auth import logout, authenticate, login -# @login_required +@login_required def home(request): return render(request, 'index.html') diff --git a/contacts/forms.py b/contacts/forms.py index f762dcd1..67fe8cca 100644 --- a/contacts/forms.py +++ b/contacts/forms.py @@ -1,35 +1,44 @@ from django import forms from contacts.models import Contact from common.models import Comment -from common.models import Address - - -class AddressForm(forms.ModelForm): - - class Meta: - - model = Address - fields = ('street', 'city', 'state', 'postcode', 'country') class ContactForm(forms.ModelForm): - class Meta: + def __init__(self, *args, **kwargs): + assigned_users = kwargs.pop('assigned_to', []) + contact_account = kwargs.pop('account', []) + super(ContactForm, self).__init__(*args, **kwargs) + for field in self.fields.values(): + field.widget.attrs = {"class": "form-control"} + self.fields['description'].widget.attrs.update({ + 'rows': '6'}) + self.fields['assigned_to'].queryset = assigned_users + self.fields['account'].queryset = contact_account + self.fields['assigned_to'].required = False + self.fields['teams'].required = False + class Meta: model = Contact - fields = ('first_name', 'last_name', 'account', 'email', 'teams', 'assigned_to', 'phone', 'description') + fields = ( + 'assigned_to', 'teams', 'first_name', 'last_name', 'account', 'email', 'phone', 'address', 'description' + ) def clean_phone(self): - a = len(self.data.get("phone")) - if (a >= 10 and a <= 12): - return self.data.get("phone") - else: - raise forms.ValidationError("Phone number must be Minimum of 10 Digits and Maximum of 12 Digits") + client_phone = self.cleaned_data.get('phone', None) + try: + if int(client_phone) and not client_phone.isalpha(): + ph_length = str(client_phone) + if len(ph_length) < 10 or len(ph_length) > 13: + raise forms.ValidationError('Phone number must be minimum 10 Digits and maximum of 13 Digits') + except (ValueError): + raise forms.ValidationError('Phone Number should contain only Numbers') + return client_phone -class CommentForm(forms.ModelForm): +class ContactCommentForm(forms.ModelForm): comment = forms.CharField(max_length=64, required=True) class Meta: model = Comment - fields = ('comment', 'commented_by', 'contact') + fields = ('comment', 'contact', 'commented_by') diff --git a/contacts/tests.py b/contacts/tests.py index a604d770..b6fc0432 100644 --- a/contacts/tests.py +++ b/contacts/tests.py @@ -1,103 +1,103 @@ -from django.test import TestCase -from contacts.models import Contact -from accounts.models import Account -from common.models import Address -from common.models import User -from django.test import Client -from django.core.urlresolvers import reverse +# from django.test import TestCase +# from contacts.models import Contact +# from accounts.models import Account +# from common.models import Address, Country +# from django.contrib.auth.models import User +# from django.test import Client +# from django.core.urlresolvers import reverse -class ContactObjectsCreation(object): - def setUp(self): - self.client = Client() - self.user = User.objects.create_superuser('user@micropyramid.com', 'username', 'password') - user_login = self.client.login(username='user@micropyramid.com', - password='password') - - self.address = Address.objects.create(street="kphb 5th phase", city="hyd", state="telanagana", postcode=502279, country='IN') - self.account = Account.objects.create(name="account", email="account@gmail.com", phone="12345", billing_address=Address.objects.get(pk=1), shipping_address=Address.objects.get(pk=1), website="account.com", industry="IT", description="account", created_by=self.user) - self.contact = Contact.objects.create(first_name="contact", email="contact@gmail.com", phone="12345", account=Account.objects.get(pk=1), address=Address.objects.get(pk=1), description="contact", created_by=self.user) +# class ContactObjectsCreation(object): +# def setUp(self): +# self.client = Client() +# self.country = Country.objects.create(iso_3166_1_a2=67, iso_3166_1_a3=87, iso_3166_1_numeric=456, printable_name="russia", name="Russia", is_shipping_country="True") +# self.address = Address.objects.create(street="kphb 5th phase", city="hyd", state="telanagana", postcode=502279, country=(Country.objects.get(pk=1))) +# self.account = Account.objects.create(name="account", email="account@gmail.com", phone="12345", billing_address=Address.objects.get(pk=1), shipping_address=Address.objects.get(pk=1), website="account.com", account_type="account", sis_code="12345", industry="IT", description="account") +# self.contact = Contact.objects.create(name="contact", email="contact@gmail.com", phone="12345", account=Account.objects.get(pk=1), address=Address.objects.get(pk=1), description="contact" ) +# self.user = User.objects.create_superuser('user@micropyramid.com', 'username', 'password') +# user_login = self.client.login(username='user@micropyramid.com', +# password='password') -class ContactObjectsCreation_Count(ContactObjectsCreation, TestCase): - def test_contact_object_creation(self): - c = Contact.objects.count() - self.assertEqual(c, 1) +# class ContactObjectsCreation_Count(ContactObjectsCreation, TestCase): +# def test_contact_object_creation(self): +# c = Contact.objects.count() +# self.assertEqual(c, 1) - def test_account_object_creation(self): - c = Account.objects.count() - self.assertEqual(c, 1) +# def test_account_object_creation(self): +# c = Account.objects.count() +# self.assertEqual(c, 1) - def test_address_object_creation(self): - c = Address.objects.count() - self.assertEqual(c, 1) +# def test_address_object_creation(self): +# c = Address.objects.count() +# self.assertEqual(c, 1) -class ContactObjectsCreation_id(ContactObjectsCreation, TestCase): +# class ContactObjectsCreation_id(ContactObjectsCreation, TestCase): - def test_create_contacts(self): - self.assertEqual(self.contact.id, 1) +# def test_create_contacts(self): +# self.assertEqual(self.contact.id, 1) - def test_create_accounts(self): - self.assertEqual(self.account.id, 1) +# def test_create_accounts(self): +# self.assertEqual(self.account.id, 1) - def test_create_address(self): - self.assertEqual(self.address.id, 1) +# def test_create_address(self): +# self.assertEqual(self.address.id, 1) -class ContactViewsTestCase(ContactObjectsCreation, TestCase): +# class ContactViewsTestCase(ContactObjectsCreation, TestCase): - def test_contacts_list_page(self): - response = self.client.get('/contacts/list/') - self.assertEqual(response.status_code, 200) - if response.status_code == 200: - self.contacts = Contact.objects.all() - self.assertEqual(response.context['contacts'][0].id, self.contact.id) - self.assertTrue(response.context['contacts']) +# def test_contacts_list_page(self): +# response = self.client.get('/contacts/list/') +# self.assertEqual(response.status_code, 200) +# if response.status_code == 200: +# self.contacts = Contact.objects.all() +# self.assertEqual(response.context['contacts'][0].id, self.contact.id) +# self.assertTrue(response.context['contacts']) - def test_contacts_list_html(self): - response = self.client.get('/contacts/list/') - self.assertTemplateUsed(response, 'contacts/contacts.html') +# def test_contacts_list_html(self): +# response = self.client.get('/contacts/list/') +# self.assertTemplateUsed(response, 'contacts/contacts.html') - def test_contacts_create(self): - response = self.client.post('/contacts/create/', { - 'name': 'contact', 'email': 'contact@gmail.com', 'phone': '12345', - 'account': self.account.id, 'address': self.address, 'description': 'contact'}) - self.assertEqual(response.status_code, 200) +# def test_contacts_create(self): +# response = self.client.post('/contacts/create/', { +# 'name': 'contact', 'email': 'contact@gmail.com', 'phone': '12345', +# 'account': self.account.id, 'address': self.address, 'description': 'contact'}) +# self.assertEqual(response.status_code, 200) - def test_contacts_create_html(self): - response = self.client.post('/contacts/create/', { - 'name': 'contact', 'email': 'contact@gmail.com', 'phone': '12345', - 'account': self.account.id, 'address': self.address, 'description': 'contact'}) - self.assertTemplateUsed(response, 'contacts/create_contact.html') +# def test_contacts_create_html(self): +# response = self.client.post('/contacts/create/', { +# 'name': 'contact', 'email': 'contact@gmail.com', 'phone': '12345', +# 'account': self.account.id, 'address': self.address, 'description': 'contact'}) +# self.assertTemplateUsed(response, 'contacts/create_contact.html') - def test_contacts_delete(self): - Contact.objects.filter(id=self.contact.id).delete() - response = self.client.get(reverse("contacts:list")) - self.assertEqual(response.status_code, 200) +# def test_contacts_delete(self): +# Contact.objects.filter(id=self.contact.id).delete() +# response = self.client.get(reverse("contacts:list")) +# self.assertEqual(response.status_code, 200) - def test_contacts_delete_location_checking(self): - response = self.client.post('/contacts/1/delete/') - self.assertEqual(response['location'], '/contacts/list/') +# def test_contacts_delete_location_checking(self): +# response = self.client.post('/contacts/1/delete/') +# self.assertEqual(response['location'], '/contacts/list/') - def test_contacts_edit(self): - response = self.client.post('/contacts/1/edit/', { - 'name': 'priya', 'email': 'contact@gmail.com', 'phone': '12345', - 'pk': 1, 'account': self.account.id, 'address': self.address.id}) - self.assertEqual(response.status_code, 200) +# def test_contacts_edit(self): +# response = self.client.post('/contacts/1/edit/', { +# 'name': 'priya', 'email': 'contact@gmail.com', 'phone': '12345', +# 'pk': 1, 'account': self.account.id, 'address': self.address.id}) +# self.assertEqual(response.status_code, 200) - def test_contacts_edit_html(self): - response = self.client.post('/contacts/1/edit/', { - 'name': 'priya', 'email': 'contact@gmail.com', 'phone': '12345', - 'pk': 1, 'account': self.account.id, 'address': self.address.id}) - self.assertTemplateUsed(response, 'contacts/create_contact.html') +# def test_contacts_edit_html(self): +# response = self.client.post('/contacts/1/edit/', { +# 'name': 'priya', 'email': 'contact@gmail.com', 'phone': '12345', +# 'pk': 1, 'account': self.account.id, 'address': self.address.id}) +# self.assertTemplateUsed(response, 'contacts/create_contact.html') - def test_contacts_view(self): - self.contacts = Contact.objects.all() - response = self.client.get('/contacts/1/view/') - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['con'].id, 1) +# def test_contacts_view(self): +# self.contacts = Contact.objects.all() +# response = self.client.get('/contacts/1/view/') +# self.assertEqual(response.status_code, 200) +# self.assertEqual(response.context['con'].id, 1) - def test_contacts_view_html(self): - response = self.client.get('/contacts/1/view/') - self.assertTemplateUsed(response, 'contacts/view_contact.html') +# def test_contacts_view_html(self): +# response = self.client.get('/contacts/1/view/') +# self.assertTemplateUsed(response, 'contacts/view_contact.html') diff --git a/contacts/urls.py b/contacts/urls.py index 3ddd8c57..eb5b3db2 100644 --- a/contacts/urls.py +++ b/contacts/urls.py @@ -1,17 +1,18 @@ from django.conf.urls import url -from .import views +from contacts import views app_name = 'contacts' urlpatterns = [ - url(r'^list/$', views.display_contact, name='list'), + url(r'^list/$', views.contacts_list, name='list'), url(r'^create/$', views.add_contact, name='add_contact'), + url(r'^(?P\d+)/view/$', views.view_contact, name='view_contact'), url(r'^(?P\d+)/edit/$', views.edit_contact, name='edit_contact'), - url(r'^(?P\d+)/delete/$', views.delete_contact, name='delete_contact'), - url(r'^(?P\d+)/view/$', views.view_contact, name='view_contact'), - url(r'^comment_create/$', views.comment_add, name='comment_add'), - url(r'^comment_edit/$', views.comment_edit, name='comment_edit'), - url(r'^comment_remove/$', views.comment_remove, name='comment_remove'), + url(r'^(?P\d+)/delete/$', views.remove_contact, name='remove_contact'), url(r'^get/list/$', views.get_contacts, name='get_contacts'), + # comments + url(r'^comment/add/$', views.add_comment, name='add_comment'), + url(r'^comment/edit/$', views.edit_comment, name='edit_comment'), + url(r'^comment/remove/$', views.remove_comment, name='remove_comment'), ] diff --git a/contacts/views.py b/contacts/views.py index 125186e6..02147d67 100644 --- a/contacts/views.py +++ b/contacts/views.py @@ -1,172 +1,193 @@ from django.shortcuts import render, get_object_or_404 from django.http import HttpResponseRedirect, HttpResponse, JsonResponse from django.contrib.auth.decorators import login_required -from django.contrib.auth.models import User from django.urls import reverse -from common.models import Address, Comment, Team + +from common.models import User, Address, Comment, Team +from common.forms import BillingAddressForm +from common.utils import COUNTRIES from accounts.models import Account -from oppurtunity.models import Opportunity, STAGES, SOURCES -from cases.models import Case -from contacts.forms import ContactForm, CommentForm, AddressForm from contacts.models import Contact -from planner.models import Event +from contacts.forms import ContactForm, ContactCommentForm + + +# CRUD Operations Start + + +@login_required +def contacts_list(request): + contact_obj_list = Contact.objects.all() + accounts = Account.objects.all() + page = request.POST.get('per_page') + first_name = request.POST.get('first_name') + account = request.POST.get('account') + city = request.POST.get('city') + phone = request.POST.get('phone') + email = request.POST.get('email') + if first_name: + contact_obj_list = contact_obj_list.filter(first_name__icontains=first_name) + if account: + contact_obj_list = contact_obj_list.filter(account=account) + if city: + a = Address.objects.filter(city__icontains=city) + contact_obj_list = contact_obj_list.filter(address__in=a) + if phone: + contact_obj_list = contact_obj_list.filter(phone__icontains=phone) + if email: + contact_obj_list = contact_obj_list.filter(email__icontains=email) + return render(request, 'contacts/contacts.html', { + 'contact_obj_list': contact_obj_list, + 'accounts': accounts, + 'per_page': page + }) @login_required def add_contact(request): - acount = Account.objects.all() - countri = Country.objects.all() - assigned_user = User.objects.filter(is_active=True) - + accounts = Account.objects.filter() + users = User.objects.filter(is_active=True).order_by('email') + form = ContactForm(assigned_to=users, account=accounts) + address_form = BillingAddressForm() + teams = Team.objects.all() + assignedto_list = request.POST.getlist('assigned_to') + teams_list = request.POST.getlist('teams') if request.method == 'POST': - - address_form = AddressForm(request.POST) - form = ContactForm(request.POST) - + form = ContactForm(request.POST, assigned_to=users, account=accounts) + address_form = BillingAddressForm(request.POST) if form.is_valid() and address_form.is_valid(): address_obj = address_form.save() contact_obj = form.save(commit=False) contact_obj.address = address_obj + contact_obj.created_by = request.user contact_obj.save() - contact_obj.users = request.user - contact_obj.save() - return HttpResponseRedirect(reverse('contacts:list')) + contact_obj.assigned_to.add(*assignedto_list) + contact_obj.teams.add(*teams_list) + if request.is_ajax(): + return JsonResponse({'error': False}) + if request.POST.get("savenewform"): + return HttpResponseRedirect(reverse("contacts:add_contact")) + else: + return HttpResponseRedirect(reverse('contacts:list')) else: + if request.is_ajax(): + return JsonResponse({'error': True, 'contact_errors': form.errors}) return render(request, 'contacts/create_contact.html', { - 'err_contct_form': form.errors, 'acount': acount, - 'err_address_form': address_form.errors, 'teams': TEAMS, - 'countri': countri, 'assigned_user': assigned_user}) - + 'contact_form': form, + 'address_form': address_form, + 'accounts': accounts, + 'countries': COUNTRIES, + 'teams': teams, + 'users': users, + 'assignedto_list': assignedto_list, + 'teams_list': teams_list + }) else: return render(request, 'contacts/create_contact.html', { - 'acount': acount, 'countri': countri, - 'teams': TEAMS, 'assigned_user': assigned_user}) + 'contact_form': form, + 'address_form': address_form, + 'accounts': accounts, + 'countries': COUNTRIES, + 'teams': teams, + 'users': users, + 'assignedto_list': assignedto_list, + 'teams_list': teams_list + }) @login_required -def display_contact(request): - display_obj = Contact.objects.all() - count = Contact.objects.all().count() - acount = Account.objects.all() - page = request.GET.get('per_page') - name = request.GET.get('name') - account = request.GET.get('account') - city = request.GET.get('city') - phone = request.GET.get('phone') - email = request.GET.get('email') - - if name: - display_obj = display_obj.filter(name__icontains=name) - - if account: - display_obj = display_obj.filter(account=account) - - if city: - a = Address.objects.filter(city__icontains=city) - display_obj = display_obj.filter(address__in=a) - - if phone: - display_obj = display_obj.filter(phone__contains=phone) - - if email: - display_obj = display_obj.filter(email__contains=email) - - return render(request, 'contacts/contacts.html', { - 'contacts': display_obj, 'count': count, - 'acount': acount, 'per_page': page}) - - -@login_required -def delete_contact(request, pk): - Contact.objects.filter(id=pk).delete() - if request.is_ajax(): - return JsonResponse({'error': False}) - return HttpResponseRedirect(reverse('contacts:list')) +def view_contact(request, contact_id): + contact_record = get_object_or_404( + Contact.objects.select_related("address"), id=contact_id) + comments = contact_record.contact_comments.all() + return render(request, 'contacts/view_contact.html', { + 'contact_record': contact_record, + 'comments': comments}) @login_required def edit_contact(request, pk): - edit_obj = get_object_or_404(Contact, id=pk) - address_obj = get_object_or_404(Address, id=edit_obj.address.id) - acount = Account.objects.all() - countri = Country.objects.all() - assigned_user = User.objects.filter(is_active=True) - address_form = AddressForm(instance=address_obj) - form = ContactForm(instance=edit_obj) + contact_obj = get_object_or_404(Contact, id=pk) + address_obj = get_object_or_404(Address, id=contact_obj.address.id) + accounts = Account.objects.filter() + users = User.objects.filter(is_active=True).order_by('email') + form = ContactForm(instance=contact_obj, assigned_to=users, account=accounts) + address_form = BillingAddressForm(instance=address_obj) + teams = Team.objects.all() + assignedto_list = request.POST.getlist('assigned_to') + teams_list = request.POST.getlist('teams') if request.method == 'POST': - address_form = AddressForm(request.POST, instance=address_obj) - form = ContactForm(request.POST, instance=edit_obj) + form = ContactForm(request.POST, instance=contact_obj, assigned_to=users, account=accounts) + address_form = BillingAddressForm(request.POST, instance=address_obj) if form.is_valid() and address_form.is_valid(): addres_obj = address_form.save() contact_obj = form.save(commit=False) contact_obj.address = addres_obj + contact_obj.created_by = request.user contact_obj.save() + contact_obj.assigned_to.clear() + contact_obj.assigned_to.add(*assignedto_list) + contact_obj.teams.clear() + contact_obj.teams.add(*teams_list) if request.is_ajax(): return JsonResponse({'error': False}) return HttpResponseRedirect(reverse('contacts:list')) else: + if request.is_ajax(): + return JsonResponse({'error': True, 'contact_errors': form.errors}) return render(request, 'contacts/create_contact.html', { - 'edit_obj': edit_obj, 'err_contct_form': form.errors, - 'teams': TEAMS, 'err_address_form': address_form.errors, - 'acount': acount, 'countri': countri, - 'assigned_user': assigned_user}) + 'contact_form': form, + 'address_form': address_form, + 'contact_obj': contact_obj, + 'accounts': accounts, + 'countries': COUNTRIES, + 'teams': teams, + 'users': users, + 'assignedto_list': assignedto_list, + 'teams_list': teams_list + }) else: return render(request, 'contacts/create_contact.html', { - 'edit_obj': edit_obj, 'address_obj': address_obj, - 'acount': acount, 'countri': countri, 'teams': TEAMS, - 'assigned_user': assigned_user}) + 'contact_form': form, + 'address_form': address_form, + 'contact_obj': contact_obj, + 'address_obj': address_obj, + 'accounts': accounts, + 'countries': COUNTRIES, + 'teams': teams, + 'users': users, + 'assignedto_list': assignedto_list, + 'teams_list': teams_list + }) @login_required -def view_contact(request, pk): - con = Contact.objects.get(id=pk) - accunt = Account.objects.all() - contact = Contact.objects.all() - opportunity = Opportunity.objects.filter(contacts=con).order_by('id') - cases = Case.objects.filter(contacts=con).order_by('id') - users = User.objects.filter(is_active=True) - comments = Comments.objects.filter(contactid=con) - meetings = Event.objects.all() - return render(request, 'contacts/view_contact.html', { - 'meetings': meetings, 'opportunity': opportunity, 'comments': comments, - 'con': con, 'stages': STAGES, 'sources': SOURCES, - 'accunt': accunt, 'contact': contact, 'users': users, 'cases': cases}) - - -@login_required -def get_contacts(request): - if request.method == 'GET': - if request.user.is_authenticated(): - contacts = Contact.objects.all() - return render(request, 'contacts/contacts_list.html', { - 'contacts': contacts}) - else: - return HttpResponseRedirect('accounts/login') +def remove_contact(request, pk): + contact_record = get_object_or_404(Contact, id=pk) + contact_record.delete() + if request.is_ajax(): + return JsonResponse({'error': False}) else: - return HttpResponse - ('Invalid Method or Not Authanticated in load_calls') + return HttpResponseRedirect(reverse('contacts:list')) + +# CRUD Operations End +# Comments Section Starts @login_required -def comment_add(request): +def add_comment(request): if request.method == 'POST': contact = get_object_or_404(Contact, id=request.POST.get('contactid')) - assigned = False - if contact.created_user: - assigned = (int(contact.created_user) == request.user) - if request.user == contact.users or assigned: - form = CommentForm(request.POST) + if request.user in contact.assigned_to.all() or request.user == contact.created_by: + form = ContactCommentForm(request.POST) if form.is_valid(): - comment = request.POST.get('comment') - comment_user = request.user - contactid = request.POST.get('contactid') - c = Comments.objects.create( - comment=comment, - contactid=Contact.objects.get(id=contactid), - comment_user=comment_user) - data = {"com_id": c.id, "comment": c.comment, - "comment_time": c.comment_time, - "com_user": c.comment_user.username} + contact_comment = form.save(commit=False) + contact_comment.comment = request.POST.get('comment') + contact_comment.commented_by = request.user + contact_comment.contact = contact + contact_comment.save() + data = {"comment_id": contact_comment.id, "comment": contact_comment.comment, + "commented_on": contact_comment.commented_on, + "commented_by": contact_comment.commented_by.email} return JsonResponse(data) else: return JsonResponse({"error": form['comment'].errors}) @@ -176,13 +197,13 @@ def comment_add(request): @login_required -def comment_edit(request): +def edit_comment(request): if request.method == "POST": comment = request.POST.get('comment') comment_id = request.POST.get("commentid") - com = get_object_or_404(Comments, id=comment_id) - form = CommentForm(request.POST) - if request.user == com.comment_user: + com = get_object_or_404(Comment, id=comment_id) + form = ContactCommentForm(request.POST) + if request.user == com.commented_by: if form.is_valid(): com.comment = comment com.save() @@ -191,21 +212,33 @@ def comment_edit(request): else: return JsonResponse({"error": form['comment'].errors}) else: - return JsonResponse({"error": "You dont have Access to edit"}) + return JsonResponse({"error": "You dont have authentication to edit"}) else: return render(request, "404.html") @login_required -def comment_remove(request): +def remove_comment(request): if request.method == 'POST': comment_id = request.POST.get('comment_id') - c = get_object_or_404(Comments, id=comment_id) - if request.user == c.comment_user: - get_object_or_404(Comments, id=comment_id).delete() + comment = get_object_or_404(Comment, id=comment_id) + if request.user == comment.commented_by: + comment.delete() data = {"cid": comment_id} return JsonResponse(data) else: return JsonResponse({"error": "You Dont have permisions to delete"}) else: - return HttpResponse("Something Went Wrong!!") + return HttpResponse("Something Went Wrong") + +# Comments Section Ends +# Other Views + + +@login_required +def get_contacts(request): + if request.method == 'GET': + contacts = Contact.objects.filter() + return render(request, 'contacts/contacts_list.html', {'contacts': contacts}) + else: + return HttpResponse('Invalid Method or Not Authanticated in load_calls') diff --git a/leads/forms.py b/leads/forms.py index 6764365b..1ae131b6 100644 --- a/leads/forms.py +++ b/leads/forms.py @@ -1,35 +1,50 @@ from django import forms from leads.models import Lead -from common.models import Comment -from common.models import Address +from common.models import Address, Comment -class CreateLeadform(forms.ModelForm): +class LeadForm(forms.ModelForm): + + def __init__(self, *args, **kwargs): + assigned_users = kwargs.pop('assigned_to', []) + super(LeadForm, self).__init__(*args, **kwargs) + for field in self.fields.values(): + field.widget.attrs = {"class": "form-control"} + if self.data.get('status') == 'converted': + self.fields['account_name'].required = True + self.fields['assigned_to'].queryset = assigned_users + self.fields['assigned_to'].required = False + self.fields['teams'].required = False + self.fields['phone'].required = False + self.fields['first_name'].widget.attrs.update({ + 'placeholder': 'First Name'}) + self.fields['last_name'].widget.attrs.update({ + 'placeholder': 'Last Name'}) + self.fields['account_name'].widget.attrs.update({ + 'placeholder': 'Account Name'}) class Meta: model = Lead - fields = ['title', 'first_name', 'last_name', 'email', 'description', - 'account', 'website', 'status', 'phone', 'teams', 'assigned_to', - 'source', 'opportunity_amount', 'description'] + fields = ('assigned_to', 'teams', 'first_name', 'last_name', 'account_name', 'title', + 'phone', 'email', 'status', 'source', 'website', 'address', 'description' + ) def clean_phone(self): - a = len(self.data.get("phone")) - if (a >= 10 and a <= 12): - return self.data.get("phone") - else: - raise forms.ValidationError("Phone number must be Minimum of 10 Digits and Maximum of 12 Digits") + client_phone = self.cleaned_data.get('phone', None) + if client_phone: + try: + if int(client_phone) and not client_phone.isalpha(): + ph_length = str(client_phone) + if len(ph_length) < 10 or len(ph_length) > 13: + raise forms.ValidationError('Phone number must be minimum 10 Digits and maximum 13 Digits') + except (ValueError): + raise forms.ValidationError('Phone Number should contain only Numbers') + return client_phone -class AddressLeadForm(forms.ModelForm): - - class Meta: - model = Address - fields = ['street', 'city', 'state', 'postcode', 'country'] - - -class CommentForm(forms.ModelForm): +class LeadCommentForm(forms.ModelForm): comment = forms.CharField(max_length=64, required=True) class Meta: model = Comment - fields = ['comment', 'commented_by', 'lead'] + fields = ('comment', 'lead', 'commented_by') diff --git a/leads/tests.py b/leads/tests.py index e45d88e0..db7f5a21 100644 --- a/leads/tests.py +++ b/leads/tests.py @@ -1,21 +1,26 @@ from django.test import TestCase from django.test import Client +from django.contrib.auth.models import User from leads.models import Lead -from common.models import Address, User +from common.models import Address, Country from accounts.models import Account class TestLeadModel(object): def setUp(self): self.client = Client() + self.country = Country.objects.create(iso_3166_1_a2="IN", + iso_3166_1_a3="IND", + iso_3166_1_numeric="001", + name="India", + printable_name="Bharath", + is_shipping_country="True") self.address = Address.objects.create(street="Gokul enclave colony", city="Hasthinapuram", state="Telangana", postcode="500079", - country='IN') - self.user = User.objects.create_superuser('user@micropyramid.com', - 'username', 'password') + country=self.country) self.account = Account.objects.create(name="account", email="account@gmail.com", @@ -23,11 +28,13 @@ class TestLeadModel(object): billing_address=Address.objects.get(pk=1), shipping_address=Address.objects.get(pk=1), website="account.com", + account_type="account", + sis_code="12345", industry="IT", - description="account", created_by=self.user) + description="account") self.lead = Lead.objects.create(title="LeadCreation", - first_name="kotha", + name="kotha", email="anjalikotha1993@gmail.com", account=self.account, address=self.address, @@ -35,8 +42,10 @@ class TestLeadModel(object): status="assigned", source="Call", opportunity_amount="700", - description="Iam an Lead", created_by=self.user) + description="Iam an Lead") + self.user = User.objects.create_superuser('user@micropyramid.com', + 'username', 'password') self.client.login(username='user@micropyramid.com', password='password') def testaddress_post_object_creation(self): @@ -47,13 +56,13 @@ class TestLeadModel(object): p = Address.objects.get(state="Telangana") self.assertEqual(p.street, "Gokul enclave colony") - # def testcountry_post_object_creation(self): - # c = Country.objects.count() - # self.assertEqual(c, 1) + def testcountry_post_object_creation(self): + c = Country.objects.count() + self.assertEqual(c, 1) - # def test_get_countryobject_with_name(self): - # p = Country.objects.get(name="India") - # self.assertEqual(p.name, "India") + def test_get_countryobject_with_name(self): + p = Country.objects.get(name="India") + self.assertEqual(p.name, "India") def test_lead_object_creation(self): c = Lead.objects.count() diff --git a/leads/urls.py b/leads/urls.py index ecbec00d..ebbd197c 100644 --- a/leads/urls.py +++ b/leads/urls.py @@ -5,15 +5,15 @@ app_name = 'leads' urlpatterns = [ - - - url(r'^list/$', views.display, name='list'), + url(r'^list/$', views.leads_list, name='list'), url(r'^create/$', views.add_lead, name='add_lead'), - url(r'^(?P\d+)/edit/$', views.edit_lead, name='edit_lead'), - url(r'^(?P\d+)/delete/$', views.delete_lead, name="delete_lead"), - url(r'^(?P\d+)/view/$', views.view_lead, name="view_lead"), - url(r'^create_comment/$', views.comment_add, name='create_comment'), - url(r'^remove_comment/$', views.comment_remove, name='remove_comment'), - url(r'^get/list/$', views.get_leads, name='get_lead'), + url(r'^(?P\d+)/view/$', views.view_lead, name="view_lead"), + url(r'^(?P\d+)/edit/$', views.edit_lead, name='edit_lead'), + url(r'^(?P\d+)/delete/$', views.remove_lead, name="remove_lead"), url(r'^(?P\d+)/convert/$', views.leads_convert, name='leads_convert'), + # comments + url(r'^comment/add/$', views.add_comment, name='add_comment'), + url(r'^comment/edit/$', views.edit_comment, name='edit_comment'), + url(r'^comment/remove/$', views.remove_comment, name='remove_comment'), + url(r'^get/list/$', views.get_leads, name='get_lead'), ] diff --git a/leads/views.py b/leads/views.py index fdec0c8f..0dafdea8 100644 --- a/leads/views.py +++ b/leads/views.py @@ -1,306 +1,329 @@ -from django.contrib.auth.models import User from django.shortcuts import render, get_object_or_404 from django.http import HttpResponseRedirect, HttpResponse, JsonResponse from django.contrib.auth.decorators import login_required +from django.urls import reverse +from django.db.models import Q +from django.views.decorators.csrf import csrf_exempt +from django.forms.models import modelformset_factory + from leads.models import Lead from contacts.forms import ContactForm -from django.views.decorators.csrf import csrf_exempt -from common.models import Address, Comment, Team -from common.utils import LEAD_STATUS, LEAD_SOURCE, INDCHOICES, TYPECHOICES -from leads.forms import CommentForm, CreateLeadform, AddressLeadForm -from django.urls import reverse +from common.models import User, Address, Comment, Team +from common.utils import LEAD_STATUS, LEAD_SOURCE, INDCHOICES, TYPECHOICES, COUNTRIES +from leads.forms import LeadCommentForm, LeadForm from accounts.forms import AccountForm -# from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger -from common.forms import BillingAddressForm, ShippingAddressForm +from common.forms import BillingAddressForm from accounts.models import Account +from planner.models import Event, Reminder +from planner.forms import ReminderForm + +# CRUD Operations Start + + +@login_required +def leads_list(request): + lead_obj = Lead.objects.all() + page = request.POST.get('per_page') + first_name = request.POST.get('first_name') + last_name = request.POST.get('last_name') + city = request.POST.get('city') + email = request.POST.get('email') + if first_name: + lead_obj = Lead.objects.filter(first_name__icontains=first_name) + if last_name: + lead_obj = Lead.objects.filter(last_name__icontains=last_name) + if city: + lead_obj = Lead.objects.filter(address=Address.objects.filter + (city__icontains=city)) + if email: + lead_obj = Lead.objects.filter(email__icontains=email) + + return render(request, 'leads/leads.html', { + 'lead_obj': lead_obj, 'per_page': page}) @login_required def add_lead(request): - acount = Account.objects.all() - countries = Country.objects.all() - assigned_user = User.objects.filter(is_active=True) + accounts = Account.objects.all() + users = User.objects.filter(is_active=True).order_by('email') + teams = Team.objects.all() + assignedto_list = request.POST.getlist('assigned_to') + teams_list = request.POST.getlist('teams') + lead_account = request.POST.get('account_name') + lead_email = request.POST.get('email') + lead_phone = request.POST.get('phone') + form = LeadForm(assigned_to=users) + address_form = BillingAddressForm() if request.method == 'POST': - address_form = AddressLeadForm(request.POST) - form = CreateLeadform(request.POST) + form = LeadForm(request.POST, assigned_to=users) + address_form = BillingAddressForm(request.POST) if form.is_valid() and address_form.is_valid(): - address_obj = address_form.save() lead_obj = form.save(commit=False) - lead_obj.address = address_obj + address_object = address_form.save() + lead_obj.address = address_object + lead_obj.created_by = request.user lead_obj.save() - return HttpResponseRedirect(reverse('leads:list')) + lead_obj.assigned_to.add(*assignedto_list) + lead_obj.teams.add(*teams_list) + if request.POST.get('status') == "converted": + Account.objects.create( + created_by=request.user, name=lead_account, + email=lead_email, phone=lead_phone + ) + if request.POST.get("savenewform"): + return HttpResponseRedirect(reverse("leads:add_lead")) + else: + return HttpResponseRedirect(reverse('leads:list')) else: return render(request, 'leads/create_lead.html', { - 'error_lead_form': form.errors, - 'error_address_form': address_form.errors, - 'acount': acount, 'countries': countries, - 'teams': TEAMS, - 'assigned_user': assigned_user, - 'status': lead_status, - 'source': lead_source}) - + 'lead_form': form, 'address_form': address_form, + 'accounts': accounts, 'countries': COUNTRIES, + 'teams': teams, 'users': users, + 'status': LEAD_STATUS, 'source': LEAD_SOURCE, + 'assignedto_list': assignedto_list, 'teams_list': teams_list}) else: return render(request, 'leads/create_lead.html', { - 'acount': acount, 'countries': countries, 'teams': TEAMS, - 'assigned_user': assigned_user, - 'status': lead_status, 'source': lead_source}) - - -@login_required -def edit_lead(request, pk): - post = get_object_or_404(Lead, id=pk) - comments = Comments.objects.filter(leadid=pk).order_by('-id') - dis_address_obj = get_object_or_404(Address, id=post.address.id) - acount = Account.objects.all() - countries = Country.objects.all() - assigned_user = User.objects.filter(is_active=True) - address_form = AddressLeadForm(instance=dis_address_obj) - form = CreateLeadform(instance=post) - - if request.method == 'POST': - - address_form = AddressLeadForm(request.POST, instance=dis_address_obj) - form = CreateLeadform(request.POST, instance=post) - - if form.is_valid() and address_form.is_valid(): - - dis_address_obj = address_form.save() - lead_obj = form.save(commit=False) - lead_obj.address = dis_address_obj - lead_obj.save() - - return HttpResponseRedirect(reverse('leads:list')) - - else: - return render(request, 'leads/create_lead.html', { - 'post': post, - 'error_lead_form': form.errors, - 'error_address_form': address_form.errors, - 'acount': acount, 'countries': countries, - 'teams': TEAMS, - 'assigned_user': assigned_user, 'comments': comments, - 'status': lead_status, 'source': lead_source}) - else: - return render(request, 'leads/create_lead.html', { - 'post': post, 'dis_address_obj': dis_address_obj, - 'acount': acount, 'countries': countries, 'teams': TEAMS, - 'assigned_user': assigned_user, 'comments': comments, - 'status': lead_status, 'source': lead_source}) - - -@login_required -def delete_lead(request, pk): - post = Lead.objects.filter(id=pk) - post.delete() - return HttpResponseRedirect(reverse('leads:list')) - - -@login_required -def display(request): - crm_task = Lead.objects.all() - count = Lead.objects.count() - dis_address_obj = Address.objects.all() - account = Account.objects.all() - if request.method == 'POST': - name = request.POST.get('name') - account = request.POST.get('account') - status = request.POST.get('status') - email = request.POST.get('email') - crm_task = Lead.objects.all() - if name: - crm_task = Lead.objects.filter(name=name) - if account: - crm_task = Lead.objects.filter(account=account) - if status: - crm_task = Lead.objects.filter(status=status) - if email: - crm_task = Lead.objects.filter(email__contains=email) - return render(request, 'leads/leads.html', { - 'crm_task': crm_task, 'dis_address_obj': dis_address_obj, - 'count': count, 'status': lead_status}) - else: - return render(request, 'leads/leads.html', { - 'dis_address_obj': dis_address_obj, 'count': count, - 'crm_task': crm_task, 'account': account, 'status': lead_status}) + 'lead_form': form, 'address_form': address_form, + 'accounts': accounts, 'countries': COUNTRIES, 'teams': teams, + 'users': users, 'status': LEAD_STATUS, 'source': LEAD_SOURCE, + 'assignedto_list': assignedto_list, 'teams_list': teams_list}) @login_required @csrf_exempt -def view_lead(request, pk): - ss = Lead.objects.get(id=pk) - crm_task = Lead.objects.all() - countries = Country.objects.all() - comments = Comments.objects.filter(leadid=pk).order_by('-id') +def view_lead(request, lead_id): + lead_record = get_object_or_404(Lead, id=lead_id) + comments = Comment.objects.filter(lead__id=lead_id).order_by('-id') + meetings = Event.objects.filter(Q(created_by=request.user) | Q(updated_by=request.user), + event_type='Meeting', attendees_leads=lead_record).order_by('-id') + calls = Event.objects.filter(Q(created_by=request.user) | Q(updated_by=request.user), + event_type='Call', attendees_leads=lead_record).order_by('-id') + RemindersFormSet = modelformset_factory(Reminder, form=ReminderForm, can_delete=True) + data = { + 'form-TOTAL_FORMS': '1', + 'form-INITIAL_FORMS': '0', + 'form-MAX_NUM_FORMS': '10', + } + reminder_form_set = RemindersFormSet(data) return render(request, "leads/view_leads.html", { - "ss": ss, 'status': lead_status, 'countries': countries, - 'crm_task': crm_task, 'comments': comments}) + "lead_record": lead_record, 'status': LEAD_STATUS, 'countries': COUNTRIES, + 'comments': comments, 'reminder_form_set': reminder_form_set, + 'meetings': meetings, 'calls': calls + }) @login_required -def get_leads(request): - if request.method == 'GET': - if request.user.is_authenticated(): - leads = Lead.objects.all() - return render(request, 'leads/leads_list.html', {'leads': leads}) - else: - return HttpResponseRedirect('accounts/login') - else: - return HttpResponse('Invalid Method or No Authanticated in load_calls') - - -@login_required -def comment_add(request): +def edit_lead(request, lead_id): + lead_obj = get_object_or_404(Lead, id=lead_id) + address_obj = get_object_or_404(Address, id=lead_obj.address.id) + accounts = Account.objects.all() + users = User.objects.filter().order_by('email') + form = LeadForm(instance=lead_obj, assigned_to=users) + address_form = BillingAddressForm(instance=address_obj) + assignedto_list = request.POST.getlist('assigned_to') + teams_list = request.POST.getlist('teams') + lead_account = request.POST.get('account_name') + lead_email = request.POST.get('email') + lead_phone = request.POST.get('phone') + teams = Team.objects.all() if request.method == 'POST': - form = CommentForm(request.POST) - if form.is_valid(): - comment = request.POST.get('comment') - f = form.save() - f.comment_user = request.user - f.save() - return JsonResponse({"error": False}) + form = LeadForm(request.POST, instance=lead_obj, assigned_to=users) + address_form = BillingAddressForm(request.POST, instance=address_obj) + if request.POST.get('status') == "converted": + form.fields['account_name'].required = True else: - return JsonResponse({"error": form.errors}) - - if request.method == "GET": - comment = request.GET.get('comment') - comment_id = request.GET.get("commentid") - com = Comments.objects.get(id=comment_id) - form = CommentForm(request.GET) - - if request.user == com.comment_user: - if form.is_valid(): - com.comment = comment - com.save() - return JsonResponse({"comment": com.comment, - "commentid": comment_id}) - else: - return JsonResponse({"error": form.errors}) + form.fields['account_name'].required = False + if form.is_valid() and address_form.is_valid(): + dis_address_obj = address_form.save() + lead_obj = form.save(commit=False) + lead_obj.address = dis_address_obj + lead_obj.created_by = request.user + lead_obj.save() + lead_obj.assigned_to.clear() + lead_obj.assigned_to.add(*assignedto_list) + lead_obj.teams.clear() + lead_obj.teams.add(*teams_list) + if request.POST.get('status') == "converted": + Account.objects.create( + created_by=request.user, name=lead_account, + email=lead_email, phone=lead_phone + ) + return HttpResponseRedirect(reverse('leads:list')) else: - return JsonResponse({"error": - "You dont have authentication to edit"}) + return render(request, 'leads/create_lead.html', { + 'lead_obj': lead_obj, + 'lead_form': form, + 'address_form': address_form, + 'accounts': accounts, 'countries': COUNTRIES, + 'teams': teams, 'users': users, + 'status': LEAD_STATUS, 'source': LEAD_SOURCE, + 'assignedto_list': assignedto_list, 'teams_list': teams_list}) else: - return render(request, "404.html") + return render(request, 'leads/create_lead.html', { + 'lead_form': form, 'address_form': address_form, + 'lead_obj': lead_obj, 'address_obj': address_obj, + 'accounts': accounts, 'countries': COUNTRIES, 'teams': teams, + 'users': users, 'status': LEAD_STATUS, 'source': LEAD_SOURCE, + 'assignedto_list': assignedto_list, 'teams_list': teams_list}) @login_required -def comment_remove(request): - if request.method == 'POST': - comment_id = request.POST.get('comment_id') - Comments.objects.get(id=comment_id).delete() - data = {"cid": comment_id} - return JsonResponse(data) - else: - return HttpResponse("Something Went Wrong") +def remove_lead(request, lead_id): + lead_obj = get_object_or_404(Lead, id=lead_id) + lead_obj.delete() + return HttpResponseRedirect(reverse('leads:list')) +# CRUD Operations Ends +# Leads Conversion Functionality Starts + + +# The Below View Should be Discussed for Functionality @login_required def leads_convert(request, pk): account_form = AccountForm() billing_form = BillingAddressForm() shipping_form = ShippingAddressForm(prefix='ship') - country_list = Country.objects.all() - users = User.objects.filter(is_active=True) - crm_task = Lead.objects.all() - post = Lead.objects.get(id=pk) - assigned_user = User.objects.filter(is_active=True) - countries = Country.objects.all() - acount = Account.objects.all() - form = ContactForm(request.POST) - address_form = AddressLeadForm(request.POST) + lead_objects = Lead.objects.all() + lead_obj = Lead.objects.get(id=pk) + accounts = Account.objects.all() + contact_form = ContactForm() + opportunity_form = OpportunityForm() + teams = Team.objects.all() if request.method == "POST": if request.POST.get('accountname') == "on": account_form = AccountForm(request.POST) billing_form = BillingAddressForm(request.POST) shipping_form = ShippingAddressForm(request.POST, prefix='ship') if account_form.is_valid() and billing_form.is_valid() and shipping_form.is_valid(): - if request.POST.get("users"): - users = User.objects.get(id=request.POST.get("users")) - users.save() billing_object = billing_form.save() shipping_object = shipping_form.save() account_object = account_form.save(commit=False) account_object.billing_address = billing_object account_object.shipping_address = shipping_object + account_object.created_by = request.user account_object.save() - post.delete() + lead_obj.delete() return HttpResponseRedirect(reverse('leads:list')) else: - street1 = request.POST.get('ship-street') - city1 = request.POST.get('ship-city') - state1 = request.POST.get('ship-state') - postcode1 = request.POST.get('ship-postcode') - country1 = request.POST.get('ship-country') - shipdata = {'street1': street1, 'city1': city1, - 'state1': state1, + street1 = request.POST.get('street') + city1 = request.POST.get('city') + state1 = request.POST.get('state') + postcode1 = request.POST.get('postcode') + country1 = request.POST.get('country') + shipdata = {'street1': street1, 'city1': city1, 'state1': state1, 'postcode1': postcode1, 'country1': country1} return render(request, 'leads/checkbox.html', { - 'account_form': account_form, - 'form1': billing_form, 'form2': shipping_form, - 'form5': country_list, - 'acc_error': account_form.errors, - 'shipdata': shipdata, - 'industries': INDCHOICES, 'types': TYPECHOICES, - 'teams': TEAMS, - 'users': users, - 'crm_task': crm_task, - "post": post, - "acount": acount, - "assigned_user": assigned_user, - "counties": countries}) + 'account_form': account_form, 'form1': billing_form, 'form2': shipping_form, + 'form5': COUNTRIES, 'stages': STAGES, 'acc_error': account_form.errors, + 'shipdata': shipdata, 'sources': LEAD_SOURCE, 'industries': INDCHOICES, + 'teams': teams, 'task': lead_objects, 'post': lead_obj, + 'accounts': accounts, + 'counties': COUNTRIES}) if request.POST.get('contactname') == "on": - if form.is_valid() and address_form.is_valid(): + contact_form = ContactForm(request.POST) + address_form = BillingAddressForm(request.POST) + if contact_form.is_valid() and address_form.is_valid(): address_obj = address_form.save() - contact_obj = form.save(commit=False) + contact_obj = contact_form.save(commit=False) contact_obj.address = address_obj + contact_obj.created_by = request.user contact_obj.save() return HttpResponseRedirect(reverse('contacts:list')) else: return render(request, 'leads/checkbox.html', { - 'post': post, - 'acount': acount, - 'teams': TEAMS, - 'err_contct_form': form.errors, - 'assigned_user': assigned_user}) + 'post': lead_obj, 'accounts': accounts, 'teams': teams, + 'contact_form': contact_form, 'address_form': address_form}) + if request.POST.get('opportunityname') == "on": + opportunity_form = OpportunityForm(request.POST) + if opportunity_form.is_valid(): + opportunity_form.save() + return HttpResponseRedirect(reverse('oppurtunities:list')) + else: + return render(request, 'leads/checkbox.html', { + 'post': lead_obj, 'accounts': accounts, 'sources': LEAD_SOURCE, + 'teams': teams, 'stages': STAGES, 'opportunity_form': opportunity_form}) else: return render(request, 'leads/checkbox.html', { - 'form': account_form, - 'form1': billing_form, 'form2': shipping_form, - 'form5': country_list, 'industries': INDCHOICES, - 'types': TYPECHOICES, 'teams': TEAMS, - 'users': users, - 'crm_task': crm_task, - "post": post, - "assigned_user": assigned_user, - "counties": countries, - 'acount': acount}) + 'form': account_form, 'form1': billing_form, 'form2': shipping_form, + 'form5': COUNTRIES, 'industries': INDCHOICES, 'teams': teams, + 'task': lead_objects, 'counties': COUNTRIES, + 'post': lead_obj, 'accounts': accounts}) -# @login_required -# def new_contact(request, pk): -# post = get_object(Lead, id=pk) -# edit_obj = get_object(Contact, id=pk) -# countri = Country.objects.all() -# acount = Account.objects.all() -# ss = Lead.objects.get(id=pk) -# assigned_user = User.objects.filter(is_active=True) +# Leads Conversion Functionality Ends +# Comments Section Start -# if request.method == 'POST': -# address_form = AddressForm(request.POST) -# form = ContactForm(request.POST) +@login_required +def add_comment(request): + if request.method == 'POST': + lead = get_object_or_404(Lead, id=request.POST.get('leadid')) + if request.user in lead.assigned_to.all() or request.user == lead.created_by: + form = LeadCommentForm(request.POST) + if form.is_valid(): + lead_comment = form.save(commit=False) + lead_comment.comment = request.POST.get('comment') + lead_comment.commented_by = request.user + lead_comment.lead = lead + lead_comment.save() + data = { + "comment_id": lead_comment.id, "comment": lead_comment.comment, + "commented_on": lead_comment.commented_on, + "commented_by": lead_comment.commented_by.user.email + } + return JsonResponse(data) + else: + return JsonResponse({"error": form['comment'].errors}) + else: + data = {'error': "You Dont Have permissions to Comment"} + return JsonResponse(data) -# if form.is_valid() and address_form.is_valid(): -# address_obj = address_form.save() -# contact_obj = form.save(commit=False) -# contact_obj.address = address_obj -# contact_obj.save() -# return HttpResponseRedirect(reverse('contacts:list')) -# else: -# return render(request, 'leads/checkbox.html', {'ss': ss, -# 'post': post, -# 'acount': acount, -# 'teams': TEAMS, -# 'err_contct_form':form.errors, -# 'edit_obj': edit_obj, -# 'assigned_user': assigned_user}) + +@login_required +def edit_comment(request): + if request.method == "POST": + comment = request.POST.get('comment') + comment_id = request.POST.get("commentid") + lead_comment = get_object_or_404(Comment, id=comment_id) + form = LeadCommentForm(request.POST) + if request.user == lead_comment.commented_by: + if form.is_valid(): + lead_comment.comment = comment + lead_comment.save() + data = {"comment": lead_comment.comment, "commentid": comment_id} + return JsonResponse(data) + else: + return JsonResponse({"error": form['comment'].errors}) + else: + return JsonResponse({"error": "You dont have authentication to edit"}) + else: + return render(request, "404.html") + + +@login_required +def remove_comment(request): + if request.method == 'POST': + comment_id = request.POST.get('comment_id') + comment = get_object_or_404(Comment, id=comment_id) + if request.user == comment.commented_by: + comment.delete() + data = {"cid": comment_id} + return JsonResponse(data) + else: + return JsonResponse({"error": "You Dont have permisions to delete"}) + else: + return HttpResponse("Something Went Wrong") + +# Comments Section End +# Other Views + + +@login_required +def get_leads(request): + if request.method == 'GET': + leads = Lead.objects.all() + return render(request, 'leads/leads_list.html', {'leads': leads}) + else: + return HttpResponse('Invalid Method or No Authanticated in load_calls') diff --git a/oppurtunity/forms.py b/oppurtunity/forms.py index 4d9c8b7a..c6ad0f14 100644 --- a/oppurtunity/forms.py +++ b/oppurtunity/forms.py @@ -4,13 +4,35 @@ from common.models import Comment class OpportunityForm(forms.ModelForm): + probability = forms.IntegerField(max_value=100, required=False) + + def __init__(self, *args, **kwargs): + assigned_users = kwargs.pop('assigned_to', []) + opp_accounts = kwargs.pop('account', []) + opp_contacts = kwargs.pop('contacts', []) + super(OpportunityForm, self).__init__(*args, **kwargs) + for field in self.fields.values(): + field.widget.attrs = {"class": "form-control"} + self.fields['description'].widget.attrs.update({ + 'rows': '8'}) + self.fields['assigned_to'].queryset = assigned_users + self.fields['account'].queryset = opp_accounts + self.fields['contacts'].queryset = opp_contacts + self.fields['assigned_to'].required = False + self.fields['teams'].required = False + self.fields['contacts'].required = False + class Meta: model = Opportunity - fields = "__all__" + fields = ( + 'name', 'amount', 'account', 'contacts', 'assigned_to', 'currency', + 'probability', 'teams', 'closed_on', 'lead_source', 'description', 'stage', + ) -class CommentForm(forms.ModelForm): +class OpportunityCommentForm(forms.ModelForm): + comment = forms.CharField(max_length=64, required=True) class Meta: model = Comment - fields = ['comment', ] + fields = ('comment', 'opportunity', 'commented_by') diff --git a/oppurtunity/tests.py b/oppurtunity/tests.py index 3fc49702..e5b70801 100644 --- a/oppurtunity/tests.py +++ b/oppurtunity/tests.py @@ -1,9 +1,9 @@ from django.test import TestCase from oppurtunity.models import Opportunity -from common.models import Address +from common.models import Country, Address from accounts.models import Account from contacts.models import Contact -from common.models import User +from django.contrib.auth.models import User # Create your tests here. @@ -11,21 +11,23 @@ from common.models import User class OpportunityModel(object): def setUp(self): + self.country = Country.objects.create( + iso_3166_1_a2="jh", iso_3166_1_a3="nh", + iso_3166_1_numeric="gt", printable_name="America", + name="India", + is_shipping_country="True") self.address = Address.objects.create( street="kphb", city="hyderabad", postcode="584", - country='IN') - self.user = User.objects.create(username='madhurima') - self.user.set_password('madhu123') - self.user.save() - + country=Country.objects.get(pk=1)) self.account = Account.objects.create( name="uday", email="uday@gmail.com", phone="58964", billing_address=self.address, shipping_address=self.address, website="hello.com", - industry="sw", description="bgyyr", created_by=self.user) + account_type="initial", + sis_code="98745", industry="sw", description="bgyyr") self.contacts = Contact.objects.create( - first_name="navi", + name="navi", email="navi@gmail.com", phone="8547", account=self.account, description="defyj", @@ -35,6 +37,9 @@ class OpportunityModel(object): stage="negotiation/review", lead_source="Call", probability="58", close_date="2016-05-04", description="hgfdxc") + self.user = User.objects.create(username='madhurima') + self.user.set_password('madhu123') + self.user.save() self.client.login(username='madhurima', password='madhu123') diff --git a/oppurtunity/urls.py b/oppurtunity/urls.py index 750404d1..d5c1fadd 100644 --- a/oppurtunity/urls.py +++ b/oppurtunity/urls.py @@ -5,16 +5,15 @@ app_name = 'oppurtunity' urlpatterns = [ - + url(r'^list/$', views.opp_list, name='list'), url(r'^create/$', views.opp_create, name='save'), - url(r'^list/$', views.opp_display, name='list'), + url(r'^(?P\d+)/view/$', views.opp_view, name='opp_view'), + url(r'^(?P\d+)/edit/$', views.opp_edit, name='opp_edit'), + url(r'^(?P\d+)/delete/$', views.opp_remove, name='opp_remove'), url(r'^contacts/$', views.contacts, name='contacts'), - url(r'^editdetails/$', views.editdetails, name='editdetails'), - url(r'^comment_add/$', views.comment_add, name='comment_add'), - url(r'^comment_edit/$', views.comment_edit, name='comment_edit'), - url(r'^comment_remove/$', views.comment_remove, name='comment_remove'), - url(r'^(?P\d+)/delete/$', views.opp_delete, name='opp_delete'), - url(r'^(?P\d+)/edit/$', views.opp_edit, name='opp_edit'), - url(r'^(?P\d+)/view/$', views.opp_view, name='opp_view'), - # url(r'^get/list/$', views.get_opportunity, name='get_opportunity'), + url(r'^get/list/$', views.get_opportunity, name='get_opportunity'), + # comments + url(r'^comment/add/$', views.add_comment, name='add_comment'), + url(r'^comment/edit/$', views.edit_comment, name='edit_comment'), + url(r'^comment/remove/$', views.remove_comment, name='remove_comment'), ] diff --git a/oppurtunity/views.py b/oppurtunity/views.py index 4bcae053..b3412ec6 100644 --- a/oppurtunity/views.py +++ b/oppurtunity/views.py @@ -1,185 +1,226 @@ +import json + from django.shortcuts import render, redirect -from django.contrib.auth.models import User from django.http import HttpResponseRedirect, HttpResponse, JsonResponse from django.contrib.auth.decorators import login_required -from accounts.models import Account -from oppurtunity.models import Opportunity -from common.models import Comment, Team -from common.utils import STAGES, SOURCES -from oppurtunity.forms import OpportunityForm, CommentForm -from contacts.models import Contact from django.shortcuts import get_object_or_404 from django.urls import reverse -import json -# Create your views here. + +from common.models import User, Comment, Team +from common.utils import STAGES, SOURCES, CURRENCY_CODES +from accounts.models import Account +from contacts.models import Contact +from oppurtunity.models import Opportunity +from oppurtunity.forms import OpportunityForm, OpportunityCommentForm + +# CRUD Operations Start + + +@login_required +def opp_list(request): + opportunity_list = Opportunity.objects.all().prefetch_related("contacts", "account") + accounts = Account.objects.all() + contacts = Contact.objects.all() + page = request.POST.get('per_page') + opp_name = request.POST.get('name') + opp_account = request.POST.get('account') + opp_contact = request.POST.get('contacts') + opp_stage = request.POST.get('stage') + opp_source = request.POST.get('lead_source') + if opp_name: + opportunity_list = Opportunity.objects.filter(name__contains=opp_name) + if opp_stage: + opportunity_list = opportunity_list.filter(stage=opp_stage) + if opp_source: + opportunity_list = opportunity_list.filter(lead_source=opp_source) + if opp_account: + opportunity_list = opportunity_list.filter(account=opp_account) + if opp_contact: + opportunity_list = opportunity_list.filter(contacts=opp_contact) + return render(request, "oppurtunity/opportunity.html", { + 'opportunity_list': opportunity_list, + 'accounts': accounts, + 'contacts': contacts, + 'stages': STAGES, + 'sources': SOURCES, + 'per_page': page + }) @login_required def opp_create(request): - users = User.objects.filter(is_active=True) - accunt = Account.objects.all() + users = User.objects.filter(is_active=True).order_by('email') + accounts = Account.objects.all() + contacts = Contact.objects.all() + form = OpportunityForm(assigned_to=users, account=accounts, contacts=contacts) + assignedto_list = request.POST.getlist("assigned_to") + teams_list = request.POST.getlist("teams") + contacts_list = request.POST.getlist("contacts") + teams = Team.objects.all() if request.method == 'POST': - form = OpportunityForm(request.POST) + form = OpportunityForm(request.POST, assigned_to=users, account=accounts, contacts=contacts) if form.is_valid(): - a = form.save() - # a.contacts.add(*(request.POST.getlist("contacts"))) - accunt = Account.objects.all() - a.users = request.user - a.save() + opportunity_obj = form.save(commit=False) + opportunity_obj.created_by = request.user + if request.POST.get('stage') in ['CLOSED WON', 'CLOSED LOST']: + opportunity_obj.closed_by = request.user + opportunity_obj.save() + opportunity_obj.assigned_to.add(*assignedto_list) + opportunity_obj.teams.add(*teams_list) + opportunity_obj.contacts.add(*contacts_list) if request.is_ajax(): return JsonResponse({'error': False}) - if request.POST.get("user"): - a.users = User.objects.get(id=request.POST.get("users")) - a.save() - if request.POST.get("teams"): - a.teams = request.POST.get("teams") - a.save() + if request.POST.get("savenewform"): + return HttpResponseRedirect(reverse("oppurtunities:save")) + else: + return HttpResponseRedirect(reverse('oppurtunities:list')) + else: if request.is_ajax(): - return HttpResponse(json.dumps({'error': False})) + return JsonResponse({'error': True, 'opportunity_errors': form.errors}) + return render(request, 'oppurtunity/create_opportunity.html', { + 'opportunity_form': form, + 'accounts': accounts, + 'users': users, + 'teams': teams, + 'stages': STAGES, + 'sources': SOURCES, + 'currencies': CURRENCY_CODES, + 'assignedto_list': assignedto_list, + 'teams_list': teams_list, + 'contacts_list': contacts_list + }) + else: + return render(request, 'oppurtunity/create_opportunity.html', { + 'opportunity_form': form, + 'accounts': accounts, + 'users': users, + 'teams': teams, + 'stages': STAGES, + 'sources': SOURCES, + 'currencies': CURRENCY_CODES, + 'assignedto_list': assignedto_list, + 'teams_list': teams_list, + 'contacts_list': contacts_list + }) + + +@login_required +def opp_view(request, pk): + opportunity_record = get_object_or_404( + Opportunity.objects.prefetch_related("contacts", "account"), id=pk) + comments = opportunity_record.opportunity_comments.all() + return render(request, 'oppurtunity/view_opportunity.html', { + 'opportunity_record': opportunity_record, + 'comments': comments + }) + + +@login_required +def opp_edit(request, pk): + opportunity_obj = get_object_or_404(Opportunity, id=pk) + users = User.objects.filter(is_active=True).order_by('email') + accounts = Account.objects.all() + contacts = Contact.objects.all() + form = OpportunityForm( + instance=opportunity_obj, assigned_to=users, account=accounts, contacts=contacts) + assignedto_list = request.POST.getlist("assigned_to") + teams_list = request.POST.getlist("teams") + contacts_list = request.POST.getlist("contacts") + teams = Team.objects.all() + if request.method == 'POST': + form = OpportunityForm( + request.POST, instance=opportunity_obj, assigned_to=users, account=accounts, + contacts=contacts + ) + if form.is_valid(): + opportunity_obj = form.save(commit=False) + opportunity_obj.created_by = request.user + if request.POST.get('stage') in ['CLOSED WON', 'CLOSED LOST']: + opportunity_obj.closed_by = request.user + opportunity_obj.save() + opportunity_obj.assigned_to.clear() + opportunity_obj.assigned_to.add(*assignedto_list) + opportunity_obj.teams.clear() + opportunity_obj.teams.add(*teams_list) + opportunity_obj.contacts.clear() + opportunity_obj.contacts.add(*request.POST.getlist("contacts")) + if request.is_ajax(): + return JsonResponse({'error': False}) return HttpResponseRedirect(reverse('oppurtunities:list')) else: + if request.is_ajax(): + return JsonResponse({'error': True, 'opportunity_errors': form.errors}) return render(request, 'oppurtunity/create_opportunity.html', { - 'stages': STAGES, 'sources': SOURCES, - 'accunt': accunt, 'teams': TEAMS, 'users': users, - 'error': form.errors}) + 'opportunity_form': form, + 'opportunity_obj': opportunity_obj, + 'accounts': accounts, + 'users': users, + 'teams': teams, + 'stages': STAGES, + 'sources': SOURCES, + 'currencies': CURRENCY_CODES, + 'assignedto_list': assignedto_list, + 'teams_list': teams_list, + 'contacts_list': contacts_list + }) else: - form = OpportunityForm() return render(request, 'oppurtunity/create_opportunity.html', { - 'form': form, 'stages': STAGES, 'sources': SOURCES, - 'accunt': accunt, 'teams': TEAMS, 'users': users}) + 'opportunity_form': form, + 'opportunity_obj': opportunity_obj, + 'accounts': accounts, + 'users': users, + 'teams': teams, + 'stages': STAGES, + 'sources': SOURCES, + 'currencies': CURRENCY_CODES, + 'assignedto_list': assignedto_list, + 'teams_list': teams_list, + 'contacts_list': contacts_list + }) + + +@login_required +def opp_remove(request, pk): + opportunity_record = get_object_or_404(Opportunity, id=pk) + opportunity_record.delete() + if request.is_ajax(): + return JsonResponse({'error': False}) + return HttpResponseRedirect(reverse('oppurtunities:list')) def contacts(request): - acc = request.GET["Account"] - account_contact = Account.objects.filter(id=acc) - contacts = Contact.objects.filter(account=account_contact) - data = {} - for i in contacts: - new = {i.pk: i.name} - data.update(new) - return JsonResponse(data) - - -@login_required -def editdetails(request): - eid = request.POST.get("tid") - edata = get_object_or_404(Opportunity, id=eid) - account = 0 - if edata.account: - account = edata.account.id - con = Contact.objects.filter(account=account) - selcon = edata.contacts.all() - print ("selcon", selcon) - contactsHtml = render(request, "oppurtunity/opp_contacts.html", { - "con": con, "selcon": selcon}) - data = {"name": edata.name, "stage": edata.stage, "close_date": edata.close_date, - "sources": edata.lead_source, "probability": edata.probability, - "description": edata.description, "account": account, "eid": eid, } - data['contacts'] = str(contactsHtml.content) + opp_account = request.GET["account"] + if opp_account: + account = get_object_or_404(Account, id=opp_account) + contacts = Contact.objects.filter(account=account) + else: + contacts = Contact.objects.all() + data = {} + for i in contacts: + new = {i.pk: i.first_name} + data.update(new) return JsonResponse(data) -@login_required -def opp_display(request): - page = request.GET.get('per_page') - count = Opportunity.objects.count() - accounts = Account.objects.all() - contacts = Contact.objects.all() - opportunity = Opportunity.objects.all() - if request.method == 'GET': - if request.GET.get('name'): - opportunity = Opportunity.objects.filter( - name__contains=request.GET.get('name')) - if request.GET.get('stage'): - opportunity = opportunity.filter( - stage=request.GET.get('stage')) - if request.GET.get('lead_source'): - opportunity = opportunity.filter( - lead_source=request.GET.get('lead_source')) - if request.GET.get('account'): - opportunity = opportunity.filter( - account=request.GET.get('account')) - if request.GET.get('contacts'): - opportunity = opportunity.filter( - contacts=request.GET.get('contacts')) - return render(request, 'oppurtunity/opportunity.html', { - 'opportunity': opportunity, 'stages': STAGES, - 'sources': SOURCES, 'accounts': accounts, 'per_page': page, - 'contacts': contacts, 'teams': TEAMS, 'count': count}) - else: - return render(request, "oppurtunity/opportunity.html", { - 'opportunity': opportunity, 'stages': STAGES, 'sources': SOURCES, - 'per_page': page, 'accounts': accounts, 'teams': TEAMS, - 'contacts': contacts, 'count': count}) +# CRUD Operations Ends +# Comments Section Start @login_required -def opp_delete(request, opp_id): - Opportunity.objects.filter(id=opp_id).delete() - if request.is_ajax(): - return HttpResponse(json.dumps({'error': False})) - return HttpResponseRedirect('/oppurtunities/list/') - - -@login_required -def opp_view(request, opp_id): - view_record = get_object_or_404(Opportunity, id=opp_id) - comments = Comments.objects.filter(oppid=opp_id).order_by('-id') - users = User.objects.all() - accunt = Account.objects.all() - contact = view_record.contacts.all() - return render(request, 'oppurtunity/view_opportunity.html', { - 'opp': view_record, 'stages': STAGES, - 'sources': SOURCES, 'accunt': accunt, 'teams': TEAMS, - 'users': users, 'contact': contact, "comments": comments}) - - -@login_required -def opp_edit(request, opp_id): - edata = get_object_or_404(Opportunity, id=opp_id) - selcon = edata.contacts.all() - con = Contact.objects.filter(account=edata.account) - edit_opp = "editing" - accunt = Account.objects.all() +def add_comment(request): if request.method == 'POST': - eid = get_object_or_404(Opportunity, id=opp_id) - form = OpportunityForm(request.POST, instance=eid) - if form.is_valid(): - form.save() - if request.is_ajax(): - return HttpResponse(json.dumps({'error': False})) - return redirect("/oppurtunities/list") - else: - if request.is_ajax(): - return JsonResponse({'error': True, 'errors_case': form.errors}) - return render(request, "oppurtunity/view_opportunity.html", { - "opp": edata, "con": con, "accunt": accunt, "selcon": selcon, - "edit_opp": edit_opp}) - assigned_user = "None" - if edata.assigned_user: - assigned_user = edata.get_assigned_user - users = User.objects.filter(is_active=True) - return render(request, "oppurtunity/view_opportunity.html", { - "opp": edata, "con": con, "accunt": accunt, "selcon": selcon, - "edit_opp": edit_opp, "users": users, "assigned_user": assigned_user}) - - -def comment_add(request): - if request.method == 'POST': - opp = get_object_or_404(Opportunity, id=request.POST.get('oppid')) - assigned = False - if opp.assigned_user: - assigned = (int(opp.assigned_user) == request.user) - if request.user == opp.users or assigned: - form = CommentForm(request.POST) + opportunity = get_object_or_404(Opportunity, id=request.POST.get('opportunityid')) + if request.user in opportunity.assigned_to.all() or request.user == opportunity.created_by: + form = OpportunityCommentForm(request.POST) if form.is_valid(): - comment = request.POST.get('comment') - comment_user = request.user - oppid = request.POST.get('oppid') - c = Comments.objects.create(comment=comment, oppid=Opportunity.objects.get(id=oppid), comment_user=comment_user) - data = {"com_id": c.id, "comment": c.comment, - "comment_time": c.comment_time, - "com_user": c.comment_user.username} + opportunity_comment = form.save(commit=False) + opportunity_comment.comment = request.POST.get('comment') + opportunity_comment.commented_by = request.user + opportunity_comment.opportunity = opportunity + opportunity_comment.save() + data = {"comment_id": opportunity_comment.id, "comment": opportunity_comment.comment, + "commented_on": opportunity_comment.commented_on, + "commented_by": opportunity_comment.commented_by.email} return JsonResponse(data) else: return JsonResponse({"error": form['comment'].errors}) @@ -189,17 +230,17 @@ def comment_add(request): @login_required -def comment_edit(request): +def edit_comment(request): if request.method == "POST": comment = request.POST.get('comment') comment_id = request.POST.get("commentid") - com = get_object_or_404(Comments, id=comment_id) - form = CommentForm(request.POST) - if request.user == com.comment_user: + comment_object = get_object_or_404(Comment, id=comment_id) + form = OpportunityCommentForm(request.POST) + if request.user == comment_object.commented_by: if form.is_valid(): - com.comment = comment - com.save() - data = {"comment": com.comment, "commentid": comment_id} + comment_object.comment = comment + comment_object.save() + data = {"comment": comment_object.comment, "commentid": comment_id} return JsonResponse(data) else: return JsonResponse({"error": form['comment'].errors}) @@ -210,13 +251,13 @@ def comment_edit(request): @login_required -def comment_remove(request): +def remove_comment(request): if request.method == 'POST': comment_id = request.POST.get('comment_id') - c = get_object_or_404(Comments, id=comment_id) - if request.user == c.comment_user: - get_object_or_404(Comments, id=comment_id).delete() - data = {"oid": comment_id} + comment_object = get_object_or_404(Comment, id=comment_id) + if request.user == comment_object.commented_by: + get_object_or_404(Comment, id=comment_id).delete() + data = {"cid": comment_id} return JsonResponse(data) else: return JsonResponse({"error": "You Dont have permisions to delete"}) @@ -224,15 +265,14 @@ def comment_remove(request): return HttpResponse("Something Went Wrong") +# Comments Section Start +# Other Views + + @login_required def get_opportunity(request): if request.method == 'GET': - if request.user.is_authenticated(): - opportunities = Opportunity.objects.all() - return render(request, 'oppurtunity/opportunities_list.html', { - 'opportunities': opportunities}) - else: - return HttpResponseRedirect('accounts/login') + opportunities = Opportunity.objects.all() + return render(request, 'oppurtunity/opportunities_list.html', {'opportunities': opportunities}) else: return HttpResponse('Invalid Method or Not Authanticated in load_calls') - return HttpResponse('Oops!! Something Went Wrong.. in load_calls') diff --git a/planner/tests.py b/planner/tests.py index 2922eb86..1c27dba6 100644 --- a/planner/tests.py +++ b/planner/tests.py @@ -2,7 +2,7 @@ import datetime from django.utils import timezone from django.test import TestCase from planner.models import Event -from common.models import User +from django.contrib.auth.models import User class EventObjects(object): @@ -14,14 +14,14 @@ class EventObjects(object): self.meeting = Event.objects.create(event_type='Meeting', name='llll', status='Not Held', description='addsdasda', start_date=timezone.now(), - close_date=timezone.now() + datetime.timedelta(days=5), created_by=self.user) + close_date=timezone.now() + datetime.timedelta(days=5), created_user=self.user) self.task = Event.objects.create(event_type='Task', name='dddl', status='Not Held', description='addsdasda', start_date=timezone.now(), - close_date=timezone.now() + datetime.timedelta(days=1), created_by=self.user) + close_date=timezone.now() + datetime.timedelta(days=1), created_user=self.user) self.call = Event.objects.create(event_type='Call', name='asdfjkas dfasdfa 555', status='Held', description='addsdasda', start_date=timezone.now(), - close_date=timezone.now() + datetime.timedelta(days=2), created_by=self.user) + close_date=timezone.now() + datetime.timedelta(days=2), created_user=self.user) class EventCreateTestCase(EventObjects, TestCase): @@ -209,14 +209,14 @@ class EventsGetViewsTestCase(EventObjects, TestCase): response = self.client.post('/planner/get/task/', { 'taskID': self.task.id }) - self.assertEqual(response.status_code, 404) + self.assertEqual(response.status_code, 200) self.assertEqual('Task', response.json()['task']['event_type']) def test_get_task_invalidID(self): response = self.client.post('/planner/get/task/', { 'taskID': 6 }) - self.assertEqual(response.status_code, 404) + self.assertEqual(response.status_code, 200) self.assertEqual({'Event': 'DoesNotExist'}, response.json()) def test_get_call_validID(self): diff --git a/static/js/contacts/view_contact.js b/static/js/contacts/view_contact.js new file mode 100644 index 00000000..7100caac --- /dev/null +++ b/static/js/contacts/view_contact.js @@ -0,0 +1,101 @@ +function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; +} + +$("#comment_form").submit(function (e) { + e.preventDefault() + var formData = new FormData($("#comment_form")[0]); + $.ajax({ + url: "/contacts/comment/add/", + type: "POST", + data: formData, + cache: false, + contentType: false, + processData: false, + success: function (data) { + if (data.error) { + $("#CommentError").html(data.error).show() + } else { + d = new Date(data.commented_on); + $("#comments_div").prepend("
  • " + + "
    " + + "
    " + + "" + + "
    " + + "
    " + data.commented_by + " Commented
    " + + "
    " + data.comment + "
    " + + "
    " + d.toGMTString() + "
  • " + ) + $("#id_comments").val("") + alert("Comment Submitted") + } + } + }) +}) + + +function edit_comment(x) { + $('#Comments_Contacts_Modal').modal('show'); + comment = $("#comment_name" + x).text() + $("#commentid").val(x) + $("#id_editcomment").val(comment) +} + +$("#comment_edit").click(function (e) { + e.preventDefault() + var formData = new FormData($("#comment_edit_form")[0]); + $.ajax({ + url: "/contacts/comment/edit/", + type: "POST", + data: formData, + cache: false, + contentType: false, + processData: false, + success: function (data) { + if (data.error) { + $("#CommentEditError").html(data.error).show() + } else { + $("#comment_name" + data.commentid).html('
    ' + data.comment + '
    ') + $('#Comments_Contacts_Modal').modal('hide'); + $("#id_editcomment").val("") + $("#CommentEditError").hide() + } + } + }) +}) + + +function HideError(e) { + $("#CommentError").hide() +} + +function remove_comment(x) { + var csrftoken = getCookie('csrftoken'); + var con = confirm("Do you want to Delete it for Sure!?") + if (con == true) { + $.post('/contacts/comment/remove/', { + "comment_id": x, + "csrfmiddlewaretoken": csrftoken, + }, function (data) { + if (data.error) { + alert(data.error) + } else { + $("#comment" + data.cid).remove() + } + }) + } +} diff --git a/static/js/opportunities/view_opportunity.js b/static/js/opportunities/view_opportunity.js new file mode 100644 index 00000000..becda37c --- /dev/null +++ b/static/js/opportunities/view_opportunity.js @@ -0,0 +1,101 @@ +function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; +} + +$("#comment_form").submit(function (e) { + e.preventDefault() + var formData = new FormData($("#comment_form")[0]); + $.ajax({ + url: "/oppurtunities/comment/add/", + type: "POST", + data: formData, + cache: false, + contentType: false, + processData: false, + success: function (data) { + if (data.error) { + $("#CommentError").html(data.error).show() + } else { + d = new Date(data.commented_on); + $("#comments_div").prepend("
  • " + + "
    " + + "
    " + + "" + + "
    " + + "
    " + data.commented_by + " Commented
    " + + "
    " + data.comment + "
    " + + "
    " + d.toGMTString() + "
  • " + ) + $("#id_comments").val("") + alert("Comment Submitted") + } + } + }) +}) + + +function edit_comment(x) { + $('#Comments_Opportunity_Modal').modal('show'); + comment = $("#comment_name" + x).text() + $("#commentid").val(x) + $("#id_editcomment").val(comment) +} + +$("#comment_edit").click(function (e) { + e.preventDefault() + var formData = new FormData($("#comment_edit_form")[0]); + $.ajax({ + url: "/oppurtunities/comment/edit/", + type: "POST", + data: formData, + cache: false, + contentType: false, + processData: false, + success: function (data) { + if (data.error) { + $("#CommentEditError").html(data.error).show() + } else { + $("#comment_name" + data.commentid).html('
    ' + data.comment + '
    ') + $('#Comments_Opportunity_Modal').modal('hide'); + $("#id_editcomment").val("") + $("#CommentEditError").hide() + } + } + }) +}) + + +function HideError(e) { + $("#CommentError").hide() +} + +function remove_comment(x) { + var csrftoken = getCookie('csrftoken'); + var con = confirm("Do you want to Delete it for Sure!?") + if (con == true) { + $.post('/oppurtunities/comment/remove/', { + "comment_id": x, + "csrfmiddlewaretoken": csrftoken, + }, function (data) { + if (data.error) { + alert(data.error) + } else { + $("#comment" + data.cid).remove() + } + }) + } +} diff --git a/templates/accounts/accounts.html b/templates/accounts/accounts.html index 74a0ecab..00cc99f7 100644 --- a/templates/accounts/accounts.html +++ b/templates/accounts/accounts.html @@ -1,220 +1,142 @@ {% extends 'base.html' %} {% load staticfiles %} -{% block content %} {% load paginate %} +{% block content %}
    - - -
    -

    Accounts

    -
    -
    -
    -
    -
    - - -
    - -
    - -
    -
    + +
    +
    +
    +

    Accounts

    +
    +
    + -
    -
    - - - -
    -
    - + + +
    +
    +
    +
    -
    - - -
    -
    -
    -
    - FILTERS -
    -
    {% csrf_token %} -
    -
    + {% csrf_token %} +
    +
    - - + +
    -
    +
    - - + +
    -
    +
    - - -
    -
    -
    -
    - +
    -
    - - -
    - -
    -
    -
    -
    - -
    -
    -
    -
    -
    - LIST OF ACCOUNTS - Total Accounts {{count}} -
    -
    - {% ifequal accounts_list|length 0 %} -
    No Acccounts Data Found
    - {% else %} - - - - - - - - - - - - - {% paginate 10 accounts_list as accounts_list %} - {% for ac in accounts_list %} - - - - - - - - - {% endfor %} - -
    S.NoNAMECITYACCOUNT TYPEINDUSTRYACTIONS
    {{ forloop.counter }}{{ ac.name }}{{ ac.billing_address.city }}{{ ac.account_type }}{{ ac.industry }} - -
    -
    -
    -
      - {% show_pages %} -
    -
    - {% endifequal %} +
    +
    + + Clear +
    +
    +
    - - - +
    + + +
    +
    +
    +
    + LIST OF ACCOUNTS + {% if show_pageitems %} {% show_pageitems %}{% else %}Total Accounts {{accounts_list|length}}{% endif %} +
    +
    + + + + + + + + + + + + + {% if per_page %} + {% paginate per_page accounts_list %} + {% else%} + {% paginate 10 accounts_list %} + {% endif %} + {% for each_account in accounts_list %} + + + + + + + + + {% endfor %} + +
    S.NoNAMECITYSTATEINDUSTRYACTIONS
    {{ forloop.counter }}{% if each_account.name %}{{ each_account.name }}{% endif %}{% if each_account.billing_address.city %}{{ each_account.billing_address.city }} {% else %} Not specified {% endif %}{% if each_account.billing_address.state %}{{ each_account.billing_address.state }} {% else %} Not specified {% endif %}{% if each_account.industry %}{{ each_account.industry }} {% else %} Not specified {% endif %} + VIEW + EDIT + +
    + {% ifequal accounts_list|length 0 %} +

    No Acccount Records Found

    + {% endifequal %} +
    + {% show_pages %} +
    +
    +
    +
    +
    +
    +
    + {% endblock %} - {% block js_block %} - - {% endblock js_block %} \ No newline at end of file diff --git a/templates/contacts/contacts.html b/templates/contacts/contacts.html index e0054ae6..da57088e 100644 --- a/templates/contacts/contacts.html +++ b/templates/contacts/contacts.html @@ -1,109 +1,60 @@ {% extends 'base.html' %} {% load staticfiles %} -{% block content %} {% load paginate %} - +{% block content %} +
    +
    -
    Contacts
    -
    -
    -
    -
    -
    - - -
    - -
    - -
    -
    -
    -
    -
    - - - -
    -
    -
    +
    +
    +

    Contacts

    -
    + +
    -
    - filters +
    -
    {%csrf_token%} -
    -
    + {%csrf_token%} +
    +
    - - -
    -
    -
    -
    - +
    -
    +
    - - + +
    -
    +
    - - + + +
    +
    +
    +
    + + Clear
    -
    - -

    @@ -111,66 +62,95 @@
    +
    LIST OF CONTACTS - Total Contacts {{count}} + {% if show_pageitems %} {% show_pageitems %}{% else %}Total Contacts {{contact_obj_list|length}}{% endif %}
    - - - - - - + + + + + + - {% paginate 10 contacts as contacts %} - {% for c in contacts %} - - - - - - + {% if per_page %} + {% paginate per_page contact_obj_list %} + {% else%} + {% paginate 10 contact_obj_list %} + {% endif %} + {% for contact in contact_obj_list %} + + + + + + {% endfor%}
    S.NoNameAccountEmail AddressCityActionsS.NoNAMEACCOUNTCITYSTATEACTIONS
    {{ forloop.counter }}{{c.name}}{{c.account}}{{c.email}}{{c.address.city}}
    {{ forloop.counter }}{{contact.first_name}} - + {% if contact.account %} + {{contact.account}} + {% else %} + No Related Account + {% endif %} + + {% if contact.address.city %} + {{contact.address.city}} + {% else %} + Not Specified + {% endif %} + + {% if contact.address.state %} + {{contact.address.state}} + {% else %} + Not Specified + {% endif %} + + View + Edit + Delete
    - {% ifequal contacts|length 0 %} -

    -
    No Contacts Found
    -

    - {%else%} -
    - + {%ifequal contact_obj_list|length 0 %} +

    No Contact Records Found

    + {%endifequal%} +
    + {% show_pages %}
    - {% endifequal %}

    +
    -{%endblock%} \ No newline at end of file + +{%endblock%} +{% block js_block %} + +{% endblock js_block %} \ No newline at end of file diff --git a/templates/contacts/create_contact.html b/templates/contacts/create_contact.html index 4ace2d95..51570dce 100644 --- a/templates/contacts/create_contact.html +++ b/templates/contacts/create_contact.html @@ -1,154 +1,144 @@ {% extends 'base.html' %} {% load staticfiles %} {% block breadcrumb %} - -{%endblock%} -{%block content%} -
    {%csrf_token%} -
    -
    -
    -
    - Assigned Users & Teams -
    -
    -
    -
    - - + +{% endblock %} +{% block content %} + {%csrf_token%} +
    +
    +
    +
    + Assigned Users & Teams
    -
    -
    -
    - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - Overview -
    -
    -
    -
    -
    +
    +
    - * - - {% if err_contct_form.name%} - {{err_contct_form.name}} - {% endif %} + + {{ contact_form.assigned_to }} + {{ contact_form.assigned_to.errors }}
    -
    +
    - * - - {% if err_contct_form.account %} - {{err_contct_form.account}} - {% endif %} + + {{ contact_form.teams }} + {{ contact_form.teams.errors }}
    -
    -
    - * - - {% if err_contct_form.phone %} - {{err_contct_form.phone}} - {% endif %} -
    -
    -
    -
    - * - - {% if err_contct_form.email %} - {{err_contct_form.email}} - {% endif %} -
    -
    -
    -
    -
    -
    - - -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -
    -
    -
    - - +

    -
    - - +
    +
    +
    +
    + Overview +
    +
    +
    +
    +
    +
    + +
    +
    + {{ contact_form.first_name }} + {{ contact_form.first_name.errors }} +
    +
    + {{ contact_form.last_name }} + {{ contact_form.last_name.errors }} +
    +
    +
    +
    +
    +
    + + {{ contact_form.account }} + {{ contact_form.account.errors }} +
    +
    +
    +
    + + {{ contact_form.phone }} + {{ contact_form.phone.errors }} +
    +
    +
    +
    + + {{ contact_form.email }} + {{ contact_form.email.errors }} +
    +
    +
    +
    +
    +
    + + {{ address_form.address_line }} + {{ address_form.address_line.errors }} +
    + {{ address_form.street }} + {{ address_form.street.errors }} +
    +
    + {{ address_form.city }} + {{ address_form.city.errors }} +
    +
    + {{ address_form.state }} + {{ address_form.state.errors }} +
    +
    + {{ address_form.postcode }} + {{ address_form.postcode.errors }} +
    +
    + {{ address_form.country }} + {{ address_form.country.errors }} +
    +
    +
    +
    +
    +
    + + {{ contact_form.description }} + {{ contact_form.description.errors }} +
    +
    +
    +
    +
    +
    +
    +
    - -
    -
    -
    -
    +
    + + {% if not contact_obj %} + + {% endif %} + Cancel +
    + {% endblock %} - - - \ No newline at end of file +{% block js_block %} + +{% endblock js_block %} diff --git a/templates/contacts/view_contact.html b/templates/contacts/view_contact.html index ffb8bb10..25cfa71c 100644 --- a/templates/contacts/view_contact.html +++ b/templates/contacts/view_contact.html @@ -1,1492 +1,223 @@ {% extends 'base.html' %} {% load staticfiles %} - -
    - - {% block breadcrumb %} - - {% endblock breadcrumb %} - {%block content%} -
    -
    -
    -
    -
    -
    -
    -
    OVERVIEW - - - -
    -
    -
    -
    -
    -
    -
    - -
    {{con.name}}
    -
    -
    -
    -
    - -
    - {%ifequal con.account None%}Not Specified - {% else %}{{con.account}}{% endifequal %} -
    -
    -
    -
    -
    - -
    {%ifequal con.phone None%}Not Specified - {% else %}{{con.phone}}{% endifequal %} -
    -
    -
    -
    -
    - -
    {%ifequal con.email None%}Not Specified - {% else %}{{con.email}}{% endifequal %} -
    -
    -
    -
    -
    -
    -
    - -
    {%ifequal con.address.street None%} - {% else %}{{con.address.street}}{% endifequal %} -
    -
    {%ifequal con.address.city None%} - {% else %}{{con.address.city}}{% endifequal %} -
    -
    {%ifequal con.address.state None%} - {% else %}{{con.address.state}}{% endifequal %} -
    -
    {%ifequal con.address.country None%} - {% else %}{{con.address.country}}{% endifequal %} -
    -
    {%ifequal con.address.postcode None%} - {% else %}{{con.address.postcode}}{% endifequal %} -
    -
    -
    -
    -
    - -
    {% if con.description%}{{con.description}}{% else%}Not Specified{% endif%}
    -
    -
    -
    +{% block breadcrumb %} + +{%endblock%} +{%block content%} + +
    +
    +
    +
    +
    +
    + OVERVIEW + + -
    -
    -
    Comments
    -
    -
    -
    -
    -
    {% csrf_token %} -
    - -
    - -
    - -
    -
      - {% for comment in comments %} -
    • -
      -
      - - -
      -
      -
      {{comment.comment_user}} Commented
      -
      {{comment.comment}}
      -
      {{comment.comment_time}}
      -
    • - {% endfor %} -
    -
    -
    - -
    -
    + +
    -
    -
    -
    -
    -
    -
    - OPPORTUNITIES - -
    - {%ifequal opportunity|length 0%} - -
    - No opportunites found -
    -
    - {%else%} -
    - - - - - - - - - - - {% for m in opportunity %} - - - - - - - {% endfor %} - -
    NameAccountstageActions
    {{ m.name }}{{ m.account }}{{ m.stage }} - -
    -
    - {%endifequal%} -
    -
    -
    -
    -
    -
    -
    - CASES - -
    - {%ifequal cases|length 0 %} - -
    - No cases found -
    -
    - {%else%} -
    - - - - - - - - - - - {% for c in cases%} - - - - - - - {% endfor %} - -
    NameStatusPriorityActions
    {{c.name}}{{c.status}}{{c.priority}} - -
    -
    - {%endifequal%} -
    -
    -
    -
    -
    -
    -
    Users
    -
    -
    -
    - -
    {%ifequal con.teams None%}Not Specified - {% else %}{{con.teams}}{% endifequal %} -
    -
    -
    -
    -
    - -
    {{con.users}}{% ifequal con.users "None"%}Not Specified{% endifequal %}
    -
    -
    -
    -
    - -
    {{con.date}}
    -
    -
    -
    -
    - -
    {{con.created_user}}
    -
    -
    -
    -
    -
    -
    -
    Activity
    -
    - -
    -
    -
    -
    - - - -
    -
    - - - {% for meeting in meetings %} - - - - - - {% endfor %} - -
    {{meeting.created_user}} created Meeting {{ meeting.name }} - -
    -
    -
    -
    -
    -
    -
    -
    History
    -
    - -
    -
    -
    -
    - - - -
    -
    -
    - - Press-conference - - Held - -
    -
    - Title come here - - date comes here - -
    -
    -
    -
    -
    -
    -
    -
    - - - - - - - {%for a in opportunity%} -