diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3c49fe0a..74aaf2bd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,6 +20,7 @@ deploy_mp: - pip install -r /home/dj_crm/dj_crm/requirements.txt - python /home/dj_crm/dj_crm/manage.py migrate --noinput - sudo /etc/init.d/uwsgi restart + - sudo /usr/bin/supervisorctl restart all only: - master tags: @@ -35,6 +36,7 @@ deploy_live: - pip install -r /home/dj_crm/dj_crm/requirements.txt - python /home/dj_crm/dj_crm/manage.py migrate --noinput - sudo /etc/init.d/uwsgi restart + - sudo /usr/bin/supervisorctl restart all only: - master tags: diff --git a/Dockerfile b/Dockerfile index aa455553..1b897595 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ COPY . /app/ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - && \ apt update && \ - apt install -y git ruby-dev nodejs postgresql-client && \ + apt install -y git ruby-dev nodejs postgresql-client redis-server wkhtmltopdf && \ apt clean && \ gem install compass sass && \ npm -g install less && \ diff --git a/README.rst b/README.rst index 488d40d6..dbea41a1 100644 --- a/README.rst +++ b/README.rst @@ -80,6 +80,28 @@ Demo credentials for Django CRM: * **Password:** admin +Installation +============ + +* Install the dependencies + + .. code-block:: python + + pip install -r requirements.txt + python manage.py makemigrations + python manage.py createsuperuser + python manage.py runserver + + This will install all the required dependencies for django-crm. + After this download and install the System Requirements. + + +System Requirements +=================== + +- wkhtmltopdf (https://wkhtmltopdf.org/downloads.html) +- sass (https://www.npmjs.com/package/sass) or (https://rubygems.org/gems/sass) + Community ========= diff --git a/accounts/forms.py b/accounts/forms.py index fc5d4359..2815fbf9 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -1,6 +1,6 @@ from django import forms from .models import Account -from common.models import Comment, Attachments +from common.models import Comment, Attachments, User from leads.models import Lead from contacts.models import Contact from django.db.models import Q @@ -36,14 +36,18 @@ class AccountForm(forms.ModelForm): 'placeholder': 'Postcode'}) self.fields["billing_country"].choices = [ ("", "--Country--"), ] + list(self.fields["billing_country"].choices)[1:] - self.fields["lead"].queryset = Lead.objects.all( - ).exclude(status='closed') - if request_user: + # self.fields["lead"].queryset = Lead.objects.all( + # ).exclude(status='closed') + if request_user.role == 'ADMIN': + self.fields["lead"].queryset = Lead.objects.filter().exclude(status='closed') + self.fields["contacts"].queryset = Contact.objects.filter() + else: self.fields["lead"].queryset = Lead.objects.filter( Q(assigned_to__in=[request_user]) | Q(created_by=request_user)).exclude(status='closed') self.fields["contacts"].queryset = Contact.objects.filter( Q(assigned_to__in=[request_user]) | Q(created_by=request_user)) + self.fields['assigned_to'].required = False if account_view: self.fields['billing_address_line'].required = True self.fields['billing_street'].required = True @@ -55,7 +59,7 @@ class AccountForm(forms.ModelForm): class Meta: model = Account fields = ('name', 'phone', 'email', 'website', 'industry', - 'description', 'status', + 'description', 'status', 'assigned_to', 'billing_address_line', 'billing_street', 'billing_city', 'billing_state', 'billing_postcode', 'billing_country', 'lead', 'contacts') @@ -75,3 +79,15 @@ class AccountAttachmentForm(forms.ModelForm): class Meta: model = Attachments fields = ('attachment', 'account') + + +class EmailForm(forms.Form): + recipients = forms.CharField(max_length=500) + message_subject = forms.CharField(max_length=500) + message_body = forms.CharField(widget=forms.Textarea) + + def __init__(self, *args, **kwargs): + super(EmailForm, self).__init__(*args, **kwargs) + self.fields['message_subject'].widget.attrs['class'] = 'form-control' + self.fields['message_subject'].widget.attrs['required'] = True + self.fields['message_subject'].widget.attrs['placeholder'] = 'Email Subject' diff --git a/accounts/migrations/0007_email.py b/accounts/migrations/0007_email.py new file mode 100644 index 00000000..26f28b3d --- /dev/null +++ b/accounts/migrations/0007_email.py @@ -0,0 +1,26 @@ +# Generated by Django 2.1.7 on 2019-04-30 08:13 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contacts', '0003_merge_20190214_1427'), + ('accounts', '0006_auto_20190212_1708'), + ] + + operations = [ + migrations.CreateModel( + name='Email', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('sent_at', models.DateTimeField(auto_now_add=True)), + ('message_subject', models.TextField(null=True)), + ('message_body', models.TextField(null=True)), + ('recipient', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='recieved_email', to='contacts.Contact')), + ('sender', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sent_email', to='accounts.Account')), + ], + ), + ] diff --git a/accounts/migrations/0008_account_assigned_to.py b/accounts/migrations/0008_account_assigned_to.py new file mode 100644 index 00000000..5ed47fcf --- /dev/null +++ b/accounts/migrations/0008_account_assigned_to.py @@ -0,0 +1,20 @@ +# Generated by Django 2.1.7 on 2019-05-17 09:14 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('accounts', '0007_email'), + ] + + operations = [ + migrations.AddField( + model_name='account', + name='assigned_to', + field=models.ManyToManyField(related_name='account_assigned_users', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/accounts/models.py b/accounts/models.py index bf43f95f..4529fa09 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -6,6 +6,7 @@ from common.models import User from common.utils import INDCHOICES, COUNTRIES from phonenumber_field.modelfields import PhoneNumberField from django.utils.text import slugify +from contacts.models import Contact class Tags(models.Model): @@ -65,6 +66,8 @@ class Account(models.Model): "Name of Contact", "Contact Name"), max_length=120) contacts = models.ManyToManyField( 'contacts.Contact', related_name="account_contacts") + assigned_to = models.ManyToManyField( + User, related_name='account_assigned_users') def __str__(self): return self.name @@ -102,3 +105,23 @@ class Account(models.Model): else: address += self.get_billing_country_display() return address + + +class Email(models.Model): + sender = models.ForeignKey( + Account, related_name='sent_email', on_delete=models.SET_NULL, null=True) + + recipient = models.ForeignKey( + Contact, related_name='recieved_email', on_delete=models.SET_NULL, null=True) + + sent_at = models.DateTimeField(auto_now_add=True) + message_subject = models.TextField(null=True) + message_body = models.TextField(null=True) + + def __str__(self): + return self.message_body + + def save(self, *args, **kwargs): + # prevent user from sending messages to themselves + if self.sender.email != self.recipient.email: + super(Email, self).save(*args, **kwargs) diff --git a/accounts/tasks.py b/accounts/tasks.py new file mode 100644 index 00000000..faeac063 --- /dev/null +++ b/accounts/tasks.py @@ -0,0 +1,28 @@ +from celery.task import task +from django.conf import settings +from django.core.mail import EmailMessage +from django.template.loader import render_to_string +from accounts.models import Account, Email +from contacts.models import Contact + + +@task +def send_email(subject, html_content, from_email=None, + recipients=[]): + account = Account.objects.filter(id=from_email).first() + if account: + contacts = recipients + for contact in contacts: + contact_obj = Contact.objects.filter(email=contact).first() + if contact_obj: + Email.objects.create(sender=account, + recipient=contact_obj,message_subject=subject, + message_body=html_content) + msg = EmailMessage( + subject, + html_content, + from_email=account.email, + to=[contact_obj.email, ] + ) + msg.content_subtype = "html" + msg.send() \ No newline at end of file diff --git a/accounts/templates/accounts.html b/accounts/templates/accounts.html index ec1e69aa..0ca7b419 100644 --- a/accounts/templates/accounts.html +++ b/accounts/templates/accounts.html @@ -11,7 +11,8 @@
+
{% endif %}
| {{ forloop.counter }} | -{% if each_account.name %}{{ each_account.name }}{% endif %} | -{% if each_account.billing_city %}{{ each_account.billing_city }} {% else %} Not specified {% endif %} | -{% if each_account.billing_state %}{{ each_account.billing_state }} {% else %} Not specified {% endif %} | +{% if each_account.name %}{{ each_account.name }}{% endif %} + | +{% if each_account.billing_city %}{{ each_account.billing_city }} {% else %} Not specified + {% endif %} | +{% if each_account.billing_state %}{{ each_account.billing_state }} {% else %} Not + specified {% endif %} | {% with tags=each_account.tags.all %} {% if tags %} @@ -196,8 +217,10 @@ {% endwith %} | - - + + |