diff --git a/apps/activity/forms.py b/apps/activity/forms.py
index a36f85cdad87ec5e845a2e940f627e0aacfe3f8b..b7dc6de9e50b0d985bd2d9280ba659cddb8e2423 100644
--- a/apps/activity/forms.py
+++ b/apps/activity/forms.py
@@ -2,11 +2,15 @@
 # SPDX-License-Identifier: GPL-3.0-or-later
 
 from django import forms
-
 from activity.models import Activity
+from note_kfet.inputs import DateTimePickerInput
 
 
 class ActivityForm(forms.ModelForm):
     class Meta:
         model = Activity
         fields = '__all__'
+        widgets = {
+            "date_start": DateTimePickerInput(),
+            "date_end": DateTimePickerInput(),
+        }
diff --git a/apps/activity/views.py b/apps/activity/views.py
index 224181ef9192c7818401fcafd3856579ecb1fbe3..f1ecc1b3da039298de1af554e06270792af78a17 100644
--- a/apps/activity/views.py
+++ b/apps/activity/views.py
@@ -1,6 +1,7 @@
 # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 # SPDX-License-Identifier: GPL-3.0-or-later
 
+from django.contrib.auth.mixins import LoginRequiredMixin
 from django.views.generic import CreateView, DetailView, UpdateView, TemplateView
 from django.utils.translation import gettext_lazy as _
 from django_tables2.views import SingleTableView
@@ -9,12 +10,12 @@ from .forms import ActivityForm
 from .models import Activity
 
 
-class ActivityCreateView(CreateView):
+class ActivityCreateView(LoginRequiredMixin, CreateView):
     model = Activity
     form_class = ActivityForm
 
 
-class ActivityListView(SingleTableView):
+class ActivityListView(LoginRequiredMixin, SingleTableView):
     model = Activity
 
     def get_context_data(self, **kwargs):
@@ -25,14 +26,14 @@ class ActivityListView(SingleTableView):
         return ctx
 
 
-class ActivityDetailView(DetailView):
+class ActivityDetailView(LoginRequiredMixin, DetailView):
     model = Activity
 
 
-class ActivityUpdateView(UpdateView):
+class ActivityUpdateView(LoginRequiredMixin, UpdateView):
     model = Activity
     form_class = ActivityForm
 
 
-class ActivityEntryView(TemplateView):
+class ActivityEntryView(LoginRequiredMixin, TemplateView):
     pass
diff --git a/apps/note/templatetags/pretty_money.py b/apps/note/templatetags/pretty_money.py
index ba527f9be24c170cd0260f604e588d4f57fb8382..265870a85aadd70d949f13cdeb990db5c0955a18 100644
--- a/apps/note/templatetags/pretty_money.py
+++ b/apps/note/templatetags/pretty_money.py
@@ -18,10 +18,5 @@ def pretty_money(value):
         )
 
 
-def cents_to_euros(value):
-    return "{:.02f}".format(value / 100) if value else ""
-
-
 register = template.Library()
 register.filter('pretty_money', pretty_money)
-register.filter('cents_to_euros', cents_to_euros)
diff --git a/apps/note/views.py b/apps/note/views.py
index ddf5ee6f10e0806b900ae6a415f10a26e501d9f1..c8f57924a0c9f76b3e12acf3dc36fd5158117683 100644
--- a/apps/note/views.py
+++ b/apps/note/views.py
@@ -9,6 +9,7 @@ from django.utils.translation import gettext_lazy as _
 from django.views.generic import CreateView, UpdateView
 from django_tables2 import SingleTableView
 from django.urls import reverse_lazy
+from note_kfet.inputs import AmountInput
 from permission.backends import PermissionBackend
 
 from .forms import TransactionTemplateForm
@@ -40,6 +41,7 @@ class TransactionCreateView(LoginRequiredMixin, SingleTableView):
         """
         context = super().get_context_data(**kwargs)
         context['title'] = _('Transfer money')
+        context['amount_widget'] = AmountInput(attrs={"id": "amount"})
         context['polymorphic_ctype'] = ContentType.objects.get_for_model(Transaction).pk
         context['special_polymorphic_ctype'] = ContentType.objects.get_for_model(SpecialTransaction).pk
         context['special_types'] = NoteSpecial.objects.order_by("special_type").all()
diff --git a/apps/treasury/forms.py b/apps/treasury/forms.py
index caaa365fea3dfde0f7dda776f5872c34428333f7..7fe7de4c3da65bc82e4b854353f4b756f7e33faa 100644
--- a/apps/treasury/forms.py
+++ b/apps/treasury/forms.py
@@ -7,6 +7,7 @@ from crispy_forms.helper import FormHelper
 from crispy_forms.layout import Submit
 from django import forms
 from django.utils.translation import gettext_lazy as _
+from note_kfet.inputs import DatePickerInput, AmountInput
 
 from .models import Invoice, Product, Remittance, SpecialTransactionProxy
 
@@ -19,7 +20,7 @@ class InvoiceForm(forms.ModelForm):
     # Django forms don't support date fields. We have to add it manually
     date = forms.DateField(
         initial=datetime.date.today,
-        widget=forms.TextInput(attrs={'type': 'date'})
+        widget=DatePickerInput()
     )
 
     def clean_date(self):
@@ -30,12 +31,21 @@ class InvoiceForm(forms.ModelForm):
         exclude = ('bde', )
 
 
+class ProductForm(forms.ModelForm):
+    class Meta:
+        model = Product
+        fields = '__all__'
+        widgets = {
+            "amount": AmountInput()
+        }
+
+
 # Add a subform per product in the invoice form, and manage correctly the link between the invoice and
 # its products. The FormSet will search automatically the ForeignKey in the Product model.
 ProductFormSet = forms.inlineformset_factory(
     Invoice,
     Product,
-    fields='__all__',
+    form=ProductForm,
     extra=1,
 )
 
diff --git a/apps/treasury/views.py b/apps/treasury/views.py
index 904405661ed5ceb87c25737d40624a87401817a4..c374ced102a3e342d405e16f7585e568f30bba5c 100644
--- a/apps/treasury/views.py
+++ b/apps/treasury/views.py
@@ -50,18 +50,8 @@ class InvoiceCreateView(LoginRequiredMixin, CreateView):
     def form_valid(self, form):
         ret = super().form_valid(form)
 
-        kwargs = {}
-
-        # The user type amounts in cents. We convert it in euros.
-        for key in self.request.POST:
-            value = self.request.POST[key]
-            if key.endswith("amount") and value:
-                kwargs[key] = str(int(100 * float(value)))
-            elif value:
-                kwargs[key] = value
-
         # For each product, we save it
-        formset = ProductFormSet(kwargs, instance=form.instance)
+        formset = ProductFormSet(self.request.POST, instance=form.instance)
         if formset.is_valid():
             for f in formset:
                 # We don't save the product if the designation is not entered, ie. if the line is empty
@@ -112,16 +102,7 @@ class InvoiceUpdateView(LoginRequiredMixin, UpdateView):
     def form_valid(self, form):
         ret = super().form_valid(form)
 
-        kwargs = {}
-        # The user type amounts in cents. We convert it in euros.
-        for key in self.request.POST:
-            value = self.request.POST[key]
-            if key.endswith("amount") and value:
-                kwargs[key] = str(int(100 * float(value)))
-            elif value:
-                kwargs[key] = value
-
-        formset = ProductFormSet(kwargs, instance=form.instance)
+        formset = ProductFormSet(self.request.POST, instance=form.instance)
         saved = []
         # For each product, we save it
         if formset.is_valid():
diff --git a/note_kfet/inputs.py b/note_kfet/inputs.py
new file mode 100644
index 0000000000000000000000000000000000000000..ca3a13c7f1aacfb8bd4fea4efddc02d37be92c32
--- /dev/null
+++ b/note_kfet/inputs.py
@@ -0,0 +1,280 @@
+# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"""
+This file comes from the project `django-bootstrap-datepicker-plus` available on Github:
+https://github.com/monim67/django-bootstrap-datepicker-plus
+This is distributed under Apache License 2.0.
+
+This adds datetime pickers with bootstrap.
+"""
+
+"""Contains Base Date-Picker input class for widgets of this package."""
+
+from json import dumps as json_dumps
+
+from django.forms.widgets import DateTimeBaseInput, NumberInput
+
+
+class AmountInput(NumberInput):
+    """
+    This input type lets the user type amounts in euros, but forms receive data in cents
+    """
+    template_name = "note/amount_input.html"
+
+    def format_value(self, value):
+        return None if value is None or value == "" else "{:.02f}".format(value / 100, )
+
+    def value_from_datadict(self, data, files, name):
+        val = super().value_from_datadict(data, files, name)
+        return str(int(100 * float(val))) if val else val
+
+
+class DatePickerDictionary:
+    """Keeps track of all date-picker input classes."""
+
+    _i = 0
+    items = dict()
+
+    @classmethod
+    def generate_id(cls):
+        """Return a unique ID for each date-picker input class."""
+        cls._i += 1
+        return 'dp_%s' % cls._i
+
+
+class BasePickerInput(DateTimeBaseInput):
+    """Base Date-Picker input class for widgets of this package."""
+
+    template_name = 'bootstrap_datepicker_plus/date_picker.html'
+    picker_type = 'DATE'
+    format = '%Y-%m-%d'
+    config = {}
+    _default_config = {
+        'id': None,
+        'picker_type': None,
+        'linked_to': None,
+        'options': {}  # final merged options
+    }
+    options = {}  # options extended by user
+    options_param = {}  # options passed as parameter
+    _default_options = {
+        'showClose': True,
+        'showClear': True,
+        'showTodayButton': True,
+        "locale": "fr",
+    }
+
+    # source: https://github.com/tutorcruncher/django-bootstrap3-datetimepicker
+    # file: /blob/31fbb09/bootstrap3_datetime/widgets.py#L33
+    format_map = (
+        ('DDD', r'%j'),
+        ('DD', r'%d'),
+        ('MMMM', r'%B'),
+        ('MMM', r'%b'),
+        ('MM', r'%m'),
+        ('YYYY', r'%Y'),
+        ('YY', r'%y'),
+        ('HH', r'%H'),
+        ('hh', r'%I'),
+        ('mm', r'%M'),
+        ('ss', r'%S'),
+        ('a', r'%p'),
+        ('ZZ', r'%z'),
+    )
+
+    class Media:
+        """JS/CSS resources needed to render the date-picker calendar."""
+
+        js = (
+            'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/'
+            'moment-with-locales.min.js',
+            'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/'
+            '4.17.47/js/bootstrap-datetimepicker.min.js',
+            'bootstrap_datepicker_plus/js/datepicker-widget.js'
+        )
+        css = {'all': (
+            'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/'
+            '4.17.47/css/bootstrap-datetimepicker.css',
+            'bootstrap_datepicker_plus/css/datepicker-widget.css'
+        ), }
+
+    @classmethod
+    def format_py2js(cls, datetime_format):
+        """Convert python datetime format to moment datetime format."""
+        for js_format, py_format in cls.format_map:
+            datetime_format = datetime_format.replace(py_format, js_format)
+        return datetime_format
+
+    @classmethod
+    def format_js2py(cls, datetime_format):
+        """Convert moment datetime format to python datetime format."""
+        for js_format, py_format in cls.format_map:
+            datetime_format = datetime_format.replace(js_format, py_format)
+        return datetime_format
+
+    def __init__(self, attrs=None, format=None, options=None):
+        """Initialize the Date-picker widget."""
+        self.format_param = format
+        self.options_param = options if options else {}
+        self.config = self._default_config.copy()
+        self.config['id'] = DatePickerDictionary.generate_id()
+        self.config['picker_type'] = self.picker_type
+        self.config['options'] = self._calculate_options()
+        attrs = attrs if attrs else {}
+        if 'class' not in attrs:
+            attrs['class'] = 'form-control'
+        super().__init__(attrs, self._calculate_format())
+
+    def _calculate_options(self):
+        """Calculate and Return the options."""
+        _options = self._default_options.copy()
+        _options.update(self.options)
+        if self.options_param:
+            _options.update(self.options_param)
+        return _options
+
+    def _calculate_format(self):
+        """Calculate and Return the datetime format."""
+        _format = self.format_param if self.format_param else self.format
+        if self.config['options'].get('format'):
+            _format = self.format_js2py(self.config['options'].get('format'))
+        else:
+            self.config['options']['format'] = self.format_py2js(_format)
+        return _format
+
+    def get_context(self, name, value, attrs):
+        """Return widget context dictionary."""
+        context = super().get_context(
+            name, value, attrs)
+        context['widget']['attrs']['dp_config'] = json_dumps(self.config)
+        return context
+
+    def start_of(self, event_id):
+        """
+        Set Date-Picker as the start-date of a date-range.
+
+        Args:
+            - event_id (string): User-defined unique id for linking two fields
+        """
+        DatePickerDictionary.items[str(event_id)] = self
+        return self
+
+    def end_of(self, event_id, import_options=True):
+        """
+        Set Date-Picker as the end-date of a date-range.
+
+        Args:
+            - event_id (string): User-defined unique id for linking two fields
+            - import_options (bool): inherit options from start-date input,
+              default: TRUE
+        """
+        event_id = str(event_id)
+        if event_id in DatePickerDictionary.items:
+            linked_picker = DatePickerDictionary.items[event_id]
+            self.config['linked_to'] = linked_picker.config['id']
+            if import_options:
+                backup_moment_format = self.config['options']['format']
+                self.config['options'].update(linked_picker.config['options'])
+                self.config['options'].update(self.options_param)
+                if self.format_param or 'format' in self.options_param:
+                    self.config['options']['format'] = backup_moment_format
+                else:
+                    self.format = linked_picker.format
+            # Setting useCurrent is necessary, see following issue
+            # https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1075
+            self.config['options']['useCurrent'] = False
+            self._link_to(linked_picker)
+        else:
+            raise KeyError(
+                'start-date not specified for event_id "%s"' % event_id)
+        return self
+
+    def _link_to(self, linked_picker):
+        """
+        Executed when two date-inputs are linked together.
+
+        This method for sub-classes to override to customize the linking.
+        """
+        pass
+
+
+class DatePickerInput(BasePickerInput):
+    """
+    Widget to display a Date-Picker Calendar on a DateField property.
+
+    Args:
+        - attrs (dict): HTML attributes of rendered HTML input
+        - format (string): Python DateTime format eg. "%Y-%m-%d"
+        - options (dict): Options to customize the widget, see README
+    """
+
+    picker_type = 'DATE'
+    format = '%Y-%m-%d'
+    format_key = 'DATE_INPUT_FORMATS'
+
+
+class TimePickerInput(BasePickerInput):
+    """
+    Widget to display a Time-Picker Calendar on a TimeField property.
+
+    Args:
+        - attrs (dict): HTML attributes of rendered HTML input
+        - format (string): Python DateTime format eg. "%Y-%m-%d"
+        - options (dict): Options to customize the widget, see README
+    """
+
+    picker_type = 'TIME'
+    format = '%H:%M'
+    format_key = 'TIME_INPUT_FORMATS'
+    template_name = 'bootstrap_datepicker_plus/time_picker.html'
+
+
+class DateTimePickerInput(BasePickerInput):
+    """
+    Widget to display a DateTime-Picker Calendar on a DateTimeField property.
+
+    Args:
+        - attrs (dict): HTML attributes of rendered HTML input
+        - format (string): Python DateTime format eg. "%Y-%m-%d"
+        - options (dict): Options to customize the widget, see README
+    """
+
+    picker_type = 'DATETIME'
+    format = '%Y-%m-%d %H:%M'
+    format_key = 'DATETIME_INPUT_FORMATS'
+
+
+class MonthPickerInput(BasePickerInput):
+    """
+    Widget to display a Month-Picker Calendar on a DateField property.
+
+    Args:
+        - attrs (dict): HTML attributes of rendered HTML input
+        - format (string): Python DateTime format eg. "%Y-%m-%d"
+        - options (dict): Options to customize the widget, see README
+    """
+
+    picker_type = 'MONTH'
+    format = '01/%m/%Y'
+    format_key = 'DATE_INPUT_FORMATS'
+
+
+class YearPickerInput(BasePickerInput):
+    """
+    Widget to display a Year-Picker Calendar on a DateField property.
+
+    Args:
+        - attrs (dict): HTML attributes of rendered HTML input
+        - format (string): Python DateTime format eg. "%Y-%m-%d"
+        - options (dict): Options to customize the widget, see README
+    """
+
+    picker_type = 'YEAR'
+    format = '01/01/%Y'
+    format_key = 'DATE_INPUT_FORMATS'
+
+    def _link_to(self, linked_picker):
+        """Customize the options when linked with other date-time input"""
+        yformat = self.config['options']['format'].replace('-01-01', '-12-31')
+        self.config['options']['format'] = yformat
\ No newline at end of file
diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py
index d49b25424258dc73b5e2ae336b88727c0f50f3b9..bdd4d9a38bc19824b6c1df73b1fbcb3895b8289a 100644
--- a/note_kfet/settings/base.py
+++ b/note_kfet/settings/base.py
@@ -48,6 +48,7 @@ INSTALLED_APPS = [
     'django.contrib.sites',
     'django.contrib.messages',
     'django.contrib.staticfiles',
+    'django.forms',
     # API
     'rest_framework',
     'rest_framework.authtoken',
@@ -100,6 +101,8 @@ TEMPLATES = [
     },
 ]
 
+FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
+
 WSGI_APPLICATION = 'note_kfet.wsgi.application'
 
 # Password validation
diff --git a/static/bootstrap_datepicker_plus/css/datepicker-widget.css b/static/bootstrap_datepicker_plus/css/datepicker-widget.css
new file mode 100644
index 0000000000000000000000000000000000000000..baeec507b1d95a47401fcf122bcb0402f73cdeb7
--- /dev/null
+++ b/static/bootstrap_datepicker_plus/css/datepicker-widget.css
@@ -0,0 +1,121 @@
+@font-face {
+    font-family: 'Glyphicons Halflings';
+    src: url('//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.eot');
+    src: url('//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),
+     url('//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.woff2') format('woff2'),
+     url('//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.woff') format('woff'),
+     url('//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.ttf') format('truetype'),
+     url('//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+
+.glyphicon {
+    position: relative;
+    top: 1px;
+    display: inline-block;
+    font-family: 'Glyphicons Halflings';
+    font-style: normal;
+    font-weight: normal;
+    line-height: 1;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+}
+
+.glyphicon-time:before {
+    content: "\e023";
+}
+
+.glyphicon-chevron-left:before {
+    content: "\e079";
+}
+
+.glyphicon-chevron-right:before {
+    content: "\e080";
+}
+
+.glyphicon-chevron-up:before {
+    content: "\e113";
+}
+
+.glyphicon-chevron-down:before {
+    content: "\e114";
+}
+
+.glyphicon-calendar:before {
+    content: "\e109";
+}
+
+.glyphicon-screenshot:before {
+    content: "\e087";
+}
+
+.glyphicon-trash:before {
+    content: "\e020";
+}
+
+.glyphicon-remove:before {
+    content: "\e014";
+}
+
+.bootstrap-datetimepicker-widget .btn {
+    display: inline-block;
+    padding: 6px 12px;
+    margin-bottom: 0;
+    font-size: 14px;
+    font-weight: normal;
+    line-height: 1.42857143;
+    text-align: center;
+    white-space: nowrap;
+    vertical-align: middle;
+    -ms-touch-action: manipulation;
+    touch-action: manipulation;
+    cursor: pointer;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    background-image: none;
+    border: 1px solid transparent;
+    border-radius: 4px;
+}
+
+.bootstrap-datetimepicker-widget.dropdown-menu {
+    position: absolute;
+    left: 0;
+    z-index: 1000;
+    display: none;
+    float: left;
+    min-width: 160px;
+    padding: 5px 0;
+    margin: 2px 0 0;
+    font-size: 14px;
+    text-align: left;
+    list-style: none;
+    background-color: #fff;
+    -webkit-background-clip: padding-box;
+    background-clip: padding-box;
+    border: 1px solid #ccc;
+    border: 1px solid rgba(0, 0, 0, .15);
+    border-radius: 4px;
+    -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+    box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+}
+
+.bootstrap-datetimepicker-widget .list-unstyled {
+    padding-left: 0;
+    list-style: none;
+}
+
+.bootstrap-datetimepicker-widget .collapse {
+    display: none;
+}
+
+.bootstrap-datetimepicker-widget .collapse.in {
+    display: block;
+}
+
+/* fix for bootstrap4 */
+.bootstrap-datetimepicker-widget .table-condensed > thead > tr > th,
+.bootstrap-datetimepicker-widget .table-condensed > tbody > tr > td,
+.bootstrap-datetimepicker-widget .table-condensed > tfoot > tr > td {
+    padding: 5px;
+}
diff --git a/static/bootstrap_datepicker_plus/js/datepicker-widget.js b/static/bootstrap_datepicker_plus/js/datepicker-widget.js
new file mode 100644
index 0000000000000000000000000000000000000000..2288b46bd343e8c435149a99fa594a9f8e69eda2
--- /dev/null
+++ b/static/bootstrap_datepicker_plus/js/datepicker-widget.js
@@ -0,0 +1,55 @@
+jQuery(function ($) {
+    var datepickerDict = {};
+    var isBootstrap4 = $.fn.collapse.Constructor.VERSION.split('.').shift() == "4";
+    function fixMonthEndDate(e, picker) {
+        e.date && picker.val().length && picker.val(e.date.endOf('month').format('YYYY-MM-DD'));
+    }
+    $("[dp_config]:not([disabled])").each(function (i, element) {
+        var $element = $(element), data = {};
+        try {
+            data = JSON.parse($element.attr('dp_config'));
+        }
+        catch (x) { }
+        if (data.id && data.options) {
+            data.$element = $element.datetimepicker(data.options);
+            data.datepickerdata = $element.data("DateTimePicker");
+            datepickerDict[data.id] = data;
+            data.$element.next('.input-group-addon').on('click', function(){
+                data.datepickerdata.show();
+            });
+            if(isBootstrap4){
+                data.$element.on("dp.show", function (e) {
+                    $('.collapse.in').addClass('show');
+                });
+            }
+        }
+    });
+    $.each(datepickerDict, function (id, to_picker) {
+        if (to_picker.linked_to) {
+            var from_picker = datepickerDict[to_picker.linked_to];
+            from_picker.datepickerdata.maxDate(to_picker.datepickerdata.date() || false);
+            to_picker.datepickerdata.minDate(from_picker.datepickerdata.date() || false);
+            from_picker.$element.on("dp.change", function (e) {
+                to_picker.datepickerdata.minDate(e.date || false);
+            });
+            to_picker.$element.on("dp.change", function (e) {
+                if (to_picker.picker_type == 'MONTH') fixMonthEndDate(e, to_picker.$element);
+                from_picker.datepickerdata.maxDate(e.date || false);
+            });
+            if (to_picker.picker_type == 'MONTH') {
+                to_picker.$element.on("dp.hide", function (e) {
+                    fixMonthEndDate(e, to_picker.$element);
+                });
+                fixMonthEndDate({ date: to_picker.datepickerdata.date() }, to_picker.$element);
+            }
+        }
+    });
+    if(isBootstrap4) {
+        $('body').on('show.bs.collapse','.bootstrap-datetimepicker-widget .collapse',function(e){
+            $(e.target).addClass('in');
+        });
+        $('body').on('hidden.bs.collapse','.bootstrap-datetimepicker-widget .collapse',function(e){
+            $(e.target).removeClass('in');
+        });
+    }
+});
diff --git a/templates/bootstrap_datepicker_plus/date_picker.html b/templates/bootstrap_datepicker_plus/date_picker.html
new file mode 100644
index 0000000000000000000000000000000000000000..67a11df128df40abd4a4657b5bc4857e186f86e2
--- /dev/null
+++ b/templates/bootstrap_datepicker_plus/date_picker.html
@@ -0,0 +1,6 @@
+<div class="input-group date">
+    {% include "bootstrap_datepicker_plus/input.html" %}
+    <div class="input-group-addon input-group-append" data-target="#datetimepicker1" data-toggle="datetimepickerv">
+        <div class="input-group-text"><i class="glyphicon glyphicon-calendar"></i></div>
+    </div>
+</div>
diff --git a/templates/bootstrap_datepicker_plus/input.html b/templates/bootstrap_datepicker_plus/input.html
new file mode 100644
index 0000000000000000000000000000000000000000..b2f8c403d863d416ff1ca401d413cf54abd2717d
--- /dev/null
+++ b/templates/bootstrap_datepicker_plus/input.html
@@ -0,0 +1,4 @@
+<input type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None and widget.value != "" %}
+       value="{{ widget.value }}"{% endif %}{% for name, value in widget.attrs.items %}{% ifnotequal value False %}
+    {{ name }}{% ifnotequal value True %}="{{ value|stringformat:'s' }}"{% endifnotequal %}
+{% endifnotequal %}{% endfor %}/>
\ No newline at end of file
diff --git a/templates/bootstrap_datepicker_plus/time_picker.html b/templates/bootstrap_datepicker_plus/time_picker.html
new file mode 100644
index 0000000000000000000000000000000000000000..2bd509a39dde637216c9336462d025a3cfdf1223
--- /dev/null
+++ b/templates/bootstrap_datepicker_plus/time_picker.html
@@ -0,0 +1,6 @@
+<div class="input-group date">
+    {% include "bootstrap_datepicker_plus/input.html" %}
+    <div class="input-group-addon input-group-append" data-target="#datetimepicker1" data-toggle="datetimepickerv">
+        <div class="input-group-text"><i class="glyphicon glyphicon-time"></i></div>
+    </div>
+</div>
diff --git a/templates/note/amount_input.html b/templates/note/amount_input.html
new file mode 100644
index 0000000000000000000000000000000000000000..6ef4a53abd68980520621016d962bde22b2db91c
--- /dev/null
+++ b/templates/note/amount_input.html
@@ -0,0 +1,11 @@
+<div class="input-group">
+    <input class="form-control mx-auto d-block" type="number" min="0" step="0.01"
+           {% if widget.value != None and widget.value != "" %}value="{{ widget.value }}"{% endif %}
+           name="{{ widget.name }}"
+            {% for name, value in widget.attrs.items %}
+                {% ifnotequal value False %}{{ name }}{% ifnotequal value True %}="{{ value|stringformat:'s' }}"{% endifnotequal %}{% endifnotequal %}
+            {% endfor %}>
+    <div class="input-group-append">
+        <span class="input-group-text">€</span>
+    </div>
+</div>
\ No newline at end of file
diff --git a/templates/note/transaction_form.html b/templates/note/transaction_form.html
index d2cd85e9e269ea4b1a5e0f7c5fdaa0a5760ce419..65aaa635373a9a70c8f880dda6c7536cd6954113 100644
--- a/templates/note/transaction_form.html
+++ b/templates/note/transaction_form.html
@@ -126,12 +126,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
     <div class="form-row">
         <div class="form-group col-md-6">
             <label for="amount">{% trans "Amount" %} :</label>
-            <div class="input-group">
-                <input class="form-control mx-auto d-block" type="number" min="0" step="0.01" id="amount" />
-                <div class="input-group-append">
-                    <span class="input-group-text">€</span>
-                </div>
-            </div>
+            {% include "note/amount_input.html" with widget=amount_widget %}
         </div>
 
         <div class="form-group col-md-6">
diff --git a/templates/treasury/invoice_form.html b/templates/treasury/invoice_form.html
index 0edcbdcdcbd8e55d66cc66c2a58e825664d0fd77..2875d4103c03be5fc13d1b8c796d7a0f15b65c2c 100644
--- a/templates/treasury/invoice_form.html
+++ b/templates/treasury/invoice_form.html
@@ -1,7 +1,7 @@
 {% extends "base.html" %}
 {% load static %}
 {% load i18n %}
-{% load crispy_forms_tags pretty_money %}
+{% load crispy_forms_tags %}
 {% block content %}
     <p><a class="btn btn-default" href="{% url 'treasury:invoice_list' %}">{% trans "Invoices list" %}</a></p>
     <form method="post" action="">
@@ -26,18 +26,8 @@
                 {% endif %}
                 <tr class="row-formset">
                     <td>{{ form.designation }}</td>
-                    <td>{{ form.quantity }} </td>
-                    <td>
-                        {# Use custom input for amount, with the € symbol #}
-                        <div class="input-group">
-                            <input type="number" name="product_set-{{ forloop.counter0 }}-amount" step="0.01"
-                                   id="id_product_set-{{ forloop.counter0 }}-amount"
-                                   value="{{ form.instance.amount|cents_to_euros }}">
-                            <div class="input-group-append">
-                                <span class="input-group-text">€</span>
-                            </div>
-                        </div>
-                    </td>
+                    <td>{{ form.quantity }}</td>
+                    <td>{{ form.amount }}</td>
                     {# These fields are hidden but handled by the formset to link the id and the invoice id #}
                     {{ form.invoice }}
                     {{ form.id }}
@@ -64,15 +54,7 @@
             <tr class="row-formset">
                 <td>{{ formset.empty_form.designation }}</td>
                 <td>{{ formset.empty_form.quantity }} </td>
-                <td>
-                    <div class="input-group">
-                        <input type="number" name="product_set-__prefix__-amount" step="0.01"
-                               id="id_product_set-__prefix__-amount">
-                        <div class="input-group-append">
-                            <span class="input-group-text">€</span>
-                        </div>
-                    </div>
-                </td>
+                <td>{{ formset.empty_form.amount }}</td>
                 {{ formset.empty_form.invoice }}
                 {{ formset.empty_form.id }}
             </tr>