diff --git a/hosting/admin.py b/hosting/admin.py
index d8cf3012..ef6249a6 100644
--- a/hosting/admin.py
+++ b/hosting/admin.py
@@ -1,6 +1,32 @@
from django.contrib import admin
+
+from utils.mailer import BaseEmail
from .models import VirtualMachineType, VirtualMachinePlan
+class VirtualMachinePlanAdmin(admin.ModelAdmin):
+ list_display = ('name', 'id', 'email')
+
+ def email(self, obj):
+ return obj.hosting_orders.latest('id').customer.user.email
+
+ def save_model(self, request, obj, form, change):
+ email = self.email(obj)
+ if 'status' in form.changed_data and obj.status == VirtualMachinePlan.ONLINE_STATUS:
+ context = {
+ 'vm': obj
+ }
+ email_data = {
+ 'subject': 'Your VM has been activated',
+ 'to': email,
+ 'context': context,
+ 'template_name': 'vm_activated',
+ 'template_path': 'emails/'
+ }
+ email = BaseEmail(**email_data)
+ email.send()
+ obj.save()
+
+
admin.site.register(VirtualMachineType)
-admin.site.register(VirtualMachinePlan)
+admin.site.register(VirtualMachinePlan, VirtualMachinePlanAdmin)
diff --git a/hosting/migrations/0019_virtualmachineplan_status.py b/hosting/migrations/0019_virtualmachineplan_status.py
new file mode 100644
index 00000000..e1bd5382
--- /dev/null
+++ b/hosting/migrations/0019_virtualmachineplan_status.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.4 on 2016-05-26 02:57
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('hosting', '0018_virtualmachineplan_public_key'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='virtualmachineplan',
+ name='status',
+ field=models.CharField(choices=[('pending', 'Pending for activation'), ('online', 'Online')], default='online', max_length=20),
+ ),
+ ]
diff --git a/hosting/migrations/0020_auto_20160526_0258.py b/hosting/migrations/0020_auto_20160526_0258.py
new file mode 100644
index 00000000..7cafc1ac
--- /dev/null
+++ b/hosting/migrations/0020_auto_20160526_0258.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.4 on 2016-05-26 02:58
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('hosting', '0019_virtualmachineplan_status'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='virtualmachineplan',
+ name='status',
+ field=models.CharField(choices=[('pending', 'Pending for activation'), ('online', 'Online')], default='pending', max_length=20),
+ ),
+ ]
diff --git a/hosting/migrations/0021_auto_20160526_0445.py b/hosting/migrations/0021_auto_20160526_0445.py
new file mode 100644
index 00000000..90ed64b1
--- /dev/null
+++ b/hosting/migrations/0021_auto_20160526_0445.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.4 on 2016-05-26 04:45
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('hosting', '0020_auto_20160526_0258'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='virtualmachineplan',
+ name='status',
+ field=models.CharField(choices=[('pending', 'Pending for activation'), ('online', 'Online'), ('canceled', 'Canceled')], default='pending', max_length=20),
+ ),
+ ]
diff --git a/hosting/models.py b/hosting/models.py
index 55709fca..ef33c056 100644
--- a/hosting/models.py
+++ b/hosting/models.py
@@ -81,12 +81,24 @@ class VirtualMachineType(models.Model):
class VirtualMachinePlan(models.Model):
+
+ PENDING_STATUS = 'pending'
+ ONLINE_STATUS = 'online'
+ CANCELED_STATUS = 'canceled'
+
+ VM_STATUS_CHOICES = (
+ (PENDING_STATUS, 'Pending for activation'),
+ (ONLINE_STATUS, 'Online'),
+ (CANCELED_STATUS, 'Canceled')
+ )
+
cores = models.IntegerField()
memory = models.IntegerField()
disk_size = models.IntegerField()
vm_type = models.ForeignKey(VirtualMachineType)
price = models.FloatField()
public_key = models.TextField()
+ status = models.CharField(max_length=20, choices=VM_STATUS_CHOICES, default=PENDING_STATUS)
objects = VMPlansManager()
@@ -97,6 +109,10 @@ class VirtualMachinePlan(models.Model):
def hosting_company_name(self):
return self.vm_type.get_hosting_company_display()
+ @cached_property
+ def location(self):
+ return self.vm_type.get_location_display()
+
@cached_property
def name(self):
name = 'vm-%s' % self.id
diff --git a/hosting/templates/emails/new_booked_vm.html b/hosting/templates/emails/new_booked_vm.html
index 8583ba1f..2785e686 100644
--- a/hosting/templates/emails/new_booked_vm.html
+++ b/hosting/templates/emails/new_booked_vm.html
@@ -1,5 +1,5 @@
-<
+
diff --git a/hosting/templates/emails/new_booked_vm.txt b/hosting/templates/emails/new_booked_vm.txt
index 8583ba1f..2785e686 100644
--- a/hosting/templates/emails/new_booked_vm.txt
+++ b/hosting/templates/emails/new_booked_vm.txt
@@ -1,5 +1,5 @@
-<
+
diff --git a/hosting/templates/emails/vm_activated.html b/hosting/templates/emails/vm_activated.html
new file mode 100644
index 00000000..92eec368
--- /dev/null
+++ b/hosting/templates/emails/vm_activated.html
@@ -0,0 +1,13 @@
+
+{% load staticfiles bootstrap3%}
+
+
+
+
+
+
+
+ You virtual machine {{vm.name}} has been activated. You can manage your vm on this link
+
+
+
\ No newline at end of file
diff --git a/hosting/templates/emails/vm_activated.txt b/hosting/templates/emails/vm_activated.txt
new file mode 100644
index 00000000..f7f85457
--- /dev/null
+++ b/hosting/templates/emails/vm_activated.txt
@@ -0,0 +1,15 @@
+
+{% load staticfiles bootstrap3%}
+
+
+
+
+
+
+
+ You virtual machine {{vm.name}} has been activated. You can manage your vm in this link
+
+
+
+
+
\ No newline at end of file
diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html
index 55d07b86..210739d6 100644
--- a/hosting/templates/hosting/virtual_machine_detail.html
+++ b/hosting/templates/hosting/virtual_machine_detail.html
@@ -122,12 +122,16 @@
diff --git a/hosting/templates/hosting/virtual_machines.html b/hosting/templates/hosting/virtual_machines.html
index fa673c99..208d70fc 100644
--- a/hosting/templates/hosting/virtual_machines.html
+++ b/hosting/templates/hosting/virtual_machines.html
@@ -11,7 +11,7 @@
ID
- Type
+ Location
Amount
@@ -20,7 +20,7 @@
{% for vm in vms %}
{{vm.name}}
- {{vm.hosting_company_name}}
+ {{vm.location}}
{{vm.price}} CHF
View Detail
diff --git a/membership/migrations/0006_auto_20160526_0445.py b/membership/migrations/0006_auto_20160526_0445.py
new file mode 100644
index 00000000..6d92c564
--- /dev/null
+++ b/membership/migrations/0006_auto_20160526_0445.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.4 on 2016-05-26 04:45
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('auth', '0007_alter_validators_add_error_messages'),
+ ('membership', '0005_customuser_is_admin'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='customuser',
+ name='groups',
+ field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups'),
+ ),
+ migrations.AddField(
+ model_name='customuser',
+ name='is_superuser',
+ field=models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status'),
+ ),
+ migrations.AddField(
+ model_name='customuser',
+ name='user_permissions',
+ field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'),
+ ),
+ ]
diff --git a/membership/models.py b/membership/models.py
index 97d3ee06..ea235f06 100644
--- a/membership/models.py
+++ b/membership/models.py
@@ -2,7 +2,7 @@ from datetime import datetime
from django.db import models
from django.utils.translation import ugettext_lazy as _
-from django.contrib.auth.models import User, AbstractBaseUser, BaseUserManager, AbstractUser
+from django.contrib.auth.models import User, AbstractBaseUser, BaseUserManager, AbstractUser, PermissionsMixin
from django.contrib.auth.hashers import make_password
from django.core.validators import RegexValidator
from django.contrib.auth.models import User
@@ -47,7 +47,7 @@ class MyUserManager(BaseUserManager):
return user
-class CustomUser(AbstractBaseUser):
+class CustomUser(AbstractBaseUser, PermissionsMixin):
VALIDATED_CHOICES = ((0, 'Not validated'), (1, 'Validated'))
site = models.ForeignKey(Site, default=1)
name = models.CharField(max_length=50)
diff --git a/utils/mailer.py b/utils/mailer.py
index 8081152d..130b74ee 100644
--- a/utils/mailer.py
+++ b/utils/mailer.py
@@ -16,11 +16,8 @@ class BaseEmail(object):
self.subject = kwargs.get('subject')
self.context = kwargs.get('context', {})
self.template_full_path = '%s%s' % (self.template_path, self.template_name)
-
- text_content = render_to_string('%s.txt' % self.template_full_path,
- {'data': self.context})
- html_content = render_to_string('%s.html' % self.template_full_path,
- {'data': self.context})
+ text_content = render_to_string('%s.txt' % self.template_full_path, self.context)
+ html_content = render_to_string('%s.html' % self.template_full_path, self.context)
self.email = EmailMultiAlternatives(self.subject, text_content)
self.email.attach_alternative(html_content, "text/html")