diff --git a/.gitignore b/.gitignore
index 131f236781569ef3d47a82f46dffe63c5be48b02..5f846bdc44dc42490d2b3c88d19b3dc0f50533e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,4 @@ out
 smash/htmlcov/
 run-coverage.bat
 
+media
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index fd2748cea54a607609c5c9468f6aa2ee75c9e208..7cf83b16820ded2b91b06faef75aad4f0645f8c5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -7,7 +7,7 @@ variables:
   POSTGRES_PASSWORD: password
 
 before_script:
-  - apt-get update && apt-get install -y libsasl2-dev libssl-dev
+  - apt-get update && apt-get install -y libsasl2-dev libssl-dev locales locales-all
   - pip install -r requirements.txt --default-timeout=180
   - pip install -r requirements-dev.txt --default-timeout=180
 
diff --git a/readme.md b/readme.md
index 42b1f415c237d3a92fa4a132e7b8e1e6cf5eb6eb..901118ed48af950c3283b7c5d12d01c951095e48 100644
--- a/readme.md
+++ b/readme.md
@@ -3,7 +3,7 @@
 [![coverage report](https://git-r3lab.uni.lu/piotr.atyjaszyk/scheduling-system/badges/master/coverage.svg)](https://git-r3lab.uni.lu/piotr.atyjaszyk/scheduling-system/commits/master)
 
 ## Required software (on ubuntu's OS family):
-  - `sudo apt-get install libpq-dev python-dev postgresql postgresql-contrib python virtualenv python-virtualenv gcc`
+  - `sudo apt-get install libpq-dev python-dev postgresql postgresql-contrib python virtualenv python-virtualenv gcc python-lxml libxml2-dev`
 
 ## Postgres installation
   - If you don't have postgres installed, complete step seven from [https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-django-with-postgres-nginx-and-gunicorn](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-django-with-postgres-nginx-and-gunicorn) (remember to save all the credentials, they will be necessary to run the application).
@@ -30,9 +30,9 @@
 ## Production deployment
   - git pull and other project installation should be performed in a dir where this django app should be installed, in this tutorial it's /var/www/scheduling-system/
   - install nginx: `apt-get install nginx`
-  - create gunicorn service in systemd (http://docs.gunicorn.org/en/stable/deploy.html#systemd): 
+  - create gunicorn service in systemd (http://docs.gunicorn.org/en/stable/deploy.html#systemd):
 
-### /etc/systemd/system/gunicorn.service 
+### /etc/systemd/system/gunicorn.service
 
 ```
 [Unit]
@@ -67,7 +67,7 @@ ListenStream=[::]:8000
 
 [Install]
 WantedBy=sockets.target
-  
+
    - modify nginx configuration
 
 # /etc/nginx/nginx.conf
@@ -173,4 +173,4 @@ server {
 }
 ```
   - extract static files and make them available via nginx: `./manage.py collectstatic`
-  - you start application by starting gunicorn and nginx: `service gunicorn start`, `service nginx start`
\ No newline at end of file
+  - you start application by starting gunicorn and nginx: `service gunicorn start`, `service nginx start`
diff --git a/requirements.txt b/requirements.txt
index 72e849e28c5189314ff7943b733264979c9a153a..aec2cf772fd0df7d6d20ecc33e0b13cab0f8e621 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,3 +3,6 @@ gunicorn==19.6.0
 Pillow==3.4.2
 psycopg2==2.6.2
 pytz==2016.10
+lxml==3.7.3
+python-docx==0.8.6
+django-cleanup==0.4.2
\ No newline at end of file
diff --git a/smash/smash/local_settings.py.template b/smash/smash/local_settings.py.template
index ba1dcda662d69f97380d284555e5284a86898335..32397c94d8545705fce662d3e443f15b3cdf4a20 100644
--- a/smash/smash/local_settings.py.template
+++ b/smash/smash/local_settings.py.template
@@ -1,5 +1,5 @@
 # SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = 'Paste long random string here' # Insert long random string
+SECRET_KEY = 'Paste long random string here'  # Insert long random string
 
 # SECURITY WARNING: don't run with debug turned on in production!
 DEBUG = True
@@ -21,11 +21,11 @@ DEFAULT_FROM_EMAIL = 'prc-scheduling-admin@uni.lu'
 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
+        '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
+        'PORT': ''  # '' === default one # Empty string is OK
 
         # If to use sqlite
         # 'ENGINE': 'django.db.backends.sqlite3',
@@ -33,5 +33,7 @@ DATABASES = {
     }
 }
 
-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
+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
+
+STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
diff --git a/smash/smash/settings.py b/smash/smash/settings.py
index 0e57c97649286fdad18830070e20f69a20303d03..48fbaf41986bb03af7835e85f076684e91bdbc90 100644
--- a/smash/smash/settings.py
+++ b/smash/smash/settings.py
@@ -38,6 +38,7 @@ INSTALLED_APPS = [
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
+    'django_cleanup',
     'debug_toolbar',
     'web'
 ]
diff --git a/smash/web/docx_helper.py b/smash/web/docx_helper.py
new file mode 100644
index 0000000000000000000000000000000000000000..fb78711c12cf62d7129610e3417785a2039ed796
--- /dev/null
+++ b/smash/web/docx_helper.py
@@ -0,0 +1,17 @@
+from docx import Document
+
+
+def process_file(path_to_docx, path_to_new_docx, changes_to_apply):
+    """
+    Tries to open the docx document using given path to file.
+    Then, applies the transformations- replaces template tags
+    in format of ##name## to values specified in the second
+    argument.
+    """
+    doc = Document(path_to_docx)
+    for paragraph in doc.paragraphs:
+        for placeholder, replacement in changes_to_apply.items():
+            if placeholder in paragraph.text:
+                paragraph.text = paragraph.text.replace(placeholder, replacement)
+
+    doc.save(path_to_new_docx)
diff --git a/smash/web/migrations/0034_mail_templates.py b/smash/web/migrations/0034_mail_templates.py
new file mode 100644
index 0000000000000000000000000000000000000000..20dec068d4b2392361b8c76a112dd32828354401
--- /dev/null
+++ b/smash/web/migrations/0034_mail_templates.py
@@ -0,0 +1,128 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-04-07 07:10
+from __future__ import unicode_literals
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+def update_languages(apps, schema_editor):
+    Language = apps.get_model("web", "Language")
+    updates_to_perform = [
+        ("French", 10, "fr_FR"),
+        ("Dutch", 100, "nl_NL"),
+        ("Swedish", 200, "se_SE"),
+        ("Spanish", 110, "es_ES"),
+        ("Slovak", 200, "es_ES"),
+        ("Romanian", 200, "ro_RO"),
+        ("Polish", 200, "pl_PL"),
+        ("Italian", 100, "it_IT"),
+        ("Hungarian", 200, "hu_HU"),
+        ("Greek", 200, "el_GR"),
+        ("Finnish", 200, "fi_FI"),
+        ("Danish", 200, "da_DK"),
+        ("Arabic", 200, "ar_DZ"),
+        ("Portuguese", 80, "pt_PT"),
+        ("Luxembourgish", 20, "lb_LU"),
+        ("English", 50, "en_GB"),
+        ("German", 30, "de_DE"),
+    ]
+    for update_to_perform in updates_to_perform:
+        name, order, locale = update_to_perform
+        language = Language.objects.filter(name=name).first()
+        if language is not None:
+            language.order = order
+            language.locale = locale
+            language.save()
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ('web', '0033_auto_20170406_1146'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='MailTemplate',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=255)),
+                ('context', models.CharField(choices=[(b'A', b'Appointment'), (b'S', b'Subject'), (b'V', b'Visit')],
+                                             max_length=1)),
+                ('template_file', models.FileField(upload_to=b'templates/')),
+            ],
+        ),
+        migrations.AlterModelOptions(
+            name='language',
+            options={'ordering': ['order']},
+        ),
+        migrations.AddField(
+            model_name='language',
+            name='locale',
+            field=models.CharField(
+                choices=[(b'af_ZA', b'af_ZA'), (b'am_ET', b'am_ET'), (b'ar_AE', b'ar_AE'), (b'ar_BH', b'ar_BH'),
+                         (b'ar_DZ', b'ar_DZ'), (b'ar_EG', b'ar_EG'), (b'ar_IQ', b'ar_IQ'), (b'ar_JO', b'ar_JO'),
+                         (b'ar_KW', b'ar_KW'), (b'ar_LB', b'ar_LB'), (b'ar_LY', b'ar_LY'), (b'ar_MA', b'ar_MA'),
+                         (b'ar_OM', b'ar_OM'), (b'ar_QA', b'ar_QA'), (b'ar_SA', b'ar_SA'), (b'ar_SY', b'ar_SY'),
+                         (b'ar_TN', b'ar_TN'), (b'ar_YE', b'ar_YE'), (b'arn_CL', b'arn_CL'), (b'as_IN', b'as_IN'),
+                         (b'az_AZ', b'az_AZ'), (b'az_AZ', b'az_AZ'), (b'ba_RU', b'ba_RU'), (b'be_BY', b'be_BY'),
+                         (b'bg_BG', b'bg_BG'), (b'bn_IN', b'bn_IN'), (b'bo_BT', b'bo_BT'), (b'bo_CN', b'bo_CN'),
+                         (b'br_FR', b'br_FR'), (b'bs_BA', b'bs_BA'), (b'bs_BA', b'bs_BA'), (b'ca_ES', b'ca_ES'),
+                         (b'co_FR', b'co_FR'), (b'cs_CZ', b'cs_CZ'), (b'cy_GB', b'cy_GB'), (b'da_DK', b'da_DK'),
+                         (b'de_AT', b'de_AT'), (b'de_CH', b'de_CH'), (b'de_DE', b'de_DE'), (b'de_LI', b'de_LI'),
+                         (b'de_LU', b'de_LU'), (b'div_MV', b'div_MV'), (b'dsb_DE', b'dsb_DE'), (b'el_GR', b'el_GR'),
+                         (b'en_AU', b'en_AU'), (b'en_BZ', b'en_BZ'), (b'en_CA', b'en_CA'), (b'en_CB', b'en_CB'),
+                         (b'en_GB', b'en_GB'), (b'en_IE', b'en_IE'), (b'en_IN', b'en_IN'), (b'en_IN', b'en_IN'),
+                         (b'en_JA', b'en_JA'), (b'en_MY', b'en_MY'), (b'en_NZ', b'en_NZ'), (b'en_PH', b'en_PH'),
+                         (b'en_TT', b'en_TT'), (b'en_US', b'en_US'), (b'en_ZA', b'en_ZA'), (b'en_ZW', b'en_ZW'),
+                         (b'es_AR', b'es_AR'), (b'es_BO', b'es_BO'), (b'es_CL', b'es_CL'), (b'es_CO', b'es_CO'),
+                         (b'es_CR', b'es_CR'), (b'es_DO', b'es_DO'), (b'es_EC', b'es_EC'), (b'es_ES', b'es_ES'),
+                         (b'es_ES', b'es_ES'), (b'es_GT', b'es_GT'), (b'es_HN', b'es_HN'), (b'es_MX', b'es_MX'),
+                         (b'es_NI', b'es_NI'), (b'es_PA', b'es_PA'), (b'es_PE', b'es_PE'), (b'es_PR', b'es_PR'),
+                         (b'es_PY', b'es_PY'), (b'es_SV', b'es_SV'), (b'es_UR', b'es_UR'), (b'es_US', b'es_US'),
+                         (b'es_VE', b'es_VE'), (b'et_EE', b'et_EE'), (b'eu_ES', b'eu_ES'), (b'fa_IR', b'fa_IR'),
+                         (b'fi_FI', b'fi_FI'), (b'fil_PH', b'fil_PH'), (b'fo_FO', b'fo_FO'), (b'fr_BE', b'fr_BE'),
+                         (b'fr_CA', b'fr_CA'), (b'fr_CH', b'fr_CH'), (b'fr_FR', b'fr_FR'), (b'fr_LU', b'fr_LU'),
+                         (b'fr_MC', b'fr_MC'), (b'fy_NL', b'fy_NL'), (b'ga_IE', b'ga_IE'), (b'gbz_AF', b'gbz_AF'),
+                         (b'gl_ES', b'gl_ES'), (b'gsw_FR', b'gsw_FR'), (b'gu_IN', b'gu_IN'), (b'ha_NG', b'ha_NG'),
+                         (b'he_IL', b'he_IL'), (b'hi_IN', b'hi_IN'), (b'hr_BA', b'hr_BA'), (b'hr_HR', b'hr_HR'),
+                         (b'hu_HU', b'hu_HU'), (b'hy_AM', b'hy_AM'), (b'id_ID', b'id_ID'), (b'ii_CN', b'ii_CN'),
+                         (b'is_IS', b'is_IS'), (b'it_CH', b'it_CH'), (b'it_IT', b'it_IT'), (b'iu_CA', b'iu_CA'),
+                         (b'iu_CA', b'iu_CA'), (b'ja_JP', b'ja_JP'), (b'ka_GE', b'ka_GE'), (b'kh_KH', b'kh_KH'),
+                         (b'kk_KZ', b'kk_KZ'), (b'kl_GL', b'kl_GL'), (b'kn_IN', b'kn_IN'), (b'ko_KR', b'ko_KR'),
+                         (b'kok_IN', b'kok_IN'), (b'ky_KG', b'ky_KG'), (b'lb_LU', b'lb_LU'), (b'lo_LA', b'lo_LA'),
+                         (b'lt_LT', b'lt_LT'), (b'lv_LV', b'lv_LV'), (b'mi_NZ', b'mi_NZ'), (b'mk_MK', b'mk_MK'),
+                         (b'ml_IN', b'ml_IN'), (b'mn_CN', b'mn_CN'), (b'mn_MN', b'mn_MN'), (b'moh_CA', b'moh_CA'),
+                         (b'mr_IN', b'mr_IN'), (b'ms_BN', b'ms_BN'), (b'ms_MY', b'ms_MY'), (b'mt_MT', b'mt_MT'),
+                         (b'nb_NO', b'nb_NO'), (b'ne_NP', b'ne_NP'), (b'nl_BE', b'nl_BE'), (b'nl_NL', b'nl_NL'),
+                         (b'nn_NO', b'nn_NO'), (b'ns_ZA', b'ns_ZA'), (b'oc_FR', b'oc_FR'), (b'or_IN', b'or_IN'),
+                         (b'pa_IN', b'pa_IN'), (b'pl_PL', b'pl_PL'), (b'ps_AF', b'ps_AF'), (b'pt_BR', b'pt_BR'),
+                         (b'pt_PT', b'pt_PT'), (b'qut_GT', b'qut_GT'), (b'quz_BO', b'quz_BO'), (b'quz_EC', b'quz_EC'),
+                         (b'quz_PE', b'quz_PE'), (b'rm_CH', b'rm_CH'), (b'ro_RO', b'ro_RO'), (b'ru_RU', b'ru_RU'),
+                         (b'rw_RW', b'rw_RW'), (b'sa_IN', b'sa_IN'), (b'sah_RU', b'sah_RU'), (b'se_FI', b'se_FI'),
+                         (b'se_NO', b'se_NO'), (b'se_SE', b'se_SE'), (b'si_LK', b'si_LK'), (b'sk_SK', b'sk_SK'),
+                         (b'sl_SI', b'sl_SI'), (b'sma_NO', b'sma_NO'), (b'sma_SE', b'sma_SE'), (b'smj_NO', b'smj_NO'),
+                         (b'smj_SE', b'smj_SE'), (b'smn_FI', b'smn_FI'), (b'sms_FI', b'sms_FI'), (b'sq_AL', b'sq_AL'),
+                         (b'sr_BA', b'sr_BA'), (b'sr_BA', b'sr_BA'), (b'sr_SP', b'sr_SP'), (b'sr_SP', b'sr_SP'),
+                         (b'sv_FI', b'sv_FI'), (b'sv_SE', b'sv_SE'), (b'sw_KE', b'sw_KE'), (b'syr_SY', b'syr_SY'),
+                         (b'ta_IN', b'ta_IN'), (b'te_IN', b'te_IN'), (b'tg_TJ', b'tg_TJ'), (b'th_TH', b'th_TH'),
+                         (b'tk_TM', b'tk_TM'), (b'tmz_DZ', b'tmz_DZ'), (b'tn_ZA', b'tn_ZA'), (b'tr_TR', b'tr_TR'),
+                         (b'tt_RU', b'tt_RU'), (b'ug_CN', b'ug_CN'), (b'uk_UA', b'uk_UA'), (b'ur_IN', b'ur_IN'),
+                         (b'ur_PK', b'ur_PK'), (b'uz_UZ', b'uz_UZ'), (b'uz_UZ', b'uz_UZ'), (b'vi_VN', b'vi_VN'),
+                         (b'wen_DE', b'wen_DE'), (b'wo_SN', b'wo_SN'), (b'xh_ZA', b'xh_ZA'), (b'yo_NG', b'yo_NG'),
+                         (b'zh_CHS', b'zh_CHS'), (b'zh_CHT', b'zh_CHT'), (b'zh_CN', b'zh_CN'), (b'zh_HK', b'zh_HK'),
+                         (b'zh_MO', b'zh_MO'), (b'zh_SG', b'zh_SG'), (b'zh_TW', b'zh_TW'), (b'zu_ZA', b'zu_ZA')],
+                default=b'fr_FR', max_length=10),
+        ),
+        migrations.AddField(
+            model_name='language',
+            name='order',
+            field=models.IntegerField(default=0),
+        ),
+        migrations.AddField(
+            model_name='mailtemplate',
+            name='language',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Language'),
+        ),
+        migrations.RunPython(update_languages, reverse_code=lambda x, y: None),
+    ]
diff --git a/smash/web/models/__init__.py b/smash/web/models/__init__.py
index a2dc22415ab64d1292bb53ec1fbcdc4262fbbeaf..c7f68233137fd9a8cc95916081631f6d4936686e 100644
--- a/smash/web/models/__init__.py
+++ b/smash/web/models/__init__.py
@@ -19,6 +19,7 @@ from item import Item
 from language import Language
 from subject import Subject
 from contact_attempt import ContactAttempt
+from mail_template import MailTemplate
 
 
 def get_current_year():
@@ -26,4 +27,4 @@ def get_current_year():
 
 
 __all__ = [FlyingTeam, Appointment, AppointmentType, Availability, Holiday, Item, Language, Location, Room, Subject,
-           Visit, Worker, ContactAttempt, ConfigurationItem]
+           Visit, Worker, ContactAttempt, ConfigurationItem, MailTemplate]
diff --git a/smash/web/models/appointment.py b/smash/web/models/appointment.py
index 176dd9d0b9a0cbdb19c15a2d88aa7d5a6b4066a0..c955871a389486bd8674659cca05293707e97b55 100644
--- a/smash/web/models/appointment.py
+++ b/smash/web/models/appointment.py
@@ -5,7 +5,6 @@ from django.db import models
 
 from constants import APPOINTMENT_TYPE_DEFAULT_COLOR, APPOINTMENT_TYPE_DEFAULT_FONT_COLOR, \
     CANCELLED_APPOINTMENT_COLOR_CONFIGURATION_TYPE, NO_SHOW_APPOINTMENT_COLOR_CONFIGURATION_TYPE
-from . import FlyingTeam, Location, Room, Visit, Worker
 from . import ConfigurationItem
 
 
@@ -24,11 +23,11 @@ class Appointment(models.Model):
         APPOINTMENT_STATUS_NO_SHOW: 'No Show',
     }
 
-    flying_team = models.ForeignKey(FlyingTeam,
+    flying_team = models.ForeignKey("web.FlyingTeam",
                                     verbose_name='Flying team (if applicable)',
                                     null=True, blank=True
                                     )
-    worker_assigned = models.ForeignKey(Worker,
+    worker_assigned = models.ForeignKey("web.Worker",
                                         verbose_name='Worker conducting the assessment (if applicable)',
                                         null=True, blank=True
                                         )
@@ -36,15 +35,15 @@ class Appointment(models.Model):
                                                verbose_name='Appointment types',
                                                blank=True
                                                )
-    room = models.ForeignKey(Room,
+    room = models.ForeignKey("web.Room",
                              verbose_name='Room ID',
                              null=True,
                              blank=True
                              )
-    location = models.ForeignKey(Location,
+    location = models.ForeignKey("web.Location",
                                  verbose_name='Location',
                                  )
-    visit = models.ForeignKey(Visit,
+    visit = models.ForeignKey("web.Visit",
                               verbose_name='Visit ID',
                               editable=False,
                               null=True,
diff --git a/smash/web/models/appointment_type.py b/smash/web/models/appointment_type.py
index 84304f466bc0da92703207852048dbc8f180f48d..a6a3ba76a64784212b1f1db2b32eba312aec0af1 100644
--- a/smash/web/models/appointment_type.py
+++ b/smash/web/models/appointment_type.py
@@ -7,6 +7,7 @@ from constants import APPOINTMENT_TYPE_DEFAULT_COLOR, APPOINTMENT_TYPE_DEFAULT_F
 class AppointmentType(models.Model):
     class Meta:
         app_label = 'web'
+        ordering = ['description']
 
     required_equipment = models.ManyToManyField("web.Item",
                                                 verbose_name='Required equipment',
@@ -52,9 +53,6 @@ class AppointmentType(models.Model):
                                        default='ANY'
                                        )
 
-    class Meta:
-        ordering = ['description']
-
     def __str__(self):
         return self.description
 
diff --git a/smash/web/models/constants.py b/smash/web/models/constants.py
index 5d7ac193bc9e18e59b15e858bafb2a92ee8e15aa..6fb833e06cc3dd8748fed23716c384c2beecc891 100644
--- a/smash/web/models/constants.py
+++ b/smash/web/models/constants.py
@@ -1,4 +1,6 @@
 # coding=utf-8
+import locale
+
 BOOL_CHOICES = ((True, 'Yes'), (False, 'No'))
 SEX_CHOICES_MALE = 'M'
 SEX_CHOICES_FEMALE = 'F'
@@ -34,3 +36,14 @@ NO_SHOW_APPOINTMENT_COLOR_CONFIGURATION_TYPE = "NO_SHOW_APPOINTMENT_COLOR"
 KIT_RECIPIENT_EMAIL_CONFIGURATION_TYPE = "KIT_RECIPIENT_EMAIL_CONFIGURATION_TYPE"
 KIT_EMAIL_HOUR_CONFIGURATION_TYPE = "KIT_DAILY_EMAIL_HOUR_CONFIGURATION_TYPE"
 KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE = "KIT_EMAIL_DAY_OF_WEEK_CONFIGURATION_TYPE"
+
+MAIL_TEMPLATE_CONTEXT_SUBJECT = 'S'
+MAIL_TEMPLATE_CONTEXT_APPOINTMENT = 'A'
+MAIL_TEMPLATE_CONTEXT_VISIT = 'V'
+
+MAIL_TEMPLATE_CONTEXT_CHOICES = (
+    (MAIL_TEMPLATE_CONTEXT_APPOINTMENT, 'Appointment'),
+    (MAIL_TEMPLATE_CONTEXT_SUBJECT, 'Subject'),
+    (MAIL_TEMPLATE_CONTEXT_VISIT, 'Visit'),
+)
+LOCALE_CHOICES = [(value, value) for value in sorted(locale.windows_locale.values())]
diff --git a/smash/web/models/language.py b/smash/web/models/language.py
index 8e786111d9a4265f366f2f1389db98a9af1e50f0..1b0cb703255e0aa6f9f7c23e22d804ee901ec946 100644
--- a/smash/web/models/language.py
+++ b/smash/web/models/language.py
@@ -1,13 +1,19 @@
 # coding=utf-8
+
 from django.db import models
 
+from .constants import LOCALE_CHOICES
+
 
 class Language(models.Model):
     class Meta:
         app_label = 'web'
+        ordering = ["order"]
 
     name = models.CharField(max_length=20)
     image = models.ImageField()
+    order = models.IntegerField(default=0)
+    locale = models.CharField(max_length=10, choices=LOCALE_CHOICES, null=False, blank=False, default="fr_FR")
 
     def __str__(self):
         return self.name
diff --git a/smash/web/models/mail_template.py b/smash/web/models/mail_template.py
new file mode 100644
index 0000000000000000000000000000000000000000..8e0316a9efa3a8e2fa348bf0b47f9eb71727cb4c
--- /dev/null
+++ b/smash/web/models/mail_template.py
@@ -0,0 +1,222 @@
+# coding=utf-8
+import datetime
+import locale
+from contextlib import contextmanager
+
+from django.db import models
+
+from .constants import MAIL_TEMPLATE_CONTEXT_CHOICES, MAIL_TEMPLATE_CONTEXT_APPOINTMENT, MAIL_TEMPLATE_CONTEXT_SUBJECT, \
+    MAIL_TEMPLATE_CONTEXT_VISIT
+from ..docx_helper import process_file
+from ..models import Appointment, Visit, Subject, Worker
+
+DATE_FORMAT_FULL = "%A %-d %B %Y"
+
+DATETIME_FORMAT = "%A %-d %B %Y, %H:%m"
+
+DATE_FORMAT_SHORT = "%d.%m.%Y"
+
+DATE_FORMAT_TIME = "%H:%M"
+
+now = datetime.datetime.now()
+
+
+@contextmanager
+def setlocale(name):
+    saved = locale.setlocale(locale.LC_TIME)
+    try:
+        yield locale.setlocale(locale.LC_TIME, name)
+    finally:
+        locale.setlocale(locale.LC_TIME, saved)
+
+
+class MailTemplate(models.Model):
+    MAILS_TEMPLATE_GENERIC_TAGS = [
+        ("##DATE_FULL##", "Current date when the mail will be generated (long format)", now.strftime(DATE_FORMAT_FULL)),
+        ("##DATE_SHORT##", "Current date when the mail will be generated (short format)",
+         now.strftime(DATE_FORMAT_SHORT)),
+        ("##WORKER##", "The full name of the currently logged in user", "")
+    ]
+
+    MAILS_TEMPLATE_SUBJECT_TAGS = [
+        ("##S_FULL_NAME##", "Subject's full name", "first_name last_name"),
+        ("##S_FIRST_NAME##", "Subject's first name", ""),
+        ("##S_LAST_NAME##", "Subject's last name", ""),
+        ("##S_ADDRESS##", "Subject's address", "street name and number"),
+        ("##S_CITY##", "Subject's city of residence", ""),
+        ("##S_POST_CODE##", "Subject's post code of residence", ""),
+        ("##S_COUNTRY##", "Subject's country of residence", ""),
+        ("##S_SEX##", "Subject's gender", "Male/Female"),
+        ("##S_TYPE##", "Subject's type", "CONTROL/PATIENT"),
+        ("##S_DATE_BORN##", "Subject's date of birth", now.strftime(DATE_FORMAT_SHORT)),
+
+        ("##S_EMAIL##", "Subject's email address", ""),
+        ("##S_PHONE_NUMBER##", "Subject's phone number", ""),
+        ("##S_PHONE_NUMBER_2##", "Subject's second phone number", ""),
+        ("##S_PHONE_NUMBER_3##", "Subject's third phone number", ""),
+        ("##S_MAIL_LANGUAGE##", "Subject's preferred language for written communication", ""),
+        ("##S_KNOWN_LANGUAGES##", "List of languages known by the subject", "comma separated"),
+
+        ("##S_SCREENING_NUMBER##", "Subject's screening number", ""),
+        ("##S_DIAGNOSIS##", "Subject's diagnosis", ""),
+        ("##S_DIAGNOSIS_YEAR##", "Subject's year of diagnosis", ""),
+        ("##S_MPOWER_ID##", "Subject's mPower identifier", ""),
+        ("##S_ND_NUMBER##", "Subject's ND number", ""),
+        ("##S_DATE_ADDED##", "Subject's date of creation", now.strftime(DATE_FORMAT_SHORT)),
+    ]
+
+    MAILS_TEMPLATE_VISIT_TAGS = [
+        ("##V_DATE_START_FULL##", "Visit's start date", now.strftime(DATETIME_FORMAT)),
+        ("##V_DATE_START_SHORT##", "Visit's start date", now.strftime(DATE_FORMAT_SHORT)),
+        ("##V_DATE_ENDS_FULL##", "Visit's end date", now.strftime(DATETIME_FORMAT)),
+        ("##V_DATE_ENDS_SHORT##", "Visit's end date", now.strftime(DATE_FORMAT_SHORT)),
+    ]
+
+    MAILS_TEMPLATE_APPOINTMENT_TAGS = [
+        ("##A_DATE_FULL##", "Appointment's date and time", now.strftime(DATETIME_FORMAT)),
+        ("##A_DATE_SHORT##", "Appointment's date", now.strftime(DATE_FORMAT_SHORT)),
+        ("##A_TIME##", "Appointment's time", now.strftime(DATE_FORMAT_TIME)),
+        ("##A_FLYING_TEAM##", "Appointment's flying team location", ""),
+        ("##A_LOCATION##", "Appointment's location", "value can be 'Flying Team'"),
+        ("##A_LOCATION_OR_FLYINGTEAM##", "Appointment's real location",
+         "if flying team then returns flying team exact location, otherwise returns location name"),
+        ("##A_STATUS##", "Appointment's status", ""),
+        ("##A_WORKER##", "Worker conducting the assessment", "first_name last_name"),
+        ("##A_WORKER_PHONE##", "Phone number of the worker conducting the assessment", ""),
+        ("##A_WORKER_EMAIL##", "Email address of the worker conducting the assessment", ""),
+        ("##A_ROOM##", "Appointment's room", 'room_number address city'),
+        ("##A_LENGTH##", "Appointment's duration", 'integer, value in minutes'),
+        ("##A_TYPES##", "Appointment's types", "comma separated"),
+    ]
+
+    name = models.CharField(max_length=255)
+    context = models.CharField(max_length=1, choices=MAIL_TEMPLATE_CONTEXT_CHOICES)
+    language = models.ForeignKey("web.Language", on_delete=models.CASCADE)
+    template_file = models.FileField(upload_to='templates/')
+
+    @staticmethod
+    def get_appointment_mail_templates(languages):
+        return MailTemplate.get_mail_templates_for_context(languages, MAIL_TEMPLATE_CONTEXT_APPOINTMENT)
+
+    @staticmethod
+    def get_subject_mail_templates(languages):
+        return MailTemplate.get_mail_templates_for_context(languages, MAIL_TEMPLATE_CONTEXT_SUBJECT)
+
+    @staticmethod
+    def get_visit_mail_templates(languages):
+        return MailTemplate.get_mail_templates_for_context(languages, MAIL_TEMPLATE_CONTEXT_VISIT)
+
+    @staticmethod
+    def get_mail_templates_for_context(languages, context):
+        languages_names = [language.name for language in languages]
+        templates = list(MailTemplate.objects.filter(context=context).all())
+        active_templates = []
+        disabled_templates = []
+        for template in templates:
+            if template.language.name in languages_names:
+                active_templates.append(template)
+            else:
+                disabled_templates.append(template)
+        active_templates.sort(key=lambda x: languages_names.index(x.language.name))
+        return active_templates, disabled_templates
+
+    def apply(self, instance, user, stream):
+        appointment = None
+        visit = None
+        subject = None
+        if isinstance(instance, Appointment):
+            appointment = instance
+            visit = instance.visit
+            subject = visit.subject
+        elif isinstance(instance, Visit):
+            visit = instance
+            subject = visit.subject
+        elif isinstance(instance, Subject):
+            subject = instance
+        # set locale to get correct date format
+        with setlocale(self.language.locale.encode('utf8')):
+            replacements = {}
+            self._add_generic_replacements(replacements, Worker.get_by_user(user))
+            self._add_appointment_replacements(replacements, appointment)
+            self._add_visit_replacements(replacements, visit)
+            self._add_subject_replacements(replacements, subject)
+            process_file(self.template_file.path, stream, replacements)
+        return stream
+
+    def _add_generic_replacements(self, replacements, worker):
+        current_datetime = datetime.datetime.now()
+        replacements.update({
+            "##DATE_FULL##": current_datetime.strftime(DATE_FORMAT_FULL),
+            "##DATE_SHORT##": current_datetime.strftime(DATE_FORMAT_SHORT),
+            "##WORKER##": str(worker)
+        })
+
+    def _add_appointment_replacements(self, replacements, appointment):
+        if appointment is not None:
+            if appointment.worker_assigned is not None:
+                worker_phone_number = appointment.worker_assigned.phone_number
+                worker_email_address = appointment.worker_assigned.email
+            else:
+                worker_phone_number = ""
+                worker_email_address = ""
+            if appointment.datetime_when is not None:
+                appointment_date_full = appointment.datetime_when.strftime(DATETIME_FORMAT)
+                appointment_date_short = appointment.datetime_when.strftime(DATE_FORMAT_SHORT)
+                appointment_date_time = appointment.datetime_when.strftime(DATE_FORMAT_TIME)
+            else:
+                appointment_date_full = appointment_date_short = appointment_date_time = ""
+            replacements.update({
+                "##A_DATE_FULL##": appointment_date_full,
+                "##A_DATE_SHORT##": appointment_date_short,
+                "##A_TIME##": appointment_date_time,
+                "##A_FLYING_TEAM##": appointment.flying_team,
+                "##A_STATUS##": appointment.get_status_display(),
+                "##A_LOCATION##": appointment.location.name,
+                "##A_LOCATION_OR_FLYINGTEAM##": appointment.flying_team or appointment.location.name,
+                "##A_WORKER##": str(appointment.worker_assigned),
+                '##A_WORKER_PHONE##': worker_phone_number,
+                '##A_WORKER_EMAIL##': worker_email_address,
+                "##A_ROOM##": str(appointment.room),
+                "##A_LENGTH##": appointment.length,
+                "##A_TYPES##": ", ".join([a.description for a in appointment.appointment_types.all()])
+            })
+
+    def _add_visit_replacements(self, replacements, visit):
+        if visit is not None:
+            replacements.update({
+                "##V_DATE_START_FULL##": visit.datetime_begin.strftime(DATETIME_FORMAT),
+                "##V_DATE_START_SHORT##": visit.datetime_begin.strftime(DATE_FORMAT_SHORT),
+                "##V_DATE_ENDS_FULL##": visit.datetime_end.strftime(DATETIME_FORMAT),
+                "##V_DATE_ENDS_SHORT##": visit.datetime_end.strftime(DATE_FORMAT_SHORT),
+            })
+
+    def _add_subject_replacements(self, replacements, subject):
+        if subject is not None:
+            if subject.date_born is not None:
+                date_born = subject.date_born.strftime(DATE_FORMAT_SHORT)
+            else:
+                date_born = None
+            replacements.update({
+                "##S_FULL_NAME##": str(subject),
+                "##S_FIRST_NAME##": subject.first_name,
+                "##S_LAST_NAME##": subject.last_name,
+                "##S_ADDRESS##": subject.address,
+                "##S_CITY##": subject.city,
+                "##S_COUNTRY##": subject.country,
+                "##S_DIAGNOSIS_YEAR##": subject.year_of_diagnosis,
+                "##S_DATE_ADDED##": subject.date_added.strftime(DATE_FORMAT_SHORT),
+                "##S_DATE_BORN##": date_born,
+                "##S_DIAGNOSIS##": subject.diagnosis,
+                "##S_EMAIL##": subject.email,
+                "##S_SEX##": subject.get_sex_display(),
+                "##S_MPOWER_ID##": subject.mpower_id,
+                "##S_ND_NUMBER##": subject.nd_number,
+                "##S_PHONE_NUMBER##": subject.phone_number,
+                "##S_PHONE_NUMBER_2##": subject.phone_number_2,
+                "##S_PHONE_NUMBER_3##": subject.phone_number_3,
+                "##S_POST_CODE##": subject.postal_code,
+                "##S_SCREENING_NUMBER##": subject.screening_number,
+                "##S_TYPE##": subject.get_type_display(),
+                '##S_MAIL_LANGUAGE##': subject.default_written_communication_language,
+                '##S_KNOWN_LANGUAGES##': ", ".join([l.name for l in subject.languages.all()])
+            })
diff --git a/smash/web/models/subject.py b/smash/web/models/subject.py
index d2425b84027e4f53d47b3187aa3a6cb6b832dcf8..53c798d39a212a4c27969344efa53a59c628b452 100644
--- a/smash/web/models/subject.py
+++ b/smash/web/models/subject.py
@@ -144,11 +144,6 @@ class Subject(models.Model):
         verbose_name='Year of diagnosis (YYYY)'
     )
 
-    dead = models.BooleanField(
-        verbose_name='Deceased',
-        default=False,
-        editable=True
-    )
     information_sent = models.BooleanField(
         verbose_name='Information sent',
         default=False
@@ -157,6 +152,11 @@ class Subject(models.Model):
         verbose_name='PD in family',
         default=False,
     )
+    dead = models.BooleanField(
+        verbose_name='Deceased',
+        default=False,
+        editable=True
+    )
     resigned = models.BooleanField(
         verbose_name='Resigned',
         default=False,
diff --git a/smash/web/email.py b/smash/web/smash_email.py
similarity index 79%
rename from smash/web/email.py
rename to smash/web/smash_email.py
index 6ed3208b503036cf40acde5bef6290fd7cad1b34..51d54ba029b0851bc44847db3e471a972487bde5 100644
--- a/smash/web/email.py
+++ b/smash/web/smash_email.py
@@ -1,12 +1,13 @@
 # coding=utf-8
 
 from django.conf import settings
-from django.core.mail import send_mail
 from django.core.mail import EmailMessage
 
 
 class EmailSender(object):
-    def send_email(self, subject, body, recipients, cc_recipients=[]):
+    def send_email(self, subject, body, recipients, cc_recipients=None):
+        if cc_recipients is None:
+            cc_recipients = []
         email_from = getattr(settings, "DEFAULT_FROM_EMAIL", None)
         recipient_list = []
         for recipient in recipients.split(";"):
@@ -23,4 +24,4 @@ class EmailSender(object):
         message.content_subtype = "html"
         message.send()
 
-#        send_mail(subject, "", email_from, recipient_list, cc=cc_recipients, html_message=body)
+# send_mail(subject, "", email_from, recipient_list, cc=cc_recipients, html_message=body)
diff --git a/smash/web/static/css/smash.css b/smash/web/static/css/smash.css
index 90663bb9f408b41852301da3312b6fe08ba495a6..6a442120428ed1c27543238002cbb35227ead65c 100644
--- a/smash/web/static/css/smash.css
+++ b/smash/web/static/css/smash.css
@@ -16,4 +16,10 @@
 
 .checkbox {
     margin-top: 10px !important;
+}
+
+.table-separator {
+    background-color: #f4f4f4;
+    font-variant: small-caps;
+    font-size: 1.5em;
 }
\ No newline at end of file
diff --git a/smash/web/static/js/smash.js b/smash/web/static/js/smash.js
new file mode 100644
index 0000000000000000000000000000000000000000..59ce07adc38e5620daf4570dc4ee41119f0844a7
--- /dev/null
+++ b/smash/web/static/js/smash.js
@@ -0,0 +1,9 @@
+$(document).ready(function () {
+    $("#save-and-continue").click(function () {
+        var form = $(this).parents("form");
+        var hidden_field = $("<input type='hidden' name='_continue' value='1' />");
+        form.append(hidden_field);
+        form.submit();
+    });
+
+});
\ No newline at end of file
diff --git a/smash/web/templates/_base.html b/smash/web/templates/_base.html
index 0c30d7e84c00da6b6e12a64b0a2455f32fabbe7f..96bcfee3f919f36ce5e1602e799ce529466b53a2 100644
--- a/smash/web/templates/_base.html
+++ b/smash/web/templates/_base.html
@@ -366,10 +366,12 @@ desired effect
     <script src="{% static 'AdminLTE/js/bootstrap.min.js' %}"></script>
     <!-- AdminLTE Template Helpers (for example- left side bar) -->
     <script src="{% static 'AdminLTE/js/app.min.js' %}"></script>
+    <!-- Smash js -->
+    <script src="{% static 'js/smash.js' %}"></script>
 
     <script>
         var activate = function (page_to_activate) {
-            var $e = $(".sidebar-menu > li[data-desc='" + page_to_activate + "']");
+            var $e = $(".sidebar-menu li[data-desc='" + page_to_activate + "']");
             $e.addClass("active");
         };
 
diff --git a/smash/web/templates/appointments/edit.html b/smash/web/templates/appointments/edit.html
index f6f59db5cb55c8e8da1eb02492a4cd738d6497e9..c74b9c982ab89bbb7eba9ad2573ec21eb9869108 100644
--- a/smash/web/templates/appointments/edit.html
+++ b/smash/web/templates/appointments/edit.html
@@ -87,16 +87,22 @@
                     </fieldset>
                 {% endif %}
                 <div class="box-footer">
-                    <div class="col-sm-6">
+                    <div class="col-sm-4">
                         <button type="submit" class="btn btn-block btn-success">Save</button>
                     </div>
-                    <div class="col-sm-6">
+                    <div class="col-sm-4">
+                        <button id="save-and-continue" type="button" class="btn btn-block btn-success">Save and
+                            Continue
+                        </button>
+                    </div>
+                    <div class="col-sm-4">
                         <a href="{% url 'web.views.appointments' %}" class="btn btn-block btn-default"
                            onclick="history.back()">Cancel</a>
                     </div>
                 </div><!-- /.box-footer -->
             </form>
         </div>
+        {% include 'includes/mail_templates_box.html' with instance_id=appointment.id %}
     {% endblock %}
 
 
diff --git a/smash/web/templates/includes/mail_templates_box.html b/smash/web/templates/includes/mail_templates_box.html
new file mode 100644
index 0000000000000000000000000000000000000000..392126cc5a27a8b65eec19b8cc258e5cf9e94218
--- /dev/null
+++ b/smash/web/templates/includes/mail_templates_box.html
@@ -0,0 +1,27 @@
+<div class="box box-success">
+    <div class="box-header with-border">
+        <h3>Generate Mail</h3>
+    </div>
+    <div class="box-body">
+        <h4>Available templates:</h4>
+        <p>
+            {% for mail_template in mail_templates.0 %}
+                <a href="{% url "web.views.mail_template_generate" mail_template.id instance_id %}"
+                   class="btn btn-app">
+                    <i class="fa"> {% autoescape off %}{{ mail_template.language.image_img }}{% endautoescape %}</i>
+                    {{ mail_template.name }}
+                </a>
+            {% endfor %}
+        </p>
+        <h4>Unavailable templates:</h4>
+        <p>
+            {% for mail_template in mail_templates.1 %}
+                <span
+                        class="btn btn-app disabled">
+                <i class="fa"> {% autoescape off %}{{ mail_template.language.image_img }}{% endautoescape %}</i>
+                {{ mail_template.name }}
+            </span>
+            {% endfor %}
+        <p></p>
+    </div>
+</div>
\ No newline at end of file
diff --git a/smash/web/templates/languages/add.html b/smash/web/templates/languages/add.html
new file mode 100644
index 0000000000000000000000000000000000000000..48a17cd04565f678ccb9fb13114a0d5a7bcfe2d3
--- /dev/null
+++ b/smash/web/templates/languages/add.html
@@ -0,0 +1,9 @@
+{% extends "languages/add_edit.html" %}
+
+{% block page_header %}New language{% endblock page_header %}
+
+{% block title %}{{ block.super }} - Add new language{% endblock %}
+
+{% block form-title %}Enter language §details{% endblock %}
+
+{% block save-button %}Add{% endblock %}
diff --git a/smash/web/templates/languages/add_edit.html b/smash/web/templates/languages/add_edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..794ba7c565fd4f2ef48e60e68b7095cb4c1610c2
--- /dev/null
+++ b/smash/web/templates/languages/add_edit.html
@@ -0,0 +1,77 @@
+{% extends "_base.html" %}
+{% load static %}
+{% load filters %}
+
+{% block styles %}
+    {{ block.super }}
+    <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/>
+
+{% endblock styles %}
+
+{% block ui_active_tab %}'configuration'{% endblock ui_active_tab %}
+{% block page_description %}{% endblock page_description %}
+
+{% block breadcrumb %}
+    {% include "languages/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+    {% block content %}
+        <div class="row">
+            <div class="col-md-12">
+                <div class="box box-success">
+                    <div class="box-header with-border">
+                        <h3 class="box-title">{% block form-title %}Enter language details{% endblock %}</h3>
+                    </div>
+
+
+                    <form method="post" action="" class="form-horizontal" enctype="multipart/form-data">
+                        {% csrf_token %}
+
+                        <div class="box-body">
+                            {% for field in form %}
+                                <div class="form-group {% if field.errors %}has-error{% endif %}">
+                                    <label class="col-sm-4  col-lg-offset-1 col-lg-2 control-label">
+                                        {{ field.label }}
+                                    </label>
+
+                                    <div class="col-sm-8 col-lg-4">
+                                        {{ field|add_class:'form-control' }}
+                                        {% if field.errors %}
+                                            <span class="help-block">{{ field.errors }}</span>
+                                        {% endif %}
+                                    </div>
+
+
+                                </div>
+                            {% endfor %}
+                        </div><!-- /.box-body -->
+                        <div class="box-footer">
+                            <div class="col-sm-6">
+                                <button type="submit" class="btn btn-block btn-success">{% block save-button %}
+                                    Add{% endblock %}
+                                </button>
+                            </div>
+                            <div class="col-sm-6">
+                                <a href="{% url 'web.views.languages' %}"
+                                   class="btn btn-block btn-default">Cancel</a>
+                            </div>
+                        </div><!-- /.box-footer -->
+                    </form>
+                </div>
+
+            </div>
+        </div>
+
+    {% endblock %}
+
+
+{% endblock maincontent %}
+
+{% block scripts %}
+    {{ block.super }}
+
+    <script src="{% static 'AdminLTE/plugins/awesomplete/awesomplete.min.js' %}"></script>
+
+{% endblock scripts %}
\ No newline at end of file
diff --git a/smash/web/templates/languages/breadcrumb.html b/smash/web/templates/languages/breadcrumb.html
new file mode 100644
index 0000000000000000000000000000000000000000..b3194bfb0a32794c726a75682425d7ea4b17f30d
--- /dev/null
+++ b/smash/web/templates/languages/breadcrumb.html
@@ -0,0 +1,2 @@
+<li><a href="{% url 'web.views.appointments' %}"><i class="fa fa-dashboard"></i> Dashboard</a></li>
+<li class="active"><a href="{% url 'web.views.languages' %}">Languages</a></li>
\ No newline at end of file
diff --git a/smash/web/templates/languages/confirm_delete.html b/smash/web/templates/languages/confirm_delete.html
new file mode 100644
index 0000000000000000000000000000000000000000..929c61370a2960ce8a0147249fdef6411f5d4a6c
--- /dev/null
+++ b/smash/web/templates/languages/confirm_delete.html
@@ -0,0 +1,62 @@
+{% extends "_base.html" %}
+{% load static %}
+{% load filters %}
+
+{% block styles %}
+    {{ block.super }}
+    <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/>
+
+{% endblock styles %}
+
+{% block ui_active_tab %}'configuration'{% endblock ui_active_tab %}
+{% block page_header %}Delete language{% endblock page_header %}
+{% block page_description %}{% endblock page_description %}
+
+{% block title %}{{ block.super }} - Delete language{% endblock %}
+
+{% block breadcrumb %}
+    {% include "languages/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+    {% block content %}
+        <div class="row">
+            <div class="col-md-12">
+                <div class="box box-success">
+                    <div class="box-header with-border">
+                        <h3 class="box-title">Confirm deletion</h3>
+                    </div>
+
+                    <form action="" method="post" class="form-horizontal">{% csrf_token %}
+                        <div class="box-body">
+                            <p>Are you sure you want to delete language "{{ object.name }}"?</p>
+                        </div><!-- /.box-body -->
+                        <div class="box-footer">
+                            <div class="col-sm-6">
+                                <button type="submit" class="btn btn-block btn-danger">Delete</button>
+                            </div>
+                            <div class="col-sm-6">
+                                <a href="{% url 'web.views.languages' %}"
+                                   class="btn btn-block btn-default">Cancel</a>
+                            </div>
+                        </div><!-- /.box-footer -->
+                    </form>
+                </div>
+
+            </div>
+        </div>
+
+    {% endblock %}
+
+
+{% endblock maincontent %}
+
+{% block scripts %}
+    {{ block.super }}
+
+    <script src="{% static 'AdminLTE/plugins/awesomplete/awesomplete.min.js' %}"></script>
+
+{% endblock scripts %}
+
+
diff --git a/smash/web/templates/languages/edit.html b/smash/web/templates/languages/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..ee96e0910981224b10d2ad0305cdebe40d5b63c9
--- /dev/null
+++ b/smash/web/templates/languages/edit.html
@@ -0,0 +1,10 @@
+{% extends "mail_templates/add_edit.html" %}
+
+{% block page_header %}Edit language "{{ language.name }}"{% endblock page_header %}
+
+{% block title %}{{ block.super }} - Edit language "{{ language.name }}"{% endblock %}
+
+{% block form-title %}Enter language details{% endblock %}
+
+{% block save-button %}Save{% endblock %}
+
diff --git a/smash/web/templates/languages/list.html b/smash/web/templates/languages/list.html
new file mode 100644
index 0000000000000000000000000000000000000000..eeb9eb68a3fff742857578282926129f210be213
--- /dev/null
+++ b/smash/web/templates/languages/list.html
@@ -0,0 +1,76 @@
+{% extends "_base.html" %}
+{% load static %}
+
+{% block styles %}
+    {{ block.super }}
+    <!-- DataTables -->
+    <link rel="stylesheet" href="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.css' %}">
+{% endblock styles %}
+
+{% block ui_active_tab %}'configuration'{% endblock ui_active_tab %}
+{% block page_header %}Languages{% endblock page_header %}
+{% block page_description %}{% endblock page_description %}
+
+{% block breadcrumb %}
+    {% include "languages/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+    <div>
+        <a class="btn btn-app" href="{% url 'web.views.language_add' %}">
+            <i class="fa fa-plus"></i> Add new language
+        </a>
+    </div>
+
+    <div class="box-body">
+        <table id="table" class="table table-bordered table-striped">
+            <thead>
+            <tr>
+                <th>Id</th>
+                <th>Name</th>
+                <th>Flag</th>
+                <th>Order</th>
+                <th>Locale</th>
+                <th>Edit</th>
+                <th>Delete</th>
+            </tr>
+            </thead>
+            <tbody>
+            {% for language in languages %}
+                <tr>
+                    <td>{{ language.id }}</td>
+                    <td>{{ language.name }}</td>
+                    <td>{% autoescape off %}{{ language.image_img }}{% endautoescape %}</td>
+                    <td>{{ language.order }}</td>
+                    <td>{{ language.locale }}</td>
+                    <td><a href="{% url 'web.views.language_edit' language.id %}"><i
+                            class="fa fa-edit"></i></a></td>
+                    <td><a href="{% url 'web.views.language_delete' language.id %}"><i
+                            class="fa fa-trash text-danger"></i></a></td>
+                </tr>
+            {% endfor %}
+            </tbody>
+        </table>
+    </div>
+{% endblock maincontent %}
+
+{% block scripts %}
+    {{ block.super }}
+
+    <script src="{% static 'AdminLTE/plugins/datatables/jquery.dataTables.min.js' %}"></script>
+    <script src="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js' %}"></script>
+
+    <script>
+        $(function () {
+            $('#table').DataTable({
+                "paging": true,
+                "lengthChange": false,
+                "searching": true,
+                "ordering": true,
+                "info": true,
+                "autoWidth": false
+            });
+        });
+    </script>
+{% endblock scripts %}
diff --git a/smash/web/templates/mail_templates/add.html b/smash/web/templates/mail_templates/add.html
new file mode 100644
index 0000000000000000000000000000000000000000..561eb1a989caa72dda2f5db7e2d6aabf77e34330
--- /dev/null
+++ b/smash/web/templates/mail_templates/add.html
@@ -0,0 +1,8 @@
+{% extends "mail_templates/add_edit.html" %}
+
+{% block page_header %}New mail template{% endblock page_header %}
+
+{% block title %}{{ block.super }} - Add new mail template{% endblock %}
+
+{% block form-title %}Enter mail template details{% endblock %}
+{% block save-button %}Add{% endblock %}
\ No newline at end of file
diff --git a/smash/web/templates/mail_templates/add_edit.html b/smash/web/templates/mail_templates/add_edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..4fbc937166272b85854f269c6b0d090cb677141a
--- /dev/null
+++ b/smash/web/templates/mail_templates/add_edit.html
@@ -0,0 +1,76 @@
+{% extends "_base.html" %}
+{% load static %}
+{% load filters %}
+
+{% block styles %}
+    {{ block.super }}
+    <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/>
+
+{% endblock styles %}
+
+{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %}
+{% block page_description %}{% endblock page_description %}
+
+{% block breadcrumb %}
+    {% include "mail_templates/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+    {% block content %}
+        <div class="row">
+            <div class="col-md-12">
+                <div class="box box-success">
+                    <div class="box-header with-border">
+                        <h3 class="box-title">{% block form-title %}Enter mail template details{% endblock %}</h3>
+                    </div>
+
+
+                    <form method="post" action="" class="form-horizontal" enctype="multipart/form-data">
+                        {% csrf_token %}
+
+                        <div class="box-body">
+                            {% for field in form %}
+                                <div class="form-group {% if field.errors %}has-error{% endif %}">
+                                    <label class="col-sm-4  col-lg-offset-1 col-lg-2 control-label">
+                                        {{ field.label }}
+                                    </label>
+
+                                    <div class="col-sm-8 col-lg-4">
+                                        {{ field|add_class:'form-control' }}
+                                        {% if field.errors %}
+                                            <span class="help-block">{{ field.errors }}</span>
+                                        {% endif %}
+                                    </div>
+
+
+                                </div>
+                            {% endfor %}
+                        </div><!-- /.box-body -->
+                        <div class="box-footer">
+                            <div class="col-sm-6">
+                                <button type="submit" class="btn btn-block btn-success">{% block save-button %}
+                                    Add{% endblock %}</button>
+                            </div>
+                            <div class="col-sm-6">
+                                <a href="{% url 'web.views.mail_templates' %}"
+                                   class="btn btn-block btn-default">Cancel</a>
+                            </div>
+                        </div><!-- /.box-footer -->
+                    </form>
+                </div>
+
+            </div>
+        </div>
+
+    {% endblock %}
+
+
+{% endblock maincontent %}
+
+{% block scripts %}
+    {{ block.super }}
+
+    <script src="{% static 'AdminLTE/plugins/awesomplete/awesomplete.min.js' %}"></script>
+
+{% endblock scripts %}
\ No newline at end of file
diff --git a/smash/web/templates/mail_templates/confirm_delete.html b/smash/web/templates/mail_templates/confirm_delete.html
new file mode 100644
index 0000000000000000000000000000000000000000..48b1967d7f4ae545ce63aed1474c707f80f405dc
--- /dev/null
+++ b/smash/web/templates/mail_templates/confirm_delete.html
@@ -0,0 +1,62 @@
+{% extends "_base.html" %}
+{% load static %}
+{% load filters %}
+
+{% block styles %}
+    {{ block.super }}
+    <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/>
+
+{% endblock styles %}
+
+{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %}
+{% block page_header %}Delete mail template{% endblock page_header %}
+{% block page_description %}{% endblock page_description %}
+
+{% block title %}{{ block.super }} - Delete mail template{% endblock %}
+
+{% block breadcrumb %}
+    {% include "mail_templates/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+    {% block content %}
+        <div class="row">
+            <div class="col-md-12">
+                <div class="box box-success">
+                    <div class="box-header with-border">
+                        <h3 class="box-title">Confirm deletion</h3>
+                    </div>
+
+                    <form action="" method="post" class="form-horizontal">{% csrf_token %}
+                        <div class="box-body">
+                            <p>Are you sure you want to delete mail template "{{ object.name }}"?</p>
+                        </div><!-- /.box-body -->
+                        <div class="box-footer">
+                            <div class="col-sm-6">
+                                <button type="submit" class="btn btn-block btn-danger">Delete</button>
+                            </div>
+                            <div class="col-sm-6">
+                                <a href="{% url 'web.views.mail_templates' %}"
+                                   class="btn btn-block btn-default">Cancel</a>
+                            </div>
+                        </div><!-- /.box-footer -->
+                    </form>
+                </div>
+
+            </div>
+        </div>
+
+    {% endblock %}
+
+
+{% endblock maincontent %}
+
+{% block scripts %}
+    {{ block.super }}
+
+    <script src="{% static 'AdminLTE/plugins/awesomplete/awesomplete.min.js' %}"></script>
+
+{% endblock scripts %}
+
+
diff --git a/smash/web/templates/mail_templates/edit.html b/smash/web/templates/mail_templates/edit.html
new file mode 100644
index 0000000000000000000000000000000000000000..d166d86a3b9bd34d14fd6a792b46572e41a53f0a
--- /dev/null
+++ b/smash/web/templates/mail_templates/edit.html
@@ -0,0 +1,9 @@
+{% extends "mail_templates/add_edit.html" %}
+
+{% block page_header %}Edit mail template "{{ mail_template.name }}"{% endblock page_header %}
+
+{% block title %}{{ block.super }} - Edit mail template "{{ mail_template.name }}"{% endblock %}
+
+{% block form-title %}Enter mail template details{% endblock %}
+
+{% block save-button %}Save{% endblock %}
diff --git a/smash/web/templates/mail_templates/list.html b/smash/web/templates/mail_templates/list.html
new file mode 100644
index 0000000000000000000000000000000000000000..f403957a7904b464a1a28ca7b817388b3254c9a7
--- /dev/null
+++ b/smash/web/templates/mail_templates/list.html
@@ -0,0 +1,115 @@
+{% extends "_base.html" %}
+{% load static %}
+
+{% block styles %}
+    {{ block.super }}
+    <!-- DataTables -->
+    <link rel="stylesheet" href="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.css' %}">
+{% endblock styles %}
+
+{% block ui_active_tab %}'mail_templates'{% endblock ui_active_tab %}
+{% block page_header %}Mail templates{% endblock page_header %}
+{% block page_description %}{% endblock page_description %}
+
+{% block breadcrumb %}
+    {% include "mail_templates/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+
+    <div class="box box-success">
+        <div class="box-header with-border">
+            <h3 class="box-title">Templates</h3>
+        </div>
+        <div class="box-body">
+
+            <div>
+                <a class="btn btn-app" href="{% url 'web.views.mail_template_add' %}">
+                    <i class="fa fa-plus"></i> Add new template
+                </a>
+            </div>
+            <table id="table" class="table table-bordered table-striped">
+                <thead>
+                <tr>
+                    <th>No.</th>
+                    <th>Context</th>
+                    <th>Language</th>
+                    <th>Name</th>
+                    <th>Download</th>
+                    <th>Edit</th>
+                    <th>Delete</th>
+                </tr>
+                </thead>
+                <tbody>
+                {% for mail_template in mail_templates %}
+                    <tr>
+                        <td>{{ forloop.counter }}</td>
+                        <td>{{ mail_template.get_context_display }}</td>
+                        <td>{% autoescape off %}{{ mail_template.language.image_img }}{% endautoescape %}</td>
+                        <td>{{ mail_template.name }}</td>
+                        <td><a href="{{ mail_template.template_file.url }}"><i class="fa fa-download"></i></a></td>
+                        <td><a href="{% url 'web.views.mail_template_edit' mail_template.id %}"><i
+                                class="fa fa-edit"></i></a></td>
+                        <td><a href="{% url 'web.views.mail_template_delete' mail_template.id %}"><i
+                                class="fa fa-trash text-danger"></i></a></td>
+                    </tr>
+                {% endfor %}
+                </tbody>
+            </table>
+        </div>
+    </div>
+
+    <div class="box box-success">
+        <div class="box-header with-border">
+            <h3 class="box-title">Tags <i class="fa fa-question-circle"></i></h3>
+        </div>
+        <div class="box-body">
+            <p>The following tags can be used within the Word documents and will be replaced by actual values during the
+                mail generation.</p>
+            <table id="table" class="table table-bordered table-striped">
+                <thead>
+                <tr>
+                    <th>Placeholder</th>
+                    <th>Description</th>
+                    <th>Comment</th>
+                </tr>
+                </thead>
+                <tbody>
+                {% for name, tags in explanations.items %}
+                    <tr>
+                        <td class="table-separator" colspan="3">{{ name | title }}</td>
+                    </tr>
+                    {% for tag in tags %}
+                        <tr>
+                            <td>{{ tag.0 }}</td>
+                            <td>{{ tag.1 }}</td>
+                            <td>{{ tag.2 }}</td>
+                        </tr>
+                    {% endfor %}
+                {% endfor %}
+                </tbody>
+            </table>
+        </div>
+    </div>
+{% endblock maincontent %}
+
+{% block scripts %}
+    {{ block.super }}
+
+    <script src="{% static 'AdminLTE/plugins/datatables/jquery.dataTables.min.js' %}"></script>
+    <script src="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js' %}"></script>
+
+    <script>
+        $(function () {
+            $('#table').DataTable({
+                "paging": true,
+                "lengthChange": false,
+                "searching": true,
+                "ordering": true,
+                "info": true,
+                "autoWidth": false
+            });
+        });
+    </script>
+{% endblock scripts %}
diff --git a/smash/web/templates/sidebar.html b/smash/web/templates/sidebar.html
index 19cd2afa61d442d314a2d0d5e97871f7a1352ff9..de78cae857ebdc2301f2acd619776bc54fb54795 100644
--- a/smash/web/templates/sidebar.html
+++ b/smash/web/templates/sidebar.html
@@ -57,12 +57,19 @@
             <span>Export</span>
         </a>
     </li>
-
-    <li data-desc="configuration">
-        <a href="{% url 'web.views.configuration' %}">
-            <i class="fa fa-wrench"></i>
-            <span>Configuration</span>
+    <li data-desc="configuration" class="treeview">
+        <a href="#">
+            <i class="fa fa-wrench"></i> <span>Configuration</span>
+            <span class="pull-right-container">
+              <i class="fa fa-angle-left pull-right"></i>
+            </span>
         </a>
+        <ul class="treeview-menu">
+            <li><a href="{% url 'web.views.configuration' %}">General</a></li>
+            <li>
+                <a href="{% url 'web.views.languages' %}">Languages</a>
+            </li>
+        </ul>
     </li>
 
 </ul>
\ No newline at end of file
diff --git a/smash/web/templates/subjects/edit.html b/smash/web/templates/subjects/edit.html
index 3e52807ee3294af7f56bc5956d8465adce753f7a..22c88550ac80adf6f9eb9a8e04e412b804314afb 100644
--- a/smash/web/templates/subjects/edit.html
+++ b/smash/web/templates/subjects/edit.html
@@ -70,10 +70,15 @@
 
 
                         <div class="box-footer">
-                            <div class="col-sm-6">
+                            <div class="col-sm-4">
                                 <button type="submit" class="btn btn-block btn-success">Save</button>
                             </div>
-                            <div class="col-sm-6">
+                            <div class="col-sm-4">
+                                <button id="save-and-continue" type="button" class="btn btn-block btn-success">Save and
+                                    Continue
+                                </button>
+                            </div>
+                            <div class="col-sm-4">
                                 <a href="{% url 'web.views.subjects' %}" class="btn btn-block btn-default"
                                    onclick="history.back()">Cancel</a>
                             </div>
@@ -82,6 +87,9 @@
                 </div><!-- /.box -->
             </div><!-- /.col-md-12 -->
         </div><!-- /.row -->
+
+        {% include 'includes/mail_templates_box.html' with instance_id=subject.id %}
+
         <div class="row">
             <div class="col-lg-12">
                 <div class="box box-success">
@@ -123,6 +131,8 @@
             </div>
         </div>
 
+
+
         <div class="modal modal-danger fade" id="confirm-dead-resigned-mark-dialog" tabindex="-1" role="dialog">
             <div class="modal-dialog" role="document">
                 <div class="modal-content">
diff --git a/smash/web/templates/visits/details.html b/smash/web/templates/visits/details.html
index d62679f19ab2cc314668c17c6b892f04cced51b3..db9aaab5303d7839042991a5b06bbfa3364231d7 100644
--- a/smash/web/templates/visits/details.html
+++ b/smash/web/templates/visits/details.html
@@ -80,7 +80,7 @@
                 </div><!-- /.box-body -->
                 <div class="box-footer">
                     <div class="col-sm-12">
-                        <button type="submit" class="btn btn-block btn-success">Save</button>
+                        <button type="submit" class="btn btn-block btn-success">Save and continue</button>
                     </div>
                 </div><!-- /.box-footer -->
             </form>
@@ -182,11 +182,11 @@
             </form>
         </div>
 
-        </form>
+        {% include 'includes/mail_templates_box.html' with instance_id=visit.id %}
+
     {% endblock %}
 
 
-    </div>
 
 {% endblock maincontent %}
 
diff --git a/smash/web/tests/__init__.py b/smash/web/tests/__init__.py
index 72b9f9adc3193fb034ac7656aea51eae348acddc..6782804f7cfe81faf815c0d9679159eed66a3816 100644
--- a/smash/web/tests/__init__.py
+++ b/smash/web/tests/__init__.py
@@ -1,9 +1,13 @@
+import os
+from django.conf import settings
 from django.contrib.auth.models import User
 from django.test import Client
 from django.test import TestCase
 
 from functions import create_worker
 
+settings.MEDIA_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data')
+
 
 class LoggedInTestCase(TestCase):
     def setUp(self):
diff --git a/smash/web/tests/data/template.docx b/smash/web/tests/data/template.docx
new file mode 100644
index 0000000000000000000000000000000000000000..17aee71db3c1b8699e27daf1e0701420150976a0
Binary files /dev/null and b/smash/web/tests/data/template.docx differ
diff --git a/smash/web/tests/data/upcoming_appointment_FR.docx b/smash/web/tests/data/upcoming_appointment_FR.docx
new file mode 100644
index 0000000000000000000000000000000000000000..b118fadd9d2aa89b8a7596ffe1d534e17d33f2d3
Binary files /dev/null and b/smash/web/tests/data/upcoming_appointment_FR.docx differ
diff --git a/smash/web/tests/functions.py b/smash/web/tests/functions.py
index fea131ec68825d924ccc2e8ec60e6d0d5035d88d..24cd16c2bff10bebb7076afc7b14c00c05354fd7 100644
--- a/smash/web/tests/functions.py
+++ b/smash/web/tests/functions.py
@@ -1,8 +1,9 @@
 import datetime
 
+import os
 from django.contrib.auth.models import User
 
-from web.models import Location, AppointmentType, Subject, Worker, Visit, Appointment, ConfigurationItem
+from web.models import Location, AppointmentType, Subject, Worker, Visit, Appointment, ConfigurationItem, Language
 from web.models.constants import SEX_CHOICES_MALE, SUBJECT_TYPE_CHOICES_CONTROL
 from web.views.notifications import get_today_midnight_date
 
@@ -42,7 +43,8 @@ def create_subject(id=1):
         sex=SEX_CHOICES_MALE,
         type=SUBJECT_TYPE_CHOICES_CONTROL,
         screening_number="piotr's number" + str(id),
-        country="france")
+        country="france"
+    )
 
 
 def create_user(username=None, password=None):
@@ -84,6 +86,8 @@ def create_visit(subject=None):
 def create_appointment(visit=None, when=None):
     if visit is None:
         visit = create_visit()
+    # if when is None:
+    #     when = get_today_midnight_date()
     return Appointment.objects.create(
         visit=visit,
         length=30,
@@ -97,4 +101,14 @@ def create_configuration_item():
     item.value = "xxx"
     item.name = "yyy"
     item.save()
-    return item;
+    return item
+
+
+def create_language(name="French", locale="fr_FR"):
+    language = Language(name=name, locale=locale)
+    language.save()
+    return language
+
+
+def get_resource_path(filename):
+    return os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data', filename)
diff --git a/smash/web/tests/test_email.py b/smash/web/tests/test_email.py
index 879acc7e3b4164b87d40d6c7cbc150f8c3ac9349..460d681334d5d405cb928b4f16ca15a54079af6f 100644
--- a/smash/web/tests/test_email.py
+++ b/smash/web/tests/test_email.py
@@ -3,7 +3,7 @@
 from django.core import mail
 from django.test import TestCase
 
-from web.email import EmailSender
+from web.smash_email import EmailSender
 
 
 class TestEmailSender(TestCase):
diff --git a/smash/web/tests/test_model_mail_template.py b/smash/web/tests/test_model_mail_template.py
new file mode 100644
index 0000000000000000000000000000000000000000..0460314373a98c926c4dcabf9b725cf9949efd81
--- /dev/null
+++ b/smash/web/tests/test_model_mail_template.py
@@ -0,0 +1,125 @@
+import StringIO
+
+from django.test import TestCase
+from docx import Document
+
+from functions import create_language, get_resource_path, create_appointment, create_user, create_subject, \
+    create_visit
+from web.models import MailTemplate
+from web.models.constants import MAIL_TEMPLATE_CONTEXT_APPOINTMENT, MAIL_TEMPLATE_CONTEXT_VISIT, \
+    MAIL_TEMPLATE_CONTEXT_SUBJECT
+from web.models.mail_template import DATE_FORMAT_SHORT
+
+
+class MailTemplateModelTests(TestCase):
+    def setUp(self):
+        self.french_language = create_language("French", "fr_FR")
+        self.english_language = create_language("English", "en_GB")
+        self.template_file = get_resource_path('upcoming_appointment_FR.docx')
+        self.user = create_user()
+
+    def test_get_appointment_mail_templates(self):
+        context = MAIL_TEMPLATE_CONTEXT_APPOINTMENT
+        function_to_test = MailTemplate.get_appointment_mail_templates
+        self.check_get_mail_templates(context, function_to_test)
+
+    def test_get_visit_mail_templates(self):
+        context = MAIL_TEMPLATE_CONTEXT_VISIT
+        function_to_test = MailTemplate.get_visit_mail_templates
+        self.check_get_mail_templates(context, function_to_test)
+
+    def test_get_subject_mail_templates(self):
+        context = MAIL_TEMPLATE_CONTEXT_SUBJECT
+        function_to_test = MailTemplate.get_subject_mail_templates
+        self.check_get_mail_templates(context, function_to_test)
+
+    def check_get_mail_templates(self, context, function_to_test):
+        # create french template
+        template_name_french = "test_fr"
+        appointment_template_french = MailTemplate(name=template_name_french, language=self.french_language,
+                                                   context=context,
+                                                   template_file=self.template_file)
+        appointment_template_french.save()
+        # create english template
+        template_name_english = "test_en"
+        appointment_template_english = MailTemplate(name=template_name_english, language=self.english_language,
+                                                    context=context,
+                                                    template_file=self.template_file)
+        appointment_template_english.save()
+        active_templates, inactive_templates = function_to_test([self.french_language])
+        self.assertEqual(1, len(active_templates), "only on active template should be returned (for french)")
+        self.assertEqual(1, len(inactive_templates), "only on inactive template should be returned (for english)")
+        self.assertEqual(template_name_french, active_templates[0].name)
+        self.assertEqual(template_name_english, inactive_templates[0].name)
+        # now tries with multiple languages
+        active_templates, inactive_templates = function_to_test(
+            [self.english_language, self.french_language])
+        self.assertEqual(2, len(active_templates), "two active templates should be returned (for french and english)")
+        self.assertEqual(0, len(inactive_templates), "no inactive template should be returned")
+        # also checks the correct sorting
+        self.assertEqual(template_name_english, active_templates[0].name)
+        self.assertEqual(template_name_french, active_templates[1].name)
+
+        # tries with no languages
+        active_templates, inactive_templates = function_to_test([])
+        self.assertEqual(0, len(active_templates), "no active templates should be returned")
+        self.assertEqual(2, len(inactive_templates), "two inactive templates should be returned (french and english)")
+
+    def test_apply_appointment(self):
+        template_name_french = "test_fr"
+        appointment = create_appointment()
+        appointment_template_french = MailTemplate(name=template_name_french, language=self.french_language,
+                                                   context=MAIL_TEMPLATE_CONTEXT_APPOINTMENT,
+                                                   template_file=self.template_file)
+        stream = StringIO.StringIO()
+        appointment_template_french.apply(appointment, self.user, stream)
+        doc = Document(stream)
+        worker_name = str(self.user.worker)
+        location = appointment.location.name
+        self.check_doc_contains(doc, [worker_name, location])
+
+    def test_apply_subject(self):
+        template_name_french = "test_fr"
+        subject = create_subject()
+        subject_template_french = MailTemplate(name=template_name_french, language=self.french_language,
+                                               context=MAIL_TEMPLATE_CONTEXT_SUBJECT,
+                                               template_file=self.template_file)
+        stream = StringIO.StringIO()
+        subject_template_french.apply(subject, self.user, stream)
+        doc = Document(stream)
+        worker_name = str(self.user.worker)
+
+        self.check_doc_contains(doc, [worker_name, str(subject), subject.country, subject.nd_number,
+                                      subject.get_type_display()])
+
+    def test_apply_visit(self):
+        template_name_french = "test_fr"
+        visit = create_visit()
+        visit_template_french = MailTemplate(name=template_name_french, language=self.french_language,
+                                             context=MAIL_TEMPLATE_CONTEXT_VISIT,
+                                             template_file=self.template_file)
+        stream = StringIO.StringIO()
+        visit_template_french.apply(visit, self.user, stream)
+        doc = Document(stream)
+        worker_name = str(self.user.worker)
+
+        self.check_doc_contains(doc, [worker_name, str(visit.subject), visit.subject.country, visit.subject.nd_number,
+                                      visit.subject.get_type_display(),
+                                      visit.datetime_begin.strftime(DATE_FORMAT_SHORT),
+                                      visit.datetime_end.strftime(DATE_FORMAT_SHORT)])
+
+    def check_doc_contains(self, doc, needles):
+        founds = [False] * len(needles)
+        all_founds = False
+        count_found = 0
+        for paragraph in doc.paragraphs:
+            for i in range(0, len(needles)):
+                if not founds[i] and needles[i] in paragraph.text:
+                    founds[i] = True
+                    count_found += 1
+            if count_found == len(needles):
+                all_founds = True
+                break
+        if not all_founds:
+            for i in range(0, len(needles)):
+                self.assertTrue(founds[i], "{} was not found in the generated Word document".format(needles[i]))
diff --git a/smash/web/tests/test_process_file.py b/smash/web/tests/test_process_file.py
new file mode 100644
index 0000000000000000000000000000000000000000..413530a2a102ef9fbf36510de2f8c4eddcc6b79a
--- /dev/null
+++ b/smash/web/tests/test_process_file.py
@@ -0,0 +1,29 @@
+import datetime
+import locale
+import tempfile
+
+import os
+from django.test import TestCase
+
+from functions import get_resource_path
+from web.docx_helper import process_file
+
+
+class TestDocxProcessor(TestCase):
+    def test_process_file(self):
+        template_path = get_resource_path('template.docx')
+        locale.setlocale(locale.LC_TIME, "fr_FR")
+        output_path = tempfile.mktemp()
+        changes = {
+            "##SIR##": "Mr",
+            "##NAME##": "Jan",
+            "##SURNAME##": "Weglarz",
+            "##ADDRESS1##": "Piotrowo 23",
+            "##ADDRESS2##": "61-234, Poznan",
+            "##COUNTRY##": "POLAND",
+            "##CONTENT##": "1",
+            "##DATE##": datetime.datetime.now().date().strftime("%A %-d %B %Y"),
+        }
+        process_file(template_path, output_path, changes)
+        self.assertTrue(os.path.isfile(output_path))
+        os.remove(output_path)
diff --git a/smash/web/urls.py b/smash/web/urls.py
index 83a16c80987041c894842f77b1427cf6420aeb34..d57fa428213f97060c88501bb153cfd9becd1d4d 100644
--- a/smash/web/urls.py
+++ b/smash/web/urls.py
@@ -68,7 +68,8 @@ urlpatterns = [
     #    CONTACTS      #
     ####################
 
-    url(r'^subjects/(?P<subject_id>\d+)/contacts/add$', views.contact_attempt.contact_add, name='web.views.contact_add'),
+    url(r'^subjects/(?P<subject_id>\d+)/contacts/add$', views.contact_attempt.contact_add,
+        name='web.views.contact_add'),
 
     ####################
     #     DOCTORS      #
@@ -100,7 +101,26 @@ urlpatterns = [
     #       MAIL       #
     ####################
 
-    url(r'^mail_templates$', views.mails.mail_templates, name='web.views.mail_templates'),
+    url(r'^mail_templates_old$', views.mails.mail_templates, name='web.views.mail_templates_old'),
+    url(r'^mail_templates$', views.mails.MailTemplatesListView.as_view(), name='web.views.mail_templates'),
+    url(r'^mail_templates/add$', views.mails.MailTemplatesCreateView.as_view(), name='web.views.mail_template_add'),
+    url(r'^mail_templates/(?P<pk>\d+)/delete$', views.mails.MailTemplatesDeleteView.as_view(),
+        name='web.views.mail_template_delete'),
+    url(r'^mail_templates/(?P<pk>\d+)/edit$', views.mails.MailTemplatesEditView.as_view(),
+        name='web.views.mail_template_edit'),
+    url(r'^mail_templates/(?P<mail_template_id>\d+)/generate/(?P<instance_id>\d+)$', views.mails.generate,
+        name="web.views.mail_template_generate"),
+
+    ####################
+    #     LANGUAGES    #
+    ####################
+
+    url(r'^languages$', views.language.LanguageListView.as_view(), name='web.views.languages'),
+    url(r'^languages/add$', views.language.LanguageCreateView.as_view(), name='web.views.language_add'),
+    url(r'^languages/(?P<pk>\d+)/delete$', views.language.LanguageDeleteView.as_view(),
+        name='web.views.language_delete'),
+    url(r'^languages/(?P<pk>\d+)/edit$', views.language.LanguageEditView.as_view(),
+        name='web.views.language_edit'),
 
     ####################
     #    STATISTICS    #
diff --git a/smash/web/views/__init__.py b/smash/web/views/__init__.py
index e78ca58cbcfbf9adab1177766bbcedea96fd51ca..4322cb370c651c5e613bf6f708f68a559aa7c315 100644
--- a/smash/web/views/__init__.py
+++ b/smash/web/views/__init__.py
@@ -2,6 +2,7 @@
 
 from django.contrib.auth.decorators import login_required
 from django.shortcuts import redirect, render
+from django.views.generic.base import ContextMixin
 
 from notifications import get_notifications
 from ..models import Worker
@@ -36,18 +37,26 @@ def e400_bad_request(request, context=None):
 
 @login_required
 def wrap_response(request, template, params):
-    person, role = Worker.get_details(request.user)
+    final_params = extend_context(params, request)
+    return render(request, template, final_params)
 
-    notifications = get_notifications(request.user)
 
+def extend_context(params, request):
+    person, role = Worker.get_details(request.user)
+    notifications = get_notifications(request.user)
     final_params = params.copy()
     final_params.update({
         'person': person,
         'role': role,
         'notifications': notifications
     })
+    return final_params
 
-    return render(request, template, final_params)
+
+class WrappedView(ContextMixin):
+    def get_context_data(self, **kwargs):
+        context = super(WrappedView, self).get_context_data(**kwargs)
+        return extend_context(context, self.request)
 
 
 import auth
@@ -62,3 +71,4 @@ import statistics
 import export
 import contact_attempt
 import configuration_item
+import language
diff --git a/smash/web/views/appointment.py b/smash/web/views/appointment.py
index 760b83884517ec462f60df31e0dc51ed17bf9b41..25841372be897b94d191d2228010ceb7a772bb00 100644
--- a/smash/web/views/appointment.py
+++ b/smash/web/views/appointment.py
@@ -1,9 +1,10 @@
 # coding=utf-8
+from django.contrib import messages
 from django.shortcuts import get_object_or_404, redirect
 
 from . import wrap_response
 from ..forms import AppointmentDetailForm, AppointmentAddForm, AppointmentEditForm, SubjectEditForm
-from ..models import Appointment, Subject
+from ..models import Appointment, Subject, MailTemplate
 
 APPOINTMENT_LIST_GENERIC = "GENERIC"
 APPOINTMENT_LIST_UNFINISHED = "UNFINISHED"
@@ -81,6 +82,9 @@ def appointment_edit(request, id):
                 subject.information_sent = True
                 subject.save()
 
+            messages.success(request, "Modifications saved")
+            if '_continue' in request.POST:
+                return redirect('web.views.appointment_edit', id=the_appointment.id)
             if (the_appointment.status != Appointment.APPOINTMENT_STATUS_SCHEDULED) and (
                         the_appointment.visit is not None):
                 return redirect('web.views.visit_details', id=the_appointment.visit.id)
@@ -91,9 +95,16 @@ def appointment_edit(request, id):
         if the_appointment.visit is not None:
             subject_form = SubjectEditForm(instance=the_appointment.visit.subject, prefix="subject")
 
+    languages = []
+    if the_appointment.visit is not None:
+        subject = the_appointment.visit.subject
+        if subject.default_written_communication_language:
+            languages.append(subject.default_written_communication_language)
+        languages.extend(subject.languages.all())
     return wrap_response(request, 'appointments/edit.html', {
         'form': appointment_form,
         'subject_form': subject_form,
         'id': id,
-        'appointment': the_appointment
+        'appointment': the_appointment,
+        'mail_templates': MailTemplate.get_appointment_mail_templates(languages)
     })
diff --git a/smash/web/views/language.py b/smash/web/views/language.py
new file mode 100644
index 0000000000000000000000000000000000000000..463210b74ece287296f76634dd29a4a41e8d4df9
--- /dev/null
+++ b/smash/web/views/language.py
@@ -0,0 +1,47 @@
+# coding=utf-8
+from django.contrib import messages
+from django.urls import reverse_lazy
+from django.views.generic import CreateView
+from django.views.generic import DeleteView
+from django.views.generic import ListView
+from django.views.generic import UpdateView
+
+from . import WrappedView
+from ..models import Language
+
+
+class LanguageListView(ListView, WrappedView):
+    model = Language
+    context_object_name = "languages"
+    template_name = 'languages/list.html'
+
+
+class LanguageCreateView(CreateView, WrappedView):
+    model = Language
+    template_name = "languages/add.html"
+    fields = '__all__'
+    success_url = reverse_lazy('web.views.languages')
+    success_message = "Template created"
+
+
+class LanguageDeleteView(DeleteView, WrappedView):
+    model = Language
+    success_url = reverse_lazy('web.views.languages')
+    template_name = 'languages/confirm_delete.html'
+
+    def delete(self, request, *args, **kwargs):
+        messages.success(request, "Template deleted")
+        return super(LanguageDeleteView, self).delete(request, *args, **kwargs)
+
+
+class LanguageEditView(UpdateView, WrappedView):
+    model = Language
+    success_url = reverse_lazy('web.views.languages')
+    fields = '__all__'
+    success_message = "Template edited"
+    template_name = "languages/edit.html"
+    context_object_name = "language"
+
+
+def generate(request, mail_template_id, instance_id):
+    return None
diff --git a/smash/web/views/mails.py b/smash/web/views/mails.py
index 041daa092e41c729c55e0d0262d1f4e5352191d4..abe5d7f79cf1d12b087d2da1c5b66a9314f4ee1b 100644
--- a/smash/web/views/mails.py
+++ b/smash/web/views/mails.py
@@ -1,6 +1,86 @@
 # coding=utf-8
-from . import wrap_response
+import StringIO
+from wsgiref.util import FileWrapper
+
+from django.contrib import messages
+from django.contrib.auth.decorators import login_required
+from django.http import HttpResponse
+from django.shortcuts import get_object_or_404
+from django.urls import reverse_lazy
+from django.views.generic import CreateView
+from django.views.generic import DeleteView
+from django.views.generic import ListView
+from django.views.generic import UpdateView
+
+from . import wrap_response, WrappedView
+from ..models import Subject, Visit, Appointment, MailTemplate
+from ..models.constants import MAIL_TEMPLATE_CONTEXT_SUBJECT, MAIL_TEMPLATE_CONTEXT_VISIT, \
+    MAIL_TEMPLATE_CONTEXT_APPOINTMENT
+
+MIMETYPE_DOCX = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
+
+CONTEXT_TYPES_MAPPING = {
+    MAIL_TEMPLATE_CONTEXT_SUBJECT: Subject,
+    MAIL_TEMPLATE_CONTEXT_VISIT: Visit,
+    MAIL_TEMPLATE_CONTEXT_APPOINTMENT: Appointment
+}
 
 
 def mail_templates(request):
     return wrap_response(request, "mail_templates/index.html", {})
+
+
+class MailTemplatesListView(ListView, WrappedView):
+    model = MailTemplate
+    context_object_name = "mail_templates"
+    template_name = 'mail_templates/list.html'
+
+    def get_context_data(self, **kwargs):
+        context = super(MailTemplatesListView, self).get_context_data()
+        context['explanations'] = {"generic": MailTemplate.MAILS_TEMPLATE_GENERIC_TAGS,
+                                   "subject": MailTemplate.MAILS_TEMPLATE_SUBJECT_TAGS,
+                                   "visit": MailTemplate.MAILS_TEMPLATE_VISIT_TAGS,
+                                   "appointment": MailTemplate.MAILS_TEMPLATE_APPOINTMENT_TAGS,
+                                   }
+        return context
+
+
+class MailTemplatesCreateView(CreateView, WrappedView):
+    model = MailTemplate
+    template_name = "mail_templates/add.html"
+    fields = '__all__'
+    success_url = reverse_lazy('web.views.mail_templates')
+    success_message = "Template created"
+
+
+class MailTemplatesDeleteView(DeleteView, WrappedView):
+    model = MailTemplate
+    success_url = reverse_lazy('web.views.mail_templates')
+    template_name = 'mail_templates/confirm_delete.html'
+
+    def delete(self, request, *args, **kwargs):
+        messages.success(request, "Template deleted")
+        return super(MailTemplatesDeleteView, self).delete(request, *args, **kwargs)
+
+
+class MailTemplatesEditView(UpdateView, WrappedView):
+    model = MailTemplate
+    success_url = reverse_lazy('web.views.mail_templates')
+    fields = '__all__'
+    success_message = "Template edited"
+    template_name = "mail_templates/edit.html"
+    context_object_name = "mail_template"
+
+
+@login_required
+def generate(request, mail_template_id, instance_id):
+    mail_template = get_object_or_404(MailTemplate, id=mail_template_id)
+    instance = get_object_or_404(CONTEXT_TYPES_MAPPING[mail_template.context], id=instance_id)
+    stream = StringIO.StringIO()
+    stream = mail_template.apply(instance, request.user, stream)
+    file_size = stream.tell()
+    stream.seek(0)
+    response = HttpResponse(FileWrapper(stream), content_type=MIMETYPE_DOCX)
+    response['Content-Length'] = file_size
+    response['Content-Disposition'] = 'attachment; filename={}.docx'.format(mail_template.name)
+    return response
diff --git a/smash/web/views/subject.py b/smash/web/views/subject.py
index 06615727752569a3978646cd48cea3dab812625f..f0e96b4a167646acfbf5cb2aada2b973ad30a3d6 100644
--- a/smash/web/views/subject.py
+++ b/smash/web/views/subject.py
@@ -2,15 +2,15 @@
 from django.contrib import messages
 from django.shortcuts import redirect, get_object_or_404
 
-from notifications import get_subjects_with_no_visit, get_subjects_with_reminder
 from . import wrap_response
 from ..forms import SubjectAddForm, SubjectEditForm, VisitDetailForm, get_prefix_screening_number
-from ..models import Subject, Worker
+from ..models import Subject, Worker, MailTemplate
 
 SUBJECT_LIST_GENERIC = "GENERIC"
 SUBJECT_LIST_NO_VISIT = "NO_VISIT"
 SUBJECT_LIST_REQUIRE_CONTACT = "REQUIRE_CONTACT"
 
+
 def subjects(request):
     context = {
         'list_type': SUBJECT_LIST_GENERIC,
@@ -61,14 +61,23 @@ def subject_edit(request, id):
                 the_subject.mark_as_dead()
             if form.cleaned_data['resigned'] and not was_resigned:
                 the_subject.mark_as_resigned()
+            messages.success(request, "Modifications saved")
+            if '_continue' in request.POST:
+                return redirect('web.views.subject_edit', id=the_subject.id)
             return redirect('web.views.subjects')
     else:
         form = SubjectEditForm(instance=the_subject, was_dead=was_dead, was_resigned=was_resigned)
 
+    languages = []
+    if the_subject.default_written_communication_language:
+        languages.append(the_subject.default_written_communication_language)
+    languages.extend(the_subject.languages.all())
+
     return wrap_response(request, 'subjects/edit.html', {
         'form': form,
         'subject': the_subject,
-        'contact_attempts': contact_attempts
+        'contact_attempts': contact_attempts,
+        'mail_templates': MailTemplate.get_subject_mail_templates(languages)
     })
 
 
diff --git a/smash/web/views/visit.py b/smash/web/views/visit.py
index 4d2319cdd31642359eeb2a5fbc29189845fe9722..b4f11304a30f1d2417424c1779f98ff5682bac45 100644
--- a/smash/web/views/visit.py
+++ b/smash/web/views/visit.py
@@ -6,7 +6,7 @@ from notifications import get_active_visits_with_missing_appointments, get_unfin
     waiting_for_appointment
 from . import wrap_response
 from ..forms import VisitDetailForm, SubjectDetailForm, VisitAddForm
-from ..models import Visit, Appointment, Subject
+from ..models import Visit, Appointment, Subject, MailTemplate
 
 
 def visits(request):
@@ -61,6 +61,10 @@ def visit_details(request, id):
             can_finish = False
 
     subject_form = SubjectDetailForm(instance=displayed_subject)
+    languages = []
+    if displayed_subject.default_written_communication_language:
+        languages.append(displayed_subject.default_written_communication_language)
+    languages.extend(displayed_subject.languages.all())
 
     return wrap_response(request, 'visits/details.html', {
         'vform': visit_form,
@@ -69,7 +73,8 @@ def visit_details(request, id):
         'visFinished': visit_finished,
         'canFinish': can_finish,
         'vid': visit_id,
-        'visit': displayed_visit})
+        'visit': displayed_visit,
+        'mail_templates': MailTemplate.get_visit_mail_templates(languages)})
 
 
 def visit_mark(request, id, as_what):