diff --git a/README.md b/README.md
index ad9e62d9e83e1d4a4da2621abf5a97955844d16d..5ae8a3967704fa1d128b6375f5990d51a3a943d4 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ On supposera pour la suite que vous utiliser debian/ubuntu sur un serveur tout n
 1. Paquets nécessaires
 
         $ sudo apt install nginx python3 python3-pip python3-dev uwsgi
-        $ sudo apt install uwsgi-plugin-python3 python3-virtualenv git
+        $ sudo apt install uwsgi-plugin-python3 python3-venv git acl
 
 2. Clonage du dépot
 
@@ -29,8 +29,8 @@ On supposera pour la suite que vous utiliser debian/ubuntu sur un serveur tout n
 
    À la racine du projet:
 
-        $ virtualenv env
-        $ source /env/bin/activate
+        $ python3 -m venv env
+        $ source env/bin/activate
         (env)$ pip3 install -r requirements.txt
         (env)$ deactivate
 
diff --git a/apps/member/forms.py b/apps/member/forms.py
index 66844cf4f37b3c0ebedc9625ea9beb9158dd714c..abb35cd9cb2d4493e849ffcfd9315a5f14230c4a 100644
--- a/apps/member/forms.py
+++ b/apps/member/forms.py
@@ -14,6 +14,11 @@ from crispy_forms.layout import Layout
 
 
 class SignUpForm(UserCreationForm):
+    def __init__(self,*args,**kwargs):
+        super().__init__(*args,**kwargs)
+        self.fields['username'].widget.attrs.pop("autofocus", None)
+        self.fields['first_name'].widget.attrs.update({"autofocus":"autofocus"})
+
     class Meta:
         model = User
         fields = ['first_name', 'last_name', 'username', 'email']
diff --git a/apps/member/hashers.py b/apps/member/hashers.py
new file mode 100644
index 0000000000000000000000000000000000000000..0c5d010b62f22fc45c1140866aad46df05ebae32
--- /dev/null
+++ b/apps/member/hashers.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+import hashlib
+
+from django.contrib.auth.hashers import PBKDF2PasswordHasher
+from django.utils.crypto import constant_time_compare
+
+
+class CustomNK15Hasher(PBKDF2PasswordHasher):
+    """
+    Permet d'importer les mots de passe depuis la Note KFet 2015.
+    Si un hash de mot de passe est de la forme :
+    `custom_nk15$<NB>$<ENCODED>`
+    où <NB> est un entier quelconque (symbolisant normalement un nombre d'itérations)
+    et <ENCODED> le hash du mot de passe dans la Note Kfet 2015,
+    alors ce hasher va vérifier le mot de passe.
+    N'ayant pas la priorité (cf note_kfet/settings/base.py), le mot de passe sera
+    converti automatiquement avec l'algorithme PBKDF2.
+    """
+    algorithm = "custom_nk15"
+
+    def verify(self, password, encoded):
+        if '|' in encoded:
+            salt, db_hashed_pass = encoded.split('$')[2].split('|')
+            return constant_time_compare(hashlib.sha256((salt + password).encode("utf-8")).hexdigest(), db_hashed_pass)
+        return super().verify(password, encoded)
diff --git a/apps/member/views.py b/apps/member/views.py
index 6f982c64f6463a954de664c04640ee20dd7fd9db..6d82a6ccfc58c36b7f49a3bf8052c94edd486609 100644
--- a/apps/member/views.py
+++ b/apps/member/views.py
@@ -114,12 +114,13 @@ class UserDetailView(LoginRequiredMixin, DetailView):
     """
     Affiche les informations sur un utilisateur, sa note, ses clubs...
     """
-    model = Profile
-    context_object_name = "profile"
+    model = User
+    context_object_name = "user_object"
+    template_name = "member/profile_detail.html"
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
-        user = context['profile'].user
+        user = context['user_object']
         history_list = \
             Transaction.objects.all().filter(Q(source=user.note) | Q(destination=user.note))
         context['history_list'] = HistoryTable(history_list)
diff --git a/apps/note/admin.py b/apps/note/admin.py
index 3a9721aeee3eaa7c30750ee4a31109a97fb6f5cb..52c1cc1752066221c27782a303e975e497d278cf 100644
--- a/apps/note/admin.py
+++ b/apps/note/admin.py
@@ -7,7 +7,8 @@ from polymorphic.admin import PolymorphicChildModelAdmin, \
     PolymorphicChildModelFilter, PolymorphicParentModelAdmin
 
 from .models.notes import Alias, Note, NoteClub, NoteSpecial, NoteUser
-from .models.transactions import Transaction, TransactionCategory, TransactionTemplate
+from .models.transactions import Transaction, TemplateCategory, TransactionTemplate, \
+    TemplateTransaction, MembershipTransaction
 
 
 class AliasInlines(admin.TabularInline):
@@ -97,13 +98,14 @@ class NoteUserAdmin(PolymorphicChildModelAdmin):
 
 
 @admin.register(Transaction)
-class TransactionAdmin(admin.ModelAdmin):
+class TransactionAdmin(PolymorphicParentModelAdmin):
     """
     Admin customisation for Transaction
     """
+    child_models = (TemplateTransaction, MembershipTransaction)
     list_display = ('created_at', 'poly_source', 'poly_destination',
-                    'quantity', 'amount', 'transaction_type', 'valid')
-    list_filter = ('transaction_type', 'valid')
+                    'quantity', 'amount', 'valid')
+    list_filter = ('valid',)
     autocomplete_fields = (
         'source',
         'destination',
@@ -132,7 +134,7 @@ class TransactionAdmin(admin.ModelAdmin):
         """
         if obj:  # user is editing an existing object
             return 'created_at', 'source', 'destination', 'quantity',\
-                   'amount', 'transaction_type'
+                   'amount'
         return []
 
 
@@ -141,8 +143,8 @@ class TransactionTemplateAdmin(admin.ModelAdmin):
     """
     Admin customisation for TransactionTemplate
     """
-    list_display = ('name', 'poly_destination', 'amount', 'template_type')
-    list_filter = ('template_type', )
+    list_display = ('name', 'poly_destination', 'amount', 'category', 'display', )
+    list_filter = ('category', 'display')
     autocomplete_fields = ('destination', )
 
     def poly_destination(self, obj):
@@ -154,8 +156,8 @@ class TransactionTemplateAdmin(admin.ModelAdmin):
     poly_destination.short_description = _('destination')
 
 
-@admin.register(TransactionCategory)
-class TransactionCategoryAdmin(admin.ModelAdmin):
+@admin.register(TemplateCategory)
+class TemplateCategoryAdmin(admin.ModelAdmin):
     """
     Admin customisation for TransactionTemplate
     """
diff --git a/apps/note/fixtures/initial.json b/apps/note/fixtures/initial.json
index f853d3cbb0ec8c248162c65bacc033cabdde9fb9..c0e92bda3aa9c6d2d7be0193b3b70b0df3300c0b 100644
--- a/apps/note/fixtures/initial.json
+++ b/apps/note/fixtures/initial.json
@@ -162,59 +162,59 @@
         }
     },
     {
-        "model": "note.transactioncategory",
+        "model": "note.templatecategory",
         "pk": 1,
         "fields": {
             "name": "Soft"
         }
     },
     {
-        "model": "note.transactioncategory",
+        "model": "note.templatecategory",
         "pk": 2,
         "fields": {
             "name": "Pulls"
         }
     },
     {
-        "model": "note.transactioncategory",
+        "model": "note.templatecategory",
         "pk": 3,
         "fields": {
             "name": "Gala"
         }
     },
     {
-        "model": "note.transactioncategory",
+        "model": "note.templatecategory",
         "pk": 4,
         "fields": {
             "name": "Clubs"
         }
     },
     {
-        "model": "note.transactioncategory",
+        "model": "note.templatecategory",
         "pk": 5,
         "fields": {
             "name": "Bouffe"
         }
     },
     {
-        "model": "note.transactioncategory",
+        "model": "note.templatecategory",
         "pk": 6,
         "fields": {
             "name": "BDA"
         }
     },
     {
-        "model": "note.transactioncategory",
+        "model": "note.templatecategory",
         "pk": 7,
         "fields": {
             "name": "Autre"
         }
     },
     {
-        "model": "note.transactioncategory",
+        "model": "note.templatecategory",
         "pk": 8,
         "fields": {
             "name": "Alcool"
         }
     }
-]
\ No newline at end of file
+]
diff --git a/apps/note/forms.py b/apps/note/forms.py
index e4fd344c1672031f4bf57279de23c6d965c32ffc..15cccf2e6d4c6de632d6f8228de6926edf754d96 100644
--- a/apps/note/forms.py
+++ b/apps/note/forms.py
@@ -4,7 +4,7 @@
 from dal import autocomplete
 from django import forms
 
-from .models import Transaction, TransactionTemplate
+from .models import Transaction, TransactionTemplate, TemplateTransaction
 
 
 class TransactionTemplateForm(forms.ModelForm):
@@ -31,8 +31,6 @@ class TransactionTemplateForm(forms.ModelForm):
 
 class TransactionForm(forms.ModelForm):
     def save(self, commit=True):
-        self.instance.transaction_type = 'transfert'
-
         super().save(commit)
 
     class Meta:
@@ -71,12 +69,13 @@ class ConsoForm(forms.ModelForm):
             name=self.data['button']).get()
         self.instance.destination = button.destination
         self.instance.amount = button.amount
-        self.instance.transaction_type = 'bouton'
-        self.instance.reason = button.name
+        self.instance.reason = '{} ({})'.format(button.name, button.category)
+        self.instance.name = button.name
+        self.instance.category = button.category
         super().save(commit)
 
     class Meta:
-        model = Transaction
+        model = TemplateTransaction
         fields = ('source', )
 
         # Le champ d'utilisateur est remplacé par un champ d'auto-complétion.
diff --git a/apps/note/models/__init__.py b/apps/note/models/__init__.py
index 7e6cc310e823e28eea3f8d8e40b8e1d98b87ac7c..081b31a737f6048c562773cbb67c51aca442b8bd 100644
--- a/apps/note/models/__init__.py
+++ b/apps/note/models/__init__.py
@@ -3,11 +3,12 @@
 
 from .notes import Alias, Note, NoteClub, NoteSpecial, NoteUser
 from .transactions import MembershipTransaction, Transaction, \
-    TransactionCategory, TransactionTemplate
+    TemplateCategory, TransactionTemplate, TemplateTransaction
 
 __all__ = [
     # Notes
     'Alias', 'Note', 'NoteClub', 'NoteSpecial', 'NoteUser',
     # Transactions
-    'MembershipTransaction', 'Transaction', 'TransactionCategory', 'TransactionTemplate',
+    'MembershipTransaction', 'Transaction', 'TemplateCategory', 'TransactionTemplate',
+    'TemplateTransaction',
 ]
diff --git a/apps/note/models/notes.py b/apps/note/models/notes.py
index 3b616f0e754abaee90a917ae0288d0410ce1de77..62811735a0bd7c46df48df4fa90758895ec84cf8 100644
--- a/apps/note/models/notes.py
+++ b/apps/note/models/notes.py
@@ -27,6 +27,12 @@ class Note(PolymorphicModel):
         help_text=_('in centimes, money credited for this instance'),
         default=0,
     )
+    last_negative= models.DateTimeField(
+        verbose_name=_('last negative date'),
+        help_text=_('last time the balance was negative'),
+        null=True,
+        blank=True,
+    )
     is_active = models.BooleanField(
         _('active'),
         default=True,
@@ -64,7 +70,8 @@ class Note(PolymorphicModel):
         if aliases.exists():
             # Alias exists, so check if it is linked to this note
             if aliases.first().note != self:
-                raise ValidationError(_('This alias is already taken.'))
+                raise ValidationError(_('This alias is already taken.'),
+                                      code="same_alias")
 
             # Save note
             super().save(*args, **kwargs)
@@ -87,7 +94,8 @@ class Note(PolymorphicModel):
         if aliases.exists():
             # Alias exists, so check if it is linked to this note
             if aliases.first().note != self:
-                raise ValidationError(_('This alias is already taken.'))
+                raise ValidationError(_('This alias is already taken.'),
+                                      code="same_alias",)
         else:
             # Alias does not exist yet, so check if it can exist
             a = Alias(name=str(self))
@@ -222,16 +230,19 @@ class Alias(models.Model):
     def clean(self):
         normalized_name = Alias.normalize(self.name)
         if len(normalized_name) >= 255:
-            raise ValidationError(_('Alias too long.'))
+            raise ValidationError(_('Alias is too long.'),
+                                  code='alias_too_long')
         try:
-            if self != Alias.objects.get(normalized_name=normalized_name):
-                raise ValidationError(
-                    _('An alias with a similar name '
-                      'already exists.'))
+            sim_alias = Alias.objects.get(normalized_name=normalized_name)
+            if self != sim_alias:
+                raise ValidationError(_('An alias with a similar name already exists:'),
+                                       code="same_alias"
+                )
         except Alias.DoesNotExist:
             pass
 
     def delete(self, using=None, keep_parents=False):
         if self.name == str(self.note):
-            raise ValidationError(_("You can't delete your main alias."))
+            raise ValidationError(_("You can't delete your main alias."),
+                                  code="cant_delete_main_alias")
         return super().delete(using, keep_parents)
diff --git a/apps/note/models/transactions.py b/apps/note/models/transactions.py
index 042faa161184e058b706d3e478eda816a255e9aa..49fc44b4bc44070cce44c72f55edb4dc90b1b9f4 100644
--- a/apps/note/models/transactions.py
+++ b/apps/note/models/transactions.py
@@ -5,6 +5,7 @@ from django.db import models
 from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 from django.urls import reverse
+from polymorphic.models import PolymorphicModel
 
 from .notes import Note, NoteClub
 
@@ -13,7 +14,7 @@ Defines transactions
 """
 
 
-class TransactionCategory(models.Model):
+class TemplateCategory(models.Model):
     """
     Defined a recurrent transaction category
 
@@ -43,6 +44,7 @@ class TransactionTemplate(models.Model):
         verbose_name=_('name'),
         max_length=255,
         unique=True,
+        error_messages={'unique':_("A template with this name already exist")},
     )
     destination = models.ForeignKey(
         NoteClub,
@@ -54,12 +56,19 @@ class TransactionTemplate(models.Model):
         verbose_name=_('amount'),
         help_text=_('in centimes'),
     )
-    template_type = models.ForeignKey(
-        TransactionCategory,
+    category = models.ForeignKey(
+        TemplateCategory,
         on_delete=models.PROTECT,
         verbose_name=_('type'),
         max_length=31,
     )
+    display = models.BooleanField(
+        default = True,
+    )
+    description = models.CharField(
+        verbose_name=_('description'),
+        max_length=255,
+    )
 
     class Meta:
         verbose_name = _("transaction template")
@@ -69,7 +78,7 @@ class TransactionTemplate(models.Model):
         return reverse('note:template_update', args=(self.pk, ))
 
 
-class Transaction(models.Model):
+class Transaction(PolymorphicModel):
     """
     General transaction between two :model:`note.Note`
 
@@ -100,10 +109,6 @@ class Transaction(models.Model):
         default=1,
     )
     amount = models.PositiveIntegerField(verbose_name=_('amount'), )
-    transaction_type = models.CharField(
-        verbose_name=_('type'),
-        max_length=31,
-    )
     reason = models.CharField(
         verbose_name=_('reason'),
         max_length=255,
@@ -144,6 +149,22 @@ class Transaction(models.Model):
         return self.amount * self.quantity
 
 
+class TemplateTransaction(Transaction):
+    """
+    Special type of :model:`note.Transaction` associated to a :model:`note.TransactionTemplate`.
+
+    """
+
+    template = models.ForeignKey(
+        TransactionTemplate,
+        null=True,
+        on_delete=models.SET_NULL,
+    )
+    category = models.ForeignKey(
+        TemplateCategory,
+        on_delete=models.PROTECT,
+    )
+
 class MembershipTransaction(Transaction):
     """
     Special type of :model:`note.Transaction` associated to a :model:`member.Membership`.
diff --git a/apps/note/views.py b/apps/note/views.py
index 167ef4f0d4c4c8a45c251e7e60af2ebb622b98b1..75577a2e3ced39bbd28b165b5b5d3f6438d4552c 100644
--- a/apps/note/views.py
+++ b/apps/note/views.py
@@ -8,7 +8,7 @@ from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from django.views.generic import CreateView, ListView, UpdateView
 
-from .models import Transaction, TransactionTemplate, Alias
+from .models import Transaction, TransactionTemplate, Alias, TemplateTransaction
 from .forms import TransactionForm, TransactionTemplateForm, ConsoForm
 
 
@@ -129,7 +129,7 @@ class ConsoView(LoginRequiredMixin, CreateView):
     """
     Consume
     """
-    model = Transaction
+    model = TemplateTransaction
     template_name = "note/conso_form.html"
     form_class = ConsoForm
 
@@ -138,8 +138,8 @@ class ConsoView(LoginRequiredMixin, CreateView):
         Add some context variables in template such as page title
         """
         context = super().get_context_data(**kwargs)
-        context['transaction_templates'] = TransactionTemplate.objects.all() \
-            .order_by('template_type')
+        context['transaction_templates'] = TransactionTemplate.objects.filter(display=True) \
+            .order_by('category')
         context['title'] = _("Consommations")
 
         # select2 compatibility
@@ -152,3 +152,4 @@ class ConsoView(LoginRequiredMixin, CreateView):
         When clicking a button, reload the same page
         """
         return reverse('note:consos')
+
diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py
index 1a915d26171e44b59954e4093ebd9ac56d7de557..07a1c86cd89ed7b04ca987d1a5a20cb8da5653ff 100644
--- a/note_kfet/settings/base.py
+++ b/note_kfet/settings/base.py
@@ -121,6 +121,12 @@ AUTH_PASSWORD_VALIDATORS = [
     },
 ]
 
+# Use our custom hasher in order to import NK15 passwords
+PASSWORD_HASHERS = [
+    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
+    'member.hashers.CustomNK15Hasher',
+]
+
 # Django Guardian object permissions
 
 AUTHENTICATION_BACKENDS = (
diff --git a/templates/base.html b/templates/base.html
index 4b5f9872d7b52a12eeeabf8ea7500833a522d8f3..6814bedfba9b3783255ffe7df3fd3b1a826889db 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -59,8 +59,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
     <nav class="navbar navbar-expand-md navbar-light bg-light fixed-navbar shadow-sm">
         <a class="navbar-brand" href="/">{{ request.site.name }}</a>
         <button class="navbar-toggler" type="button" data-toggle="collapse"
-                data-target="#navbarNavAltMarkup"
-                aria-controls="navbarNavAltMarkup" aria-expanded="false"
+                data-target="#navbarNavDropdown"
+                aria-controls="navbarNavDropdown" aria-expanded="false"
                 aria-label="Toggle navigation">
             <span class="navbar-toggler-icon"></span>
         </button>
@@ -87,7 +87,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
                         </a>
                         <div class="dropdown-menu dropdown-menu-right"
                              aria-labelledby="navbarDropdownMenuLink">
-                            <a class="dropdown-item" href="{% url 'member:user_detail' pk=user.profile.pk %}">
+                            <a class="dropdown-item" href="{% url 'member:user_detail' pk=user.pk %}">
                                 <i class="fa fa-user"></i> Mon compte
                             </a>
                             <a class="dropdown-item" href="{% url 'logout' %}">
diff --git a/templates/member/profile_detail.html b/templates/member/profile_detail.html
index 655f9893271d4c582a087d701b0ad53ae0c1ff62..1f60414b691a25f6a0a852469e1cfa9f72dc57ff 100644
--- a/templates/member/profile_detail.html
+++ b/templates/member/profile_detail.html
@@ -5,14 +5,14 @@
 <div class="row mt-4">
     <div class="col-md-3 mb-4">
         <div class="card bg-light shadow">
-            <img src="{{ object.note.display_image.url }}" class="card-img-top" alt="">
+            <img src="{{ object.note.display_image }}" class="card-img-top" alt="">
             <div class="card-body">
                 <dl class="row">
                     <dt class="col-xl-6">{% trans 'name'|capfirst %}, {% trans 'first name' %}</dt>
-                    <dd class="col-xl-6">{{ object.user.last_name }} {{ object.user.first_name }}</dd>
+                    <dd class="col-xl-6">{{ object.last_name }} {{ object.first_name }}</dd>
 
                     <dt class="col-xl-6">{% trans 'username'|capfirst %}</dt>
-                    <dd class="col-xl-6">{{ object.user.username }}</dd>
+                    <dd class="col-xl-6">{{ user.username }}</dd>
 
                     <dt class="col-xl-6">{% trans 'password'|capfirst %}</dt>
                     <dd class="col-xl-6">
@@ -22,19 +22,19 @@
                     </dd>
 
                     <dt class="col-xl-6">{% trans 'section'|capfirst %}</dt>
-                    <dd class="col-xl-6">{{ object.section }}</dd>
+                    <dd class="col-xl-6">{{ object.profile.section }}</dd>
 
                     <dt class="col-xl-6">{% trans 'address'|capfirst %}</dt>
-                    <dd class="col-xl-6">{{ object.address }}</dd>
+                    <dd class="col-xl-6">{{ object.profile.address }}</dd>
 
                     <dt class="col-xl-6">{% trans 'balance'|capfirst %}</dt>
-                    <dd class="col-xl-6">{{ object.user.note.balance | pretty_money }}</dd>
+                    <dd class="col-xl-6">{{ object.note.balance | pretty_money }}</dd>
 
                     <dt class="col-xl-6">{% trans 'aliases'|capfirst %}</dt>
-                    <dd class="col-xl-6">{{ object.user.note.alias_set.all|join:", " }}</dd>
+                    <dd class="col-xl-6">{{ object.note.alias_set.all|join:", " }}</dd>
                 </dl>
 
-                {% if object.user.pk == user.pk %}
+                {% if object.pk == user.pk %}
                     <a class="small" href="{% url 'member:auth_token' %}">{% trans 'Manage auth token' %}</a>
                 {% endif %}
             </div>
diff --git a/templates/member/signup.html b/templates/member/signup.html
index 4e6f79bcc219239830edcfab4426930e7d064513..e682bd9b8be5c6c327f8b17cdf4d7a7f07a3da96 100644
--- a/templates/member/signup.html
+++ b/templates/member/signup.html
@@ -10,7 +10,7 @@
       {% csrf_token %}
       {{ form|crispy }}
       {{ profile_form|crispy }}
-      <button class="btn btn-link" type="submit">
+      <button class="btn btn-success" type="submit">
           {% trans "Sign Up" %}
       </button>
   </form>
diff --git a/templates/note/conso_form.html b/templates/note/conso_form.html
index b121ad54d12f970a66f9572194d3b45d8a3376c8..10b06589cfd4434aa6bc79100307901d017b1547 100644
--- a/templates/note/conso_form.html
+++ b/templates/note/conso_form.html
@@ -7,7 +7,7 @@
 
 {% block content %}
     {# Regroup buttons under categories #}
-    {% regroup transaction_templates by template_type as template_types %}
+    {% regroup transaction_templates by category as categories %}
 
     <form method="post" onsubmit="window.onbeforeunload=null">
         {% csrf_token %}
@@ -44,10 +44,10 @@
                     {# Tabs for button categories #}
                     <div class="card-header">
                         <ul class="nav nav-tabs nav-fill card-header-tabs">
-                            {% for template_type in template_types %}
+                            {% for category in categories %}
                                 <li class="nav-item">
-                                    <a class="nav-link" data-toggle="tab" href="#{{ template_type.grouper|slugify }}">
-                                        {{ template_type.grouper }}
+                                    <a class="nav-link" data-toggle="tab" href="#{{ category.grouper|slugify }}">
+                                        {{ category.grouper }}
                                     </a>
                                 </li>
                             {% endfor %}
@@ -57,10 +57,10 @@
                     {# Tabs content #}
                     <div class="card-body">
                         <div class="tab-content">
-                            {% for template_type in template_types %}
-                                <div class="tab-pane" id="{{ template_type.grouper|slugify }}">
+                            {% for category in categories %}
+                                <div class="tab-pane" id="{{ category.grouper|slugify }}">
                                     <div class="d-inline-flex flex-wrap justify-content-center">
-                                        {% for button in template_type.list %}
+                                        {% for button in category.list %}
                                             <button class="btn btn-outline-dark rounded-0 flex-fill"
                                                     name="button" value="{{ button.name }}">
                                                 {{ button.name }} ({{ button.amount | pretty_money }})