diff --git a/.gitignore b/.gitignore
index e882e145fcec335b65eaeade223514c9ce1824a0..7cd94db8e4e3b989be1fb2f7f32a11f949533709 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,5 @@ local_settings.py
 #tmp files
 appointment-import/testFiles/~*
 appointment-import/tmp.sql
+.idea
+*.iml
diff --git a/appointment-import/src/main/java/smash/appointment/parse/LihControlMappingParser.java b/appointment-import/src/main/java/smash/appointment/parse/LihControlMappingParser.java
index 3163eed9966d052bea816326d4ae3632ff2406bc..f0dc3de54d5f514defb6c882e3a20abb4d7dbd47 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/LihControlMappingParser.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/LihControlMappingParser.java
@@ -154,4 +154,9 @@ public class LihControlMappingParser extends SubjectParser {
 		return false;
 	}
 
+	@Override
+	protected boolean parsePostponed(Row row) {
+		return false;
+	}
+
 }
diff --git a/appointment-import/src/main/java/smash/appointment/parse/LihControlParser.java b/appointment-import/src/main/java/smash/appointment/parse/LihControlParser.java
index c5b587f466ee3e91a4eceabf1236072d493512bf..a99ba461e07858392db5d4947a68e25a36aa8a1a 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/LihControlParser.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/LihControlParser.java
@@ -5,7 +5,9 @@ import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
 
+import org.apache.poi.ss.usermodel.Color;
 import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.xssf.usermodel.XSSFColor;
 
 public class LihControlParser extends SubjectParser {
 
@@ -54,7 +56,7 @@ public class LihControlParser extends SubjectParser {
 		return "";
 	}
 
-	private static final SimpleDateFormat	DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
+	private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
 
 	@Override
 	protected String parseAddDate(Row row) {
@@ -123,6 +125,7 @@ public class LihControlParser extends SubjectParser {
 		remarks.add(getComments(row.getCell(14)));
 		remarks.add(getComments(row.getCell(15)));
 		remarks.add(getComments(row.getCell(16)));
+		remarks.add("Inclusion="+getString(row.getCell(17)));
 		remarks.add(getString(row.getCell(18)));
 		remarks.add(getString(row.getCell(19)));
 		String result = "";
@@ -208,8 +211,51 @@ public class LihControlParser extends SubjectParser {
 		return false;
 	}
 
+	@Override
+	protected boolean parsePostponed(Row row) {
+		Color color = row.getCell(0).getCellStyle().getFillForegroundColorColor();
+		if (color == null) {
+			return false;
+		}
+
+		XSSFColor c = (XSSFColor) color;
+		String colorString = c.getARGBHex().substring(2);
+		switch (colorString) {
+			case ("FFC000"):// orange
+				return false;
+			case ("FFFF00"):// yellow
+				return false;
+			case ("FF0000"):// red
+				return false;
+			case ("FF3399"):// pink
+				return true;
+			case ("00B050"):// green
+				return false;
+		}
+		throw new RuntimeException(parseName(row) + " " + parseSurname(row) + ": Unknown color: " + colorString);
+	}
+
 	@Override
 	protected boolean parseResigned(Row row) {
-		return false;
+		Color color = row.getCell(0).getCellStyle().getFillForegroundColorColor();
+		if (color == null) {
+			return false;
+		}
+
+		XSSFColor c = (XSSFColor) color;
+		String colorString = c.getARGBHex().substring(2);
+		switch (colorString) {
+			case ("FFC000"):// orange
+				return false;
+			case ("FFFF00"):// yellow
+				return false;
+			case ("FF0000"):// red
+				return true;
+			case ("FF3399"):// pink
+				return false;
+			case ("00B050"):// green
+				return false;
+		}
+		throw new RuntimeException(parseName(row) + " " + parseSurname(row) + ": Unknown color: " + colorString);
 	}
 }
diff --git a/appointment-import/src/main/java/smash/appointment/parse/PrcControlParser.java b/appointment-import/src/main/java/smash/appointment/parse/PrcControlParser.java
index e5802c237d7caf2c35655f27037bcafdbd151e87..7a7ec376543578b77ca3db1e2fb2206e79479f89 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/PrcControlParser.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/PrcControlParser.java
@@ -157,4 +157,9 @@ public class PrcControlParser extends SubjectParser {
 	protected boolean parseResigned(Row row) {
 		return false;
 	}
+
+	@Override
+	protected boolean parsePostponed(Row row) {
+		return false;
+	}
 }
diff --git a/appointment-import/src/main/java/smash/appointment/parse/PrcFlyingParser.java b/appointment-import/src/main/java/smash/appointment/parse/PrcFlyingParser.java
index 168a3cfdd2d3443641e12d449d819fb6bcd439be..1ee25fa2de02e448063e86233b9bf137288c0a65 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/PrcFlyingParser.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/PrcFlyingParser.java
@@ -163,5 +163,9 @@ public class PrcFlyingParser extends SubjectParser {
 	protected boolean parseResigned(Row row) {
 		return false;
 	}
+	@Override
+	protected boolean parsePostponed(Row row) {
+		return false;
+	}
 
 }
diff --git a/appointment-import/src/main/java/smash/appointment/parse/PrcSubjectsParser.java b/appointment-import/src/main/java/smash/appointment/parse/PrcSubjectsParser.java
index a06e088395e0e174ea3625507faf7affb26e1b3a..5badd40394a25d065d17796f3547427dc34c6d42 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/PrcSubjectsParser.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/PrcSubjectsParser.java
@@ -205,4 +205,9 @@ public class PrcSubjectsParser extends SubjectParser {
 			return false;
 		}
 	}
+
+	@Override
+	protected boolean parsePostponed(Row row) {
+		return false;
+	}
 }
diff --git a/appointment-import/src/main/java/smash/appointment/parse/Subject.java b/appointment-import/src/main/java/smash/appointment/parse/Subject.java
index 893fbfd450461c84d13f68ebd85ccb4c3162e942..3921389cef0d569764e03ca6d4df4f0ec86cd4f7 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/Subject.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/Subject.java
@@ -32,6 +32,7 @@ public class Subject {
 	private String			 toBeSeenAt;
 	private boolean			 dead			 = false;
 	private boolean			 resigned	 = false;
+	private boolean			 postponed = false;
 
 	private List<String> languages = new ArrayList<>();
 
@@ -476,6 +477,9 @@ public class Subject {
 		setAddDate(getMergedValue("addDate", this.getAddDate(), subject.getAddDate(), errorPrefix));
 		setmPowerId(getMergedValue("mPowerId", this.getmPowerId(), subject.getmPowerId(), errorPrefix));
 		setType(getMergedValue("type", this.getType(), subject.getType(), errorPrefix));
+		setResigned(this.isResigned()|| subject.isResigned());
+		setDead(this.isDead()|| subject.isDead());
+		setPostponed(this.isPostponed()|| subject.isPostponed());
 		// override only when to be seen by flying team
 		if (subject.getToBeSeenAt().equals("F")) {
 			setToBeSeenAt(subject.getToBeSeenAt());
@@ -566,4 +570,20 @@ public class Subject {
 		}
 	}
 
+	/**
+	 * @return the postponed
+	 * @see #postponed
+	 */
+	public boolean isPostponed() {
+		return postponed;
+	}
+
+	/**
+	 * @param postponed the postponed to set
+	 * @see #postponed
+	 */
+	public void setPostponed(boolean postponed) {
+		this.postponed = postponed;
+	}
+
 }
diff --git a/appointment-import/src/main/java/smash/appointment/parse/SubjectParser.java b/appointment-import/src/main/java/smash/appointment/parse/SubjectParser.java
index 6292d3cb961547a986c42b59c3b0d665d2225bd9..f979012b76b8562a4757c6fa63ba1e6e3a408bbe 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/SubjectParser.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/SubjectParser.java
@@ -91,11 +91,13 @@ public abstract class SubjectParser {
 		result.setToBeSeenAt(parseToBeSeenAt(row));
 		result.setDead(parseDead(row));
 		result.setResigned(parseResigned(row));
+		result.setPostponed(parsePostponed(row));
 
 		return result;
 	}
 
 	protected abstract boolean parseDead(Row row);
+	protected abstract boolean parsePostponed(Row row);
 
 	protected abstract boolean parseResigned(Row row);
 
diff --git a/appointment-import/src/main/java/smash/appointment/parse/SubjectSqlExporter.java b/appointment-import/src/main/java/smash/appointment/parse/SubjectSqlExporter.java
index ebbd5866b0fa122704b3a0ef8a160a234372147b..5c59412dfbd387afab381b8e4d824dc47a7baa4d 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/SubjectSqlExporter.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/SubjectSqlExporter.java
@@ -30,6 +30,7 @@ public class SubjectSqlExporter extends SqlExporter {
 		result.append("dead,");
 		result.append("default_written_communication_language_id,");
 		result.append("resigned,");
+		result.append("postponed,");
 		result.append("date_born) ");
 
 		result.append("values (");
@@ -74,6 +75,7 @@ public class SubjectSqlExporter extends SqlExporter {
 			result.append("null,");
 		}
 		result.append(subject.isResigned() + ",");
+		result.append(subject.isPostponed() + ",");
 		result.append(getDateVal(subject.getBirthDate()));
 		result.append(");\n");
 
diff --git a/appointment-import/src/main/java/smash/appointment/parse/VisitSqlExporter.java b/appointment-import/src/main/java/smash/appointment/parse/VisitSqlExporter.java
index 6ffef703b3104abf444a31be9942ea409f59fa9b..7dbc577be9f30d938861ad6e5f4ff03d9e6e57ea 100644
--- a/appointment-import/src/main/java/smash/appointment/parse/VisitSqlExporter.java
+++ b/appointment-import/src/main/java/smash/appointment/parse/VisitSqlExporter.java
@@ -12,12 +12,14 @@ public class VisitSqlExporter extends SqlExporter {
 		result.append("subject_id,	 ");
 		result.append("datetime_begin, ");
 		result.append("datetime_end, ");
+		result.append("post_mail_sent, ");
 		result.append("is_finished)");
 
 		result.append("values (");
 		result.append("(SELECT id from web_subject where screening_number = "+getStringVal(visit.getSubject().getScreeningNumber()) + "),");
 		result.append(getStringVal(visit.getStartDate()) + ",");
 		result.append(getStringVal(visit.getEndDate()) + ",");
+		result.append("false,");
 		result.append(visit.isFinished());
 		result.append(");\n");
 		for (AppointmentEntry entry: visit.getAppointments()) {
diff --git a/appointment-import/src/test/java/smash/appointment/parse/LihControlParserTest.java b/appointment-import/src/test/java/smash/appointment/parse/LihControlParserTest.java
index bce5ee61b716e85c661cbae9db0ff0c792362469..05845e0558f5930907eaf9443d413a37d35762d8 100644
--- a/appointment-import/src/test/java/smash/appointment/parse/LihControlParserTest.java
+++ b/appointment-import/src/test/java/smash/appointment/parse/LihControlParserTest.java
@@ -1,6 +1,8 @@
 package smash.appointment.parse;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import java.util.List;
 
@@ -11,17 +13,16 @@ import org.junit.Before;
 import org.junit.Test;
 
 public class LihControlParserTest extends TestBase {
-	Logger						logger		= Logger.getLogger(LihControlParserTest.class);
-
-	LihControlParser processor	= new LihControlParser();
+	Logger					 logger		 = Logger.getLogger(LihControlParserTest.class);
 
+	LihControlParser processor = new LihControlParser();
 
 	@AfterClass
 	public static void tearDownAfterClass() throws Exception {
 	}
 
 	@Before
-	public void setUp()  {
+	public void setUp() {
 		super.setUp();
 	}
 
@@ -31,8 +32,9 @@ public class LihControlParserTest extends TestBase {
 
 	@Test
 	public void testParseLang() throws Exception {
-		assertEquals("English",processor.getMappedLanguage("EN"));
+		assertEquals("English", processor.getMappedLanguage("EN"));
 	}
+
 	@Test
 	public void test() throws Exception {
 		List<Subject> entries = processor.processExcel("testFiles/lihControlExample.xlsx");
@@ -43,7 +45,7 @@ public class LihControlParserTest extends TestBase {
 		assertEquals("Name", subject.getName());
 		assertEquals("Surname", subject.getSurname());
 		assertTrue(subject.getRemarks().contains("001 rdv 01/09/2015 9h jyf"));
-		assertTrue(subject.getRemarks().contains("PD family relation=pd info"));		
+		assertTrue(subject.getRemarks().contains("PD family relation=pd info"));
 		assertEquals("11, Rue blabla", subject.getAddress());
 		assertEquals("L-3322", subject.getZipCode());
 		assertEquals("Luxembourg", subject.getCity());
@@ -58,11 +60,9 @@ public class LihControlParserTest extends TestBase {
 		assertNotNull(subject.getAddDate());
 		assertEquals("", subject.getNdNumber());
 		assertEquals("1937-01-03", subject.getBirthDate());
-		assertTrue(subject.getRemarks().contains("some other remark"));		
-		assertTrue(subject.getRemarks().contains("at home: NMS + RFQ 1 + RFQ 2 + REM + PDSS: manque une page ds RFQ => Linda pr level b 09/09/15"));		
-		assertTrue(subject.getLanguages().contains("French"));		
-		assertTrue(subject.getLanguages().contains("German"));		
+		assertTrue(subject.getRemarks().contains("some other remark"));
+		assertTrue(subject.getRemarks().contains("at home: NMS + RFQ 1 + RFQ 2 + REM + PDSS: manque une page ds RFQ => Linda pr level b 09/09/15"));
+		assertTrue(subject.getLanguages().contains("French"));
+		assertTrue(subject.getLanguages().contains("German"));
 	}
-
-
 }
diff --git a/readme.md b/readme.md
index ebabb3fd11f567f25326f7af08f3fb79a0a438a3..3214f721cf79429cc6476a7ac6604496677cc83d 100644
--- a/readme.md
+++ b/readme.md
@@ -14,39 +14,8 @@
   - `virtualenv env` to create new virtualenv (contains clean python working environment)
   - `. env/bin/activate` (to start using virtualenv)
   - `pip install -r requirements.txt` to install project's dependencies
-  - Create `local_settings.py` file in `(./scheduling-system)/smash/smash` directory (see template below), and change your database connection data:
+  - Create `local_settings.py` file in `(./scheduling-system)/smash/smash` directory by copying the template in `(./scheduling-system)/smash/smash/local_settings.template` and edit your local_setttings.py file to change your database connection data.
 
-```
-# SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = 'Paste long random string here' # Insert long random string
-
-# SECURITY WARNING: don't run with debug turned on in production!
-DEBUG = True
-
-WSGI_APPLICATION = 'smash.wsgi.application'
-
-
-# Database
-# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
-
-DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.postgresql_psycopg2',
-        'NAME': 'smashdb', # Insert your database's name
-        'USER': 'postgresmashuser', # Insert your database's user
-        'PASSWORD': 'thePOSTGRESpassword', # Insert your user's password
-        'HOST': 'localhost',
-        'PORT': '' # '' === default one # Empty string is OK
-
-        # If to use sqlite
-        # 'ENGINE': 'django.db.backends.sqlite3',
-        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
-    }
-}
-
-STATIC_ROOT = '/tmp/static' # Warning! `/tmp` directory can be flushed in any moment; use a persistent one; e.g. ~/tmp/static
-MEDIA_ROOT = '/tmp/media' # Warning! `/tmp` directory can be flushed in any moment; use a persistent one, e.g. ~/tmp/media
-```
  - Update migration db scrpit from file structure (`./scheduling-system/smash/manage.py makemigrations`)
  - Create the database by applying migrations (`./scheduling-system/smash/manage.py migrate`)
  - Create the first, administrative, user-  (`./scheduling-system/smash/manage.py createsuperuser`)
diff --git a/requirements.txt b/requirements.txt
index 8ddce39523486fbd85b734c6cc1a11d671a2be22..57e916dd630ac9a2b6f598607e37f97050cce20b 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,4 @@
 Django==1.10.3
 gunicorn==19.6.0
 Pillow==3.4.2
-pkg-resources==0.0.0
 psycopg2==2.6.2
diff --git a/smash/smash/local_settings.py.template b/smash/smash/local_settings.py.template
new file mode 100644
index 0000000000000000000000000000000000000000..b5c398c064b0b58992f6adf380bdb94b6ebc15a9
--- /dev/null
+++ b/smash/smash/local_settings.py.template
@@ -0,0 +1,29 @@
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'Paste long random string here' # Insert long random string
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+WSGI_APPLICATION = 'smash.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.postgresql_psycopg2',
+        'NAME': 'smashdb', # Insert your database's name
+        'USER': 'postgresmashuser', # Insert your database's user
+        'PASSWORD': 'thePOSTGRESpassword', # Insert your user's password
+        'HOST': 'localhost',
+        'PORT': '' # '' === default one # Empty string is OK
+
+        # If to use sqlite
+        # 'ENGINE': 'django.db.backends.sqlite3',
+        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+    }
+}
+
+STATIC_ROOT = '/tmp/static' # Warning! `/tmp` directory can be flushed in any moment; use a persistent one; e.g. ~/tmp/static
+MEDIA_ROOT = '/tmp/media' # Warning! `/tmp` directory can be flushed in any moment; use a persistent one, e.g. ~/tmp/media
diff --git a/smash/web/api_urls.py b/smash/web/api_urls.py
index 15e088c588272d0656c5c81f770317c7421c8e24..f607052acc2eb332339cbdbcff5909822274f772 100644
--- a/smash/web/api_urls.py
+++ b/smash/web/api_urls.py
@@ -17,9 +17,10 @@ from django.conf.urls import url
 from web import api_views
 
 urlpatterns = [
-    url(r'cities$', api_views.cities, name='web.api.cities'),
-    url(r'countries$', api_views.countries, name='web.api.countries'),
-    url(r'specializations$', api_views.specializations, name='web.api.specializations'),
-    url(r'units$', api_views.units, name='web.api.units'),
-    url(r'referrals$', api_views.referrals, name='web.api.referrals'),
+    url(r'^cities$', api_views.cities, name='web.api.cities'),
+    url(r'^countries$', api_views.countries, name='web.api.countries'),
+    url(r'^specializations$', api_views.specializations, name='web.api.specializations'),
+    url(r'^units$', api_views.units, name='web.api.units'),
+    url(r'^referrals$', api_views.referrals, name='web.api.referrals'),
+    url(r'^appointment_types$', api_views.appointment_types, name='web.api.appointment_types'),
 ]
diff --git a/smash/web/api_views.py b/smash/web/api_views.py
index b08f7c70d49118997adaaecace3f8279e9988271..d4234e9e8eb8f5807e7fcd5f9280cb528772a5ec 100644
--- a/smash/web/api_views.py
+++ b/smash/web/api_views.py
@@ -43,3 +43,18 @@ def units(request):
     return JsonResponse({
         "units" : [x[0] for x in X]
     })
+
+@login_required
+def appointment_types(request):
+    appointments = AppointmentType.objects.filter().all()
+    result = []
+    for appointment in appointments:
+        result.append({
+            "id": appointment.id,
+            "type": appointment.code,
+            "default_duration": appointment.default_duration,
+            "can_be_parallelized": appointment.can_be_parallelized,
+        })
+    return JsonResponse({
+        "appointment_types" : result
+    })
diff --git a/smash/web/forms.py b/smash/web/forms.py
index 5df96b139a5ce82909d37a17021ccff7dca13724..5b1d8c25a19162761a85cd8fd9ead0a5a2d07565 100644
--- a/smash/web/forms.py
+++ b/smash/web/forms.py
@@ -1,5 +1,5 @@
 from django import forms
-from django.forms import ModelForm
+from django.forms import ModelForm, Form
 from .models import *
 from datetime import datetime
 
@@ -35,6 +35,11 @@ class SubjectAddForm(ModelForm):
         required=False
     )
 
+    datetime_contact_reminder = forms.DateField(label="Contact on",
+        widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
+        required=False
+    )
+
     class Meta:
         model = Subject
         fields = '__all__'
@@ -56,6 +61,11 @@ class SubjectDetailForm(ModelForm):
 
 
 class SubjectEditForm(ModelForm):
+
+    datetime_contact_reminder = forms.DateField(label="Contact on",
+        widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
+        required=False
+    )
     date_born = forms.DateField(label="Date of birth",
         widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
         required=False
@@ -135,6 +145,8 @@ class VisitDetailForm(ModelForm):
         widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d")
     )
 
+    post_mail_sent = forms.RadioSelect()
+
     class Meta:
         model = Visit
         exclude = ['is_finished']
@@ -156,3 +168,14 @@ class VisitAddForm(ModelForm):
         if (self.cleaned_data['datetime_begin']>=self.cleaned_data['datetime_end']):
             self.add_error('datetime_begin', "Start date must be before end date")
             self.add_error('datetime_end', "Start date must be before end date")
+
+class KitRequestForm(Form):
+    start_date = forms.DateField(label="From date",
+        widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
+        required=False
+    )
+
+    end_date = forms.DateField(label="End date",
+        widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
+        required=False
+    )
diff --git a/smash/web/models.py b/smash/web/models.py
index 170690befbed6227eebfec5f2b8a61208187b113..71df4a06b74a8a6979d809b9b40aa8ef58ff273e 100644
--- a/smash/web/models.py
+++ b/smash/web/models.py
@@ -10,6 +10,8 @@ from datetime import timedelta
 def get_current_year():
     return datetime.datetime.now().year
 
+BOOL_CHOICES = ((True, 'Yes'), (False, 'No'))
+
 class Location (models.Model):
     name = models.CharField(max_length=20)
 
@@ -81,6 +83,15 @@ class Subject(models.Model):
         choices=SEX_CHOICES,
         verbose_name='Sex'
     )
+    postponed  = models.BooleanField(choices=BOOL_CHOICES,
+        verbose_name='Postponed',
+        default=False
+    )
+    datetime_contact_reminder = models.DateField(
+        null=True,
+	    blank=True,
+        verbose_name='Contact on',
+    )
     type = models.CharField(max_length=1,
         choices=SUBJECT_TYPE_CHOICES,
         verbose_name='Type'
@@ -122,17 +133,17 @@ class Subject(models.Model):
     )
     phone_number_2 = models.CharField(max_length=20,
         null=True,
-	blank=True,
+	    blank=True,
         verbose_name='Phone number 2'
     )
     phone_number_3 = models.CharField(max_length=20,
         null=True,
-	blank=True,
+	    blank=True,
         verbose_name='Phone number 3'
     )
     email = models.EmailField(
         null=True,
-	blank=True,
+	    blank=True,
         verbose_name='E-mail'
     )
     date_born = models.DateField(
@@ -214,6 +225,12 @@ class Item (models.Model):
         default=False,
         verbose_name='Is the item fixed?'
     )
+
+    disposable = models.BooleanField(
+        default=False,
+        verbose_name='Disposable set'
+    )
+
     name = models.CharField(max_length=255,
         verbose_name='Name'
     )
@@ -291,6 +308,10 @@ class AppointmentType (models.Model):
         verbose_name='Suggested rest time',
         default=0
     )
+    can_be_parallelized = models.BooleanField(
+        verbose_name='Can be parallelized',
+        default=False
+    )
     REQ_ROLE_CHOICES = (
         ('DOCTOR', 'Doctor'),
         ('NURSE', 'Nurse'),
@@ -473,7 +494,10 @@ class Visit(models.Model):
         verbose_name='Has ended',
         default=False
     )
-
+    post_mail_sent  = models.BooleanField(choices=BOOL_CHOICES,
+        verbose_name='Post mail sent',
+        default=False
+    )
     appointment_types = models.ManyToManyField(AppointmentType,
         verbose_name='Requested appointments',
         blank=True,
diff --git a/smash/web/static/js/appointment.js b/smash/web/static/js/appointment.js
new file mode 100644
index 0000000000000000000000000000000000000000..a195413e582bf2a7569a3c57b140e9331164bf1b
--- /dev/null
+++ b/smash/web/static/js/appointment.js
@@ -0,0 +1,44 @@
+function appointment_type_begaviour(selectObj, outObject,api_call) {
+  var appointment_types_data = null;
+
+  function get_appointment_type_by_id(id) {
+    for (var i=0 ;i <appointment_types_data.length;i++) {
+      if (id == appointment_types_data[i].id) {
+        return appointment_types_data[i];
+      }
+    }
+    return null;
+  }
+  function compute_time(object) {
+    var vals = object.val();
+    var time = 0;
+    var max_paralel_time = 0;
+    for (var i=0;i<vals.length;i++) {
+      var appointment_type = get_appointment_type_by_id(vals[i]);
+      if (appointment_type== null) {
+        console.log("Cannot find appointment type with id: "+vals[i]);
+      } else {
+        if (appointment_type.can_be_parallelized) {
+          max_paralel_time = Math.max(max_paralel_time,appointment_type.default_duration);
+        } else {
+          time +=appointment_type.default_duration;
+        }
+      }
+    }
+    time = Math.max(time, max_paralel_time)
+    $(outObject).val(time+"");
+  }
+  $(selectObj ).change(function() {
+    var object = $(this)
+    if (appointment_types_data===null) {
+      $.get(api_call, function(data) {
+        appointment_types_data= data.appointment_types;
+        compute_time(object);
+      });
+    } else {
+      compute_time(object);
+    }
+
+  });
+
+}
diff --git a/smash/web/templates/appointments/add.html b/smash/web/templates/appointments/add.html
index ea975643a3f0a4fe536878447e77c41fc709adf8..5b1bcef0884cf18657badba9c33d1ea6e5e61408 100644
--- a/smash/web/templates/appointments/add.html
+++ b/smash/web/templates/appointments/add.html
@@ -95,6 +95,7 @@
 	<script src="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js' %}"></script>
   <script src="{% static 'AdminLTE/plugins/moment.js/moment.min.js' %}"></script>
 	<script src="{% static 'AdminLTE/plugins/fullcalendar/fullcalendar.min.js' %}"></script>
+  <script src="{% static 'js/appointment.js' %}"></script>
 	<script>
 		$(function () {
 			$('#table').DataTable({
@@ -152,6 +153,8 @@
 			});
 
 		});
+
+    appointment_type_begaviour($("[name='appointment_types']"), $("[name='length']"), "{% url 'web.api.appointment_types' %}");
 	</script>
 
   {% include "includes/datetimepicker.js.html" %}
diff --git a/smash/web/templates/appointments/edit.html b/smash/web/templates/appointments/edit.html
index 50d598d8065e3e7f6bf13f1889d0285fd5b762c0..8663014d7112a134ad02e617b655c0733fb68862 100644
--- a/smash/web/templates/appointments/edit.html
+++ b/smash/web/templates/appointments/edit.html
@@ -120,6 +120,7 @@
 
 	<script src="{% static 'AdminLTE/plugins/datatables/jquery.dataTables.min.js' %}"></script>
 	<script src="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js' %}"></script>
+  <script src="{% static 'js/appointment.js' %}"></script>
 	<script>
 		$(function () {
 			$('#table').DataTable({
@@ -131,6 +132,7 @@
 			  "autoWidth": false
 			});
 		});
+    appointment_type_begaviour($("[name='appointment_types']"), $("[name='length']"), "{% url 'web.api.appointment_types' %}");
 	</script>
 
   {% include "includes/datetimepicker.js.html" %}
diff --git a/smash/web/templates/appointments/index.html b/smash/web/templates/appointments/index.html
index 3e35a34f8672051eaef93d2a2c22d3b68566d9a4..32897aeadf746587ad0387a02aa207d89e557d2c 100644
--- a/smash/web/templates/appointments/index.html
+++ b/smash/web/templates/appointments/index.html
@@ -134,7 +134,7 @@
 			  "lengthChange": false,
 			  "searching": true,
 			  "ordering": true,
-        "order": [[ 2, "asc"]],
+        "order": [[ 3, "asc"]],
 			  "info": true,
 			  "autoWidth": false
 			});
diff --git a/smash/web/templates/equipment_and_rooms/index.html b/smash/web/templates/equipment_and_rooms/index.html
index 6c7a5f4fb99b8217171a0f4d0739cd09df2405e6..95d68215f8a6193d98efb7ef6bf61095c662c7fb 100644
--- a/smash/web/templates/equipment_and_rooms/index.html
+++ b/smash/web/templates/equipment_and_rooms/index.html
@@ -10,6 +10,7 @@
 {% endblock breadcrumb %}
 
 {% block maincontent %}
+{% comment %}
 <div class="box box-danger box-solid">
   <div class="box-header with-border">
     <h3 class="box-title">Not yet implemented</h3>
@@ -27,8 +28,12 @@
   <!-- /.box-body -->
 </div>
 
+{% endcomment %}
+
 <div class="row">
+  {% comment %}
 	<div class="col-md-3">
+
 		<div class="bg-red-active small-box">
 			<div class="inner">
 			  <h4>Types of equipment</h4>
@@ -71,22 +76,24 @@
 			</a>
 		</div>
 	</div>
+  {% endcomment %}
 
 	<div class="col-md-3">
 		<div class="bg-yellow-active small-box">
 			<div class="inner">
-			  <h4>Equipment requests</h4>
+			  <h4>Kit requests</h4>
 
 			  <p>&nbsp;</p>
 			</div>
 			<div class="icon">
 			  <i class="ion ion-compose"></i>
 			</div>
-			<a href="#" class="small-box-footer">
-			  Edit <i class="fa fa-arrow-circle-right"></i>
+			<a href="{% url 'web.views.kit_requests' %}" class="small-box-footer">
+			  See <i class="fa fa-arrow-circle-right"></i>
 			</a>
 		</div>
 
+    {% comment %}
 		<div class="bg-yellow small-box">
 			<div class="inner">
 			  <h4>Equipment in rooms</h4>
@@ -100,8 +107,10 @@
 			  Edit <i class="fa fa-arrow-circle-right"></i>
 			</a>
 		</div>
+    {% endcomment %}
 	</div>
 
+  {% comment %}
 	<div class="col-md-3">
 		<div class="bg-green-active small-box">
 			<div class="inner">
@@ -145,5 +154,7 @@
 			</a>
 		</div>
 	</div>
+  {% endcomment %}
+
 </div>
 {% endblock maincontent %}
diff --git a/smash/web/templates/equipment_and_rooms/kit_requests.html b/smash/web/templates/equipment_and_rooms/kit_requests.html
new file mode 100644
index 0000000000000000000000000000000000000000..b9881bd23f51782703c9782bd84cf63f094082e3
--- /dev/null
+++ b/smash/web/templates/equipment_and_rooms/kit_requests.html
@@ -0,0 +1,103 @@
+{% extends "_base.html" %}
+
+{% block ui_active_tab %}'equipment_and_rooms'{% endblock ui_active_tab %}
+{% block page_header %}
+  Kits required between {{ start_date | date:"Y-m-d" }} and {% if end_date %}  {{ end_date | date:"Y-m-d" }} {% else %} end of time {% endif %}
+{% endblock page_header %}
+{% block page_description %}
+{% endblock page_description %}
+
+{% block styles %}
+{{ block.super }}
+	{% include "includes/datepicker.css.html" %}
+{% endblock styles %}
+
+{% block breadcrumb %}
+{% include "equipment_and_rooms/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+{% block content %}
+<div class="box box-info">
+  <form method="post" action="" class="form-horizontal">
+		{% csrf_token %}
+
+		<div class="box-body">
+      <div class="col-sm-6">
+  			{% for field in form %}
+  				<div class="form-group {% if field.errors %}has-error{% endif %}">
+  					<label class="col-sm-4 control-label">
+  						{{ field.label }}
+  					</label>
+
+  					<div class="col-sm-8">
+  						{{ field }}
+  					</div>
+
+  					{% if field.errors %}
+  						<span class="help-block">
+  							{{ field.errors }}
+  						</span>
+  					{% endif %}
+  				</div>
+  			{% endfor %}
+      </div>
+		</div>
+
+    <div class="box-footer">
+			<div class="col-sm-6">
+				<button type="submit" class="btn btn-block btn-success">Search</button>
+			</div>
+		</div><!-- /.box-footer -->
+
+	</form>
+
+	<div class="box col-md-12">
+    <table id="visit_table" class="table table-bordered table-striped">
+        <thead>
+      <tr>
+        <th>Date</th>
+        <th>Kits</th>
+      </tr>
+    </thead>
+      <tbody>
+        {% for appointment in appointments %}
+        <tr>
+          <td>{{ appointment.datetime_when | date:"Y-m-d H:i"}} </td>
+          <td>
+            {% for type in appointment.appointment_types.all %}
+              {% for item in type.required_equipment.all %}
+                {% if item.disposable %}
+                  {{ item.name }},
+                {% endif %}
+              {% endfor %}
+            {% endfor %}
+          </td>
+        </tr>
+        {% endfor %}
+      </tbody>
+    </table>
+
+    <div class="box-footer">
+			<div class="col-sm-12">
+        {% if end_date == None %}
+          <a href="{% url 'web.views.kit_requests_send_mail' start_date|date:"Y-m-d" %}" class="btn btn-block btn-default">Show email content</a>
+        {% else %}
+          <a href="{% url 'web.views.kit_requests_send_mail' start_date|date:"Y-m-d" end_date|date:"Y-m-d" %}" class="btn btn-block btn-default">Show email content</a>
+        {% endif %}
+			</div>
+		</div><!-- /.box-footer -->
+
+	</div>
+
+
+</div>
+{% endblock %}
+{% endblock maincontent %}
+
+{% block scripts %}
+	{{ block.super }}
+
+  {% include "includes/datepicker.js.html" %}
+{% endblock scripts %}
diff --git a/smash/web/templates/equipment_and_rooms/kit_requests_send_mail.html b/smash/web/templates/equipment_and_rooms/kit_requests_send_mail.html
new file mode 100644
index 0000000000000000000000000000000000000000..1c89a616bcb4c2e997d28b80d126e91908109cec
--- /dev/null
+++ b/smash/web/templates/equipment_and_rooms/kit_requests_send_mail.html
@@ -0,0 +1,26 @@
+<h1>Kits required between {{ start_date }} and {% if end_date %}  {{ end_date }} {% else %} end of time {% endif %}</h1>
+<table>
+  <thead>
+    <tr>
+      <th>Date</th>
+      <th>Kits</th>
+    </tr>
+  </thead>
+  <tbody>
+
+    {% for appointment in appointments %}
+      <tr>
+        <td>{{ appointment.datetime_when | date:"Y-m-d H:i"}}     </td>
+        <td>
+            {% for type in appointment.appointment_types.all %}
+              {% for item in type.required_equipment.all %}
+                {% if item.disposable %}
+                  {{ item.name }},
+                {% endif %}
+              {% endfor %}
+            {% endfor %}
+        </td>
+      </tr>
+    {% endfor %}
+  </tbody>
+</table>
diff --git a/smash/web/templates/includes/tablesorter.tfoot.html b/smash/web/templates/includes/tablesorter.tfoot.html
index d345ac6c9fce001a6ff774b90df66510581cdd28..b5b5536af2b6a4ecf9c852fc849fd0fb8cae96f7 100644
--- a/smash/web/templates/includes/tablesorter.tfoot.html
+++ b/smash/web/templates/includes/tablesorter.tfoot.html
@@ -1,6 +1,6 @@
 <tfoot>
 <tr>
-  <th colspan="7" class="ts-pager form-inline">
+  <th colspan="8" class="ts-pager form-inline">
     <div class="btn-group btn-group-sm" role="group">
       <button type="button" class="btn btn-default first"><span class="glyphicon glyphicon-step-backward"></span></button>
       <button type="button" class="btn btn-default prev"><span class="glyphicon glyphicon-backward"></span></button>
@@ -19,4 +19,4 @@
     <select class="form-control input-sm pagenum" title="Select page number"></select>
   </th>
 </tr>
-</tfoot>
\ No newline at end of file
+</tfoot>
diff --git a/smash/web/templates/login.html b/smash/web/templates/login.html
index 1cdc90f5f1873ce649bce6ae8e710345fdb4838a..86b7238f0d148e5aa3ec9416c1a945840e9f0a5c 100644
--- a/smash/web/templates/login.html
+++ b/smash/web/templates/login.html
@@ -75,6 +75,9 @@
 
     <form action="{% url 'web.views.login' %}" method="post">
 	  {% csrf_token %}
+    {% if next %}
+      <input type="hidden" name="next" value="{{ next }}" />
+    {% endif %}
 
       <div class="form-group has-feedback">
         <input type="text" name="username" class="form-control" placeholder="Login">
diff --git a/smash/web/templates/subjects/index.html b/smash/web/templates/subjects/index.html
index 991e049ceeaeba1c2294375208eaa7440bfee197..889fb48da4794ed960c6470aeedd36fefb200d3c 100644
--- a/smash/web/templates/subjects/index.html
+++ b/smash/web/templates/subjects/index.html
@@ -34,11 +34,10 @@
 				<th>Screening</th>
 				<th>First name</th>
 				<th>Last name</th>
-				<th>Country</th>
-				<th data-sorter="false" data-filter="false">Languages</th>
 				<th class="filter-select filter-exact" data-placeholder="Select location">Default location</th>
 				<th>Dead</th>
 				<th>Resigned</th>
+				<th>Postponed</th>
 				<th>Edit</th>
 			</tr>
 		</thead>
@@ -52,17 +51,10 @@
 			<td>{{ subject.screening_number }}</td>
 			<td>{{ subject.first_name }}</td>
       <td>{{ subject.last_name }}</td>
-      <td>{{ subject.country }}</td>
-			<td>
-        {% autoescape off %}
-        {% for language in subject.languages.all %}
-          {{language.image_img}}
-        {% endfor %}
-        {% endautoescape %}
-      </td>
 			<td>{{ subject.get_default_appointment_location_display }}</td>
 			<td>{% if subject.dead %} YES {% else %} NO {% endif %}	</td>
 			<td>{% if subject.resigned %} YES {% else %} NO {% endif %}	</td>
+			<td>{% if subject.postponed %} YES {% else %} NO {% endif %}	</td>
 			<td><a href="{% url 'web.views.subject_edit' subject.id %}" type="button" class="btn btn-block btn-default">Edit</a></td>
 		</tr>
     {% endfor %}
@@ -94,10 +86,7 @@
 					filter_cssFilter: "form-control",
 				},
 				headers: {
-					5: { sorter: false},
-					8: { sorter: false},
-					9: { sorter: false},
-					10: { sorter: false}
+					0: { sorter: true},
 				}
 			}).tablesorterPager({
 			    container: $(".ts-pager"),
diff --git a/smash/web/tests/functions.py b/smash/web/tests/functions.py
index c8c748908ff4ba8ee947fa06dfcc513efdf5457e..520601b637e923bc3825a17787eccd68caf1a6c7 100644
--- a/smash/web/tests/functions.py
+++ b/smash/web/tests/functions.py
@@ -40,13 +40,17 @@ def create_worker():
         email='jacob@bla',
         )
 
-def create_visit(subject):
+def create_visit(subject = None):
+    if subject == None:
+        subject= create_subject()
     return Visit.objects.create(datetime_begin=get_today_midnight_date()+datetime.timedelta(days=-31),
                                 datetime_end=get_today_midnight_date()+datetime.timedelta(days=31),
                                 subject =subject,
                                 is_finished = False)
 
-def create_appointment(visit):
+def create_appointment(visit= None):
+    if visit == None:
+        visit = create_visit()
     return Appointment.objects.create(
         visit = visit,
         length = 30,
diff --git a/smash/web/tests/test_view_kit_request.py b/smash/web/tests/test_view_kit_request.py
new file mode 100644
index 0000000000000000000000000000000000000000..6b32ea7e142954bb750a77cf80c40af4fcc39042
--- /dev/null
+++ b/smash/web/tests/test_view_kit_request.py
@@ -0,0 +1,76 @@
+from django.test import TestCase, RequestFactory
+from django.urls import reverse
+
+from web.views import *
+
+from web.tests.functions import *
+
+class ViewFunctionsTests(TestCase):
+    def setUp(self):
+        self.factory = RequestFactory()
+        self.user = create_user()
+
+    def test_kit_requests(self):
+        request = self.factory.get(reverse('web.views.kit_requests'));
+        request.user = self.user
+        response = kit_requests(request);
+        self.assertEqual(response.status_code, 200)
+
+    def test_kit_requests_2(self):
+        item_name  = "Test item to be ordered"
+        item = Item.objects.create(disposable=True, name=item_name)
+        appointment_type = create_appointment_type()
+        appointment_type.required_equipment.add(item)
+        appointment_type.save()
+
+        appointment = create_appointment()
+        appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2)
+        appointment.appointment_types.add(appointment_type)
+        appointment.save()
+
+        request = self.factory.get(reverse('web.views.kit_requests'));
+        request.user = self.user
+        response = kit_requests(request);
+        self.assertEqual(response.status_code, 200)
+
+        self.assertTrue(item_name in response.content)
+
+    def test_kit_requests_4(self):
+        item_name  = "Test item to be ordered"
+        item = Item.objects.create(disposable=True, name=item_name)
+        appointment_type = create_appointment_type()
+        appointment_type.required_equipment.add(item)
+        appointment_type.save()
+
+        appointment = create_appointment()
+        appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2)
+        appointment.appointment_types.add(appointment_type)
+        appointment.status = Appointment.APPOINTMENT_STATUS_CANCELLED
+        appointment.save()
+
+        request = self.factory.get(reverse('web.views.kit_requests'));
+        request.user = self.user
+        response = kit_requests(request);
+        self.assertEqual(response.status_code, 200)
+
+        self.assertFalse(item_name in response.content)
+
+    def test_kit_requests_3(self):
+        item_name  = "Test item to be ordered"
+        item = Item.objects.create(disposable=True, name=item_name)
+        appointment_type = create_appointment_type()
+        appointment_type.required_equipment.add(item)
+        appointment_type.save()
+
+        appointment = create_appointment()
+        appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2)
+        appointment.appointment_types.add(appointment_type)
+        appointment.location = create_location("other_loc")
+        appointment.save()
+
+        request = self.factory.get(reverse('web.views.kit_requests'));
+        request.user = self.user
+        response = kit_requests(request);
+        self.assertEqual(response.status_code, 200)
+
+        self.assertFalse(not item_name in response.content)
diff --git a/smash/web/tests/test_view_notifications.py b/smash/web/tests/test_view_notifications.py
index 82868c2765e70250566fe6bf0782a0aba62f05b6..9a2fb73aad6adf009be43399f0640e2fb77e9131 100644
--- a/smash/web/tests/test_view_notifications.py
+++ b/smash/web/tests/test_view_notifications.py
@@ -206,3 +206,89 @@ class NotificationViewTests(TestCase):
 
         notification = get_subject_with_no_visit_notifications_count(worker)
         self.assertEquals(original_notification.count +1, notification.count)
+
+
+    def test_get_approaching_visits_for_mail_contact_count(self):
+        original_notification = get_approaching_visits_for_mail_contact_count(self.user)
+        subject = create_subject()
+        visit = create_visit(subject)
+        visit.datetime_begin = get_today_midnight_date()+datetime.timedelta(days=100)
+        visit.save()
+
+        notification = get_approaching_visits_for_mail_contact_count(self.user)
+        self.assertEquals(original_notification.count + 1, notification.count)
+
+    def test_get_approaching_visits_for_mail_contact_count_2(self):
+        original_notification = get_approaching_visits_for_mail_contact_count(self.user)
+        subject = create_subject()
+        visit = create_visit(subject)
+        visit.datetime_begin = get_today_midnight_date()+datetime.timedelta(days=100)
+        visit.save()
+        appointment = create_appointment(visit)
+
+        notification = get_approaching_visits_for_mail_contact_count(self.user)
+        self.assertEquals(original_notification.count, notification.count)
+
+    def test_get_approaching_visits_for_mail_contact_count_3(self):
+        original_notification = get_approaching_visits_for_mail_contact_count(self.user)
+        subject = create_subject()
+        visit = create_visit(subject)
+        visit.datetime_begin = get_today_midnight_date()+datetime.timedelta(days=100)
+        visit.save()
+        appointment = create_appointment(visit)
+
+        appointment.status = Appointment.APPOINTMENT_STATUS_CANCELLED
+        appointment.save()
+
+        notification = get_approaching_visits_for_mail_contact_count(self.user)
+        self.assertEquals(original_notification.count + 1, notification.count)
+
+    def test_get_approaching_visits_for_mail_contact_count_4(self):
+        original_notification = get_approaching_visits_for_mail_contact_count(self.user)
+        subject = create_subject()
+        visit = create_visit(subject)
+        visit.datetime_begin = get_today_midnight_date()+datetime.timedelta(days=100)
+        visit.post_mail_sent = True
+        visit.save()
+
+        notification = get_approaching_visits_for_mail_contact_count(self.user)
+        self.assertEquals(original_notification.count, notification.count)
+
+    def test_get_subjects_with_reminder_count(self):
+        original_without_visit_notification = get_subject_with_no_visit_notifications_count(self.user)
+        original_notification = get_subjects_with_reminder_count(self.user)
+        subject = create_subject()
+        subject.datetime_contact_reminder = get_today_midnight_date()+datetime.timedelta(days=-1)
+        subject.save()
+
+        notification = get_subjects_with_reminder_count(self.user)
+        self.assertEquals(original_notification.count + 1, notification.count)
+
+        notification = get_subject_with_no_visit_notifications_count(self.user)
+        self.assertEquals(original_without_visit_notification.count, notification.count)
+
+    def test_get_subjects_with_reminder_count_2(self):
+        original_without_visit_notification = get_subject_with_no_visit_notifications_count(self.user)
+        original_notification = get_subjects_with_reminder_count(self.user)
+        subject = create_subject()
+        subject.datetime_contact_reminder = get_today_midnight_date()+datetime.timedelta(hours=23)
+        subject.save()
+
+        notification = get_subjects_with_reminder_count(self.user)
+        self.assertEquals(original_notification.count + 1, notification.count)
+
+        notification = get_subject_with_no_visit_notifications_count(self.user)
+        self.assertEquals(original_without_visit_notification.count, notification.count)
+
+    def test_get_subjects_with_reminder_count_3(self):
+        original_without_visit_notification = get_subject_with_no_visit_notifications_count(self.user)
+        original_notification = get_subjects_with_reminder_count(self.user)
+        subject = create_subject()
+        subject.datetime_contact_reminder = get_today_midnight_date()+datetime.timedelta(days=2)
+        subject.save()
+
+        notification = get_subjects_with_reminder_count(self.user)
+        self.assertEquals(original_notification.count, notification.count)
+
+        notification = get_subject_with_no_visit_notifications_count(self.user)
+        self.assertEquals(original_without_visit_notification.count, notification.count)
diff --git a/smash/web/urls.py b/smash/web/urls.py
index 2129f7b67af2873d70618d465c2a5329f09902e8..46500c6bd3a953d157ae7a4eab6d64265a2f8061 100644
--- a/smash/web/urls.py
+++ b/smash/web/urls.py
@@ -33,6 +33,7 @@ urlpatterns = [
     url(r'^visits/exceeded$', views.exceeded_visits, name='web.views.exceeded_visits'),
     url(r'^visits/unfinished$', views.unfinished_visits, name='web.views.unfinished_visits'),
     url(r'^visits/approaching$', views.approaching_visits_without_appointments, name='web.views.approaching_visits_without_appointments'),
+    url(r'^visits/approaching_post_mail$', views.approaching_visits_for_mail_contact, name='web.views.approaching_visits_for_mail_contact'),
     url(r'^visits/missing_appointments$', views.visits_with_missing_appointments, name='web.views.visits_with_missing_appointments'),
     url(r'^visits/details/(?P<id>\d+)$', views.visit_details, name='web.views.visit_details'),
     url(r'^visits/add$', views.visit_add, name='web.views.visit_add'),
@@ -41,6 +42,7 @@ urlpatterns = [
 
     url(r'^subjects$', views.subjects, name='web.views.subjects'),
     url(r'^subjects/no_visit$', views.subject_no_visits, name='web.views.subject_no_visits'),
+    url(r'^subjects/equire_contact$', views.subject_require_contact, name='web.views.subject_require_contact'),
     url(r'^subjects/add$', views.subject_add, name='web.views.subject_add'),
     url(r'^subjects/subject_visit_details/(?P<id>\d+)$', views.subject_visit_details, name='web.views.subject_visit_details'),
     url(r'^subjects/edit/(?P<id>\d+)$', views.subject_edit, name='web.views.subject_edit'),
@@ -56,6 +58,10 @@ urlpatterns = [
 
     url(r'^equipment_and_rooms$', views.equipment_and_rooms, name='web.views.equipment_and_rooms'),
     url(r'^equipment_and_rooms/eqdef$', views.equipment_def, name='web.views.equipment_def'),
+    url(r'^equipment_and_rooms/kit_requests$', views.kit_requests, name='web.views.kit_requests'),
+    url(r'^equipment_and_rooms/kit_requests/(?P<start_date>[\w-]+)/$', views.kit_requests_send_mail, name='web.views.kit_requests_send_mail'),
+    url(r'^equipment_and_rooms/kit_requests/(?P<start_date>[\w-]+)/(?P<end_date>[\w-]+)/$', views.kit_requests_send_mail, name='web.views.kit_requests_send_mail'),
+
 
     url(r'^mail_templates$', views.mail_templates, name='web.views.mail_templates'),
 
diff --git a/smash/web/views.py b/smash/web/views.py
index 63b6bad87ee63ac5ab9cfbcce12b7a58279fb33e..d7306572359ff81326d4da4cdabb81bc329de271 100644
--- a/smash/web/views.py
+++ b/smash/web/views.py
@@ -15,6 +15,7 @@ import datetime
 from django.db.models import Count
 from django.db.models import Case
 from django.db.models import When
+from django.utils.dateparse import parse_datetime
 
 import csv
 
@@ -53,13 +54,18 @@ def login(request):
 	if request.GET and request.GET.get('error'):
 		context['state'] = request.GET.get('error')
 
+	if request.method == "GET" and request.GET:
+		context['next'] = request.GET.get('next')
+
 	if request.method == "POST" and request.POST:
 		state, message = do_login(request)
 		if state == True:
-			return redirect(appointments)
+			if request.POST.get('next'):
+				return redirect(request.POST.get('next'))
+			else:
+				return redirect(appointments)
 		else:
 			return redirect('/login?error=' + message)
-
 	return render(request, "login.html", context)
 
 class NotificationCount(object):
@@ -76,12 +82,18 @@ class NotificationCount(object):
 
 def get_filter_locations(user):
 	worker = None
+
 	if isinstance(user, User):
 		workers = Worker.objects.filter(user=user)
 		if len(workers)>0:
 			worker = workers[0]
-	else:
+	elif isinstance(user, Worker):
 		worker = user
+	elif isinstance(user, AnonymousUser):
+		# anonymous user shouldn't see anything
+		return Location.objects.filter(id=-1)
+	elif user!=None:
+		raise TypeError("Unknown class type: "+user.__class__.__name__)
 
 	if worker==None or worker.locations.count() == 0:
 		return Location.objects.all()
@@ -108,10 +120,31 @@ def get_subjects_with_no_visit(user):
 		dead=False,
 		resigned=False,
 		my_count=0,
-		default_location__in = get_filter_locations(user)
+		default_location__in = get_filter_locations(user),
+		postponed=False,
+		datetime_contact_reminder__isnull=True,
+		)
+	return result
+
+def get_subjects_with_reminder(user):
+	tomorrow = get_today_midnight_date() + datetime.timedelta(days=1)
+
+	result = Subject.objects.filter(
+		dead=False,
+		resigned=False,
+		default_location__in = get_filter_locations(user),
+		datetime_contact_reminder__lt=tomorrow,
 		)
 	return result
 
+def get_subjects_with_reminder_count(user):
+	notification = NotificationCount(
+		title = "subject required contact",
+		count = get_subjects_with_reminder(user).count(),
+	 	style = "fa fa-users text-aqua",
+		type = 'web.views.subject_require_contact')
+	return notification
+
 def get_subject_with_no_visit_notifications_count(user):
 	notification = NotificationCount(
 		title = "subject without visit",
@@ -181,9 +214,17 @@ def get_approaching_visits_without_appointments_count(user):
 		type = 'web.views.approaching_visits_without_appointments')
 	return notification
 
+def get_approaching_visits_for_mail_contact_count(user):
+	notification = NotificationCount(
+		title = "post mail for approaching visits",
+		count = get_approaching_visits_for_mail_contact(user).count(),
+		style = "fa fa-users text-aqua",
+		type = 'web.views.approaching_visits_for_mail_contact')
+	return notification
+
 def get_approaching_visits_without_appointments(user):
 	today = get_today_midnight_date()
-	today_plus_two_months =today+datetime.timedelta(days=93)
+	today_plus_two_months =today+datetime.timedelta(days=62)
 	return Visit.objects.annotate(my_count=Count(Case(When(appointment__status=Appointment.APPOINTMENT_STATUS_SCHEDULED, then=1)))).filter(
 		datetime_begin__gt = today,
 		datetime_begin__lt = today_plus_two_months,
@@ -191,6 +232,18 @@ def get_approaching_visits_without_appointments(user):
 		subject__default_location__in = get_filter_locations(user),
 		my_count=0)
 
+def get_approaching_visits_for_mail_contact(user):
+	today = get_today_midnight_date()
+	today_plus_three_months =today+datetime.timedelta(days=91)
+	today_plus_six_months =today+datetime.timedelta(days=183)
+	return Visit.objects.annotate(my_count=Count(Case(When(appointment__status=Appointment.APPOINTMENT_STATUS_SCHEDULED, then=1)))).filter(
+		datetime_begin__gt = today_plus_three_months,
+		datetime_begin__lt = today_plus_six_months,
+		is_finished = False,
+		post_mail_sent = False,
+		subject__default_location__in = get_filter_locations(user),
+		my_count=0)
+
 def get_unfinished_appointments_count(user):
 	return NotificationCount(
 		title = "unfinished appointments ",
@@ -218,6 +271,9 @@ def get_notifications(the_user):
 			notifications.append(get_unfinished_appointments_count(person))
 			notifications.append(get_visits_with_missing_appointments_count(person))
 			notifications.append(get_subject_with_no_visit_notifications_count(person))
+			notifications.append(get_approaching_visits_for_mail_contact_count(person))
+			notifications.append(get_subjects_with_reminder_count(person))
+
 
 			for notification in notifications:
 				count += notification.count
@@ -281,9 +337,16 @@ def approaching_visits_without_appointments(request):
 	context = {
 		'visit_list': get_approaching_visits_without_appointments(request.user)
 	}
+	return wrap_response(request, 'visits/index.html', context)
 
+def approaching_visits_for_mail_contact(request):
+	context = {
+		'visit_list': get_approaching_visits_for_mail_contact(request.user)
+	}
 	return wrap_response(request, 'visits/index.html', context)
 
+
+
 def visit_details(request, id):
 	displayedVisit = get_object_or_404(Visit, id=id)
 	if request.method == 'POST':
@@ -371,6 +434,14 @@ def subject_no_visits(request):
 
 	return wrap_response(request, 'subjects/index.html', context)
 
+def subject_require_contact(request):
+	subjects_list = get_subjects_with_reminder(request.user).order_by('-last_name')
+	context = {
+		'subjects_list':  subjects_list
+	}
+
+	return wrap_response(request, 'subjects/index.html', context)
+
 def subject_edit(request, id):
 	the_subject = get_object_or_404(Subject, id=id)
 	if request.method == 'POST':
@@ -632,6 +703,7 @@ def appointment_edit_datetime(request, id):
 		form = AppointmentEditForm(instance=the_appointment)
 	return wrap_response(request, 'appointments/edit.html', {'form': form})
 
+#because we don't  wrap_response we must force login required
 @login_required
 def export_to_csv2(request, type="subjects"):
     #Create the HttpResponse object with the appropriate CSV header.
@@ -700,3 +772,52 @@ def write_appointments_to_csv(writer):
 
 def export(request):
 	return wrap_response(request, 'export/index.html',{})
+
+def get_kit_requests(user, start_date = None, end_date = None):
+	if start_date == None:
+		start_date = get_today_midnight_date() + datetime.timedelta(days=1)
+		end_date = start_date + datetime.timedelta(days=7)
+	else :
+		if isinstance(start_date, str):
+			start_date = parse_datetime(start_date)
+		if (end_date != None) and (isinstance(end_date, str)):
+			end_date = parse_datetime(end_date)
+
+	appointment_types = AppointmentType.objects.filter(required_equipment__disposable=True)
+
+	appointments = Appointment.objects.filter(
+		appointment_types__in = appointment_types,
+		datetime_when__gt = start_date,
+		location__in = get_filter_locations(user),
+		status = Appointment.APPOINTMENT_STATUS_SCHEDULED,
+		)
+	if end_date!=None:
+		appointments = appointments.filter(datetime_when__lt = end_date)
+
+	result = {
+		'start_date' 	: start_date,
+		'end_date'		: end_date,
+		'appointments'	: appointments,
+		}
+	return result
+
+def get_kit_requests_data(request, start_date = None, end_date = None):
+	form = KitRequestForm()
+	if request.method=='POST':
+		form = KitRequestForm(request.POST)
+		if form.is_valid():
+			form_data = form.cleaned_data
+			start_date = form_data.get('start_date')
+			end_date = form_data.get('end_date')
+
+	params = get_kit_requests(request.user, start_date, end_date)
+	params.update({
+		'form': form
+	})
+	return params
+
+def kit_requests(request):
+	return wrap_response(request, 'equipment_and_rooms/kit_requests.html', get_kit_requests_data(request))
+
+def kit_requests_send_mail(request, start_date, end_date = None):
+	return wrap_response(request, 'equipment_and_rooms/kit_requests_send_mail.html', get_kit_requests_data(request, start_date, end_date))
diff --git a/todos.txt b/todos.txt
deleted file mode 100644
index 261e8d71eccbefea0f53193c9a39530a6c980183..0000000000000000000000000000000000000000
--- a/todos.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-* TODO List
-
-** Notice
-Moved all the important stuff to gitlab issues
-
-** Important
- - label for's => give them correct html id's (all html forms).
-   Currently it works, but it's not valid HTML, as the ID (for labels) are all the same.
-   It requires a hack, because django forms are not-so-flexible
- - implement `on leave` button
- - what about possible sunday in availabilities?
- - in beta remember to disable Guest Access
- - in beta remember to forbid not-logged users to browse the API
-
-** Visual
- - None
-
-** Possible improvements
-- breadcrumbs - make them stack. Currently, they are made "half-manually".
-  While it is not a great problem, it is not a flexible solution
-- make some names sound/look more pythonic. Unfortunately, due to
-  programmistic experience of our team, instead of sticking to python convencies
-  (lower case methods, fields; using underscore to break words instead of
-  camelCase), using full names and not abbrieviations, the code sometimes
-  resembles a mess.