diff --git a/calebasse/agenda/appointments.py b/calebasse/agenda/appointments.py
index 50921bb..3b1e326 100644
--- a/calebasse/agenda/appointments.py
+++ b/calebasse/agenda/appointments.py
@@ -85,6 +85,7 @@ class Appointment(object):
             self.patient_record_paper_id = event.patient.paper_id
             self.act_type = event.act_type.name
             self.is_billed = event.act.is_billed
+            self.already_billed = event.act.already_billed
             state = event.get_state()
             state_name = state.state_name if state else 'NON_VALIDE'
             display_name = VALIDATION_STATES[state_name]
diff --git a/calebasse/agenda/forms.py b/calebasse/agenda/forms.py
index 364071b..4225af6 100644
--- a/calebasse/agenda/forms.py
+++ b/calebasse/agenda/forms.py
@@ -8,6 +8,7 @@ from django.utils.translation import ugettext_lazy as _

 from ..dossiers.models import PatientRecord
 from ..personnes.models import Worker
+from ..actes.models import Act
 from ..ressources.models import ActType
 from ..middleware.request import get_request

@@ -154,12 +155,26 @@ class UpdatePeriodicAppointmentForm(UpdateAppointmentForm):

     def clean(self):
         cleaned_data = super(UpdatePeriodicAppointmentForm, self).clean()
-        acts = self.instance.act_set.filter(is_billed=True).order_by('-date')
-        if acts and cleaned_data.get('recurrence_end_date'):
-            recurrence_end_date = cleaned_data['recurrence_end_date']
-            if recurrence_end_date < acts[0].date:
+        start_datetime = cleaned_data.get('start_datetime')
+        if start_datetime:
+            acts = Act.objects.filter(
+                Q(parent_event=self.instance,
+                    already_billed=True, date__lt=start_datetime) | \
+                Q(parent_event__exception_to=self.instance,
+                    already_billed=True, date__lt=start_datetime))
+            if acts:
+                self._errors['start_datetime'] = self.error_class([
+                    u"La date de début doit être antérieure au premier acte déja facturé de la récurrence"])
+        recurrence_end_date = cleaned_data.get('recurrence_end_date')
+        if recurrence_end_date:
+            acts = Act.objects.filter(
+                Q(parent_event=self.instance,
+                    already_billed=True, date__gt=recurrence_end_date) | \
+                Q(parent_event__exception_to=self.instance,
+                    already_billed=True, date__gt=recurrence_end_date))
+            if acts:
                 self._errors['recurrence_end_date'] = self.error_class([
-                            u"La date doit être supérieur au dernier acte facturé de la récurrence"])
+                    u"La date de fin doit être postérieure au dernier acte déja facturé de la récurrence"])
         return cleaned_data

 class DisablePatientAppointmentForm(UpdateAppointmentForm):
@@ -279,5 +294,5 @@ class PeriodicEventsSearchForm(forms.Form):
         cleaned_data = super(PeriodicEventsSearchForm, self).clean()
         if cleaned_data.get('start_date') and cleaned_data.get('end_date'):
             if cleaned_data['start_date'] > cleaned_data['end_date']:
-                raise forms.ValidationError(u'La date de début doit être supérieure à la date de fin')
+                raise forms.ValidationError(u'La date de début doit être antérieure à la date de fin')
         return cleaned_data
diff --git a/calebasse/agenda/models.py b/calebasse/agenda/models.py
index 339b5d1..d78a738 100644
--- a/calebasse/agenda/models.py
+++ b/calebasse/agenda/models.py
@@ -207,6 +207,20 @@ class Event(models.Model):
         '''Distance between start and end of the event'''
         return self.end_datetime - self.start_datetime

+    @property
+    def time(self):
+        return self.start_datetime.time()
+
+    @property
+    def date(self):
+        return self.start_datetime.date()
+
+    @property
+    def duration(self):
+        if self.timedelta():
+            return self.timedelta().seconds / 60
+        return 0
+
     def match_date(self, date):
         if self.is_recurring():
             # consider exceptions
@@ -360,12 +374,69 @@ class Event(models.Model):
         assert self.start_datetime is not None
         self.sanitize() # init periodicity fields
         super(Event, self).save(*args, **kwargs)
+        self.events_cleaning()
         self.acts_cleaning()

     def delete(self, *args, **kwargs):
-        self.canceled = True
-        # save will clean acts
-        self.save(*args, **kwargs)
+        if not self.one_act_already_billed():
+            for exception in self.exceptions.all():
+                exception.delete()
+            self.canceled = True
+            if hasattr(self, 'eventwithact'):
+                # Needed
+                self.eventwithact.canceled = True
+            # save will clean acts
+            self.save(*args, **kwargs)
+
+    def one_act_already_billed(self):
+        '''
+            Return True if at least one act of the present event or an act
+            of one of its exceptions is already billed.
+        '''
+        from ..actes.models import Act
+        acts = Act.objects.filter(
+                models.Q(parent_event=self,
+                    already_billed=True) | \
+                models.Q(parent_event__exception_to=self,
+                    already_billed=True))
+        if acts:
+            return True
+        return False
+
+    def one_act_is_billed(self):
+        '''
+            Return True if at least one act of the present event or an act
+            of one of its exceptions is billed.
+        '''
+        from ..actes.models import Act
+        acts = Act.objects.filter(
+                models.Q(parent_event=self, is_billed=True) | \
+                models.Q(parent_event__exception_to=self, is_billed=True))
+        if acts:
+            return True
+        return False
+
+    def events_cleaning(self):
+        """
+            Delete exceptions out of bounds if not with an associated act
+            already billed.
+        """
+        events = None
+        if self.recurrence_end_date:
+            events = Event.objects.filter(
+                models.Q(exception_to=self,
+                    exception_date__lt=self.start_datetime.date()) | \
+                models.Q(exception_to=self,
+                    exception_date__gt=self.recurrence_end_date))
+        else:
+            events = Event.objects.filter(exception_to=self,
+                    exception_date__lt=self.start_datetime.date())
+        for event in events:
+            if hasattr(event, 'eventwithact'):
+                if not event.eventwithact.act.already_billed:
+                    event.delete()
+            else:
+                event.delete()

     def acts_cleaning(self):
         # list of occurences may have changed
@@ -382,13 +453,12 @@ class Event(models.Model):
         if acts:
             eventwithact = self.eventwithact
             for act in acts:
-                if act.is_billed:
-                    pass
                 occurrence = eventwithact.today_occurrence(act.date)
                 if occurrence:
                     occurrence.update_act(act)
                 else:
-                    act.delete()
+                    if not act.already_billed:
+                        act.delete()

     def to_interval(self):
         return Interval(self.start_datetime, self.end_datetime)
@@ -538,14 +608,15 @@ class EventWithAct(Event):
         act.save()

     def init_act(self, act):
-        delta = self.timedelta()
-        duration = delta.seconds // 60
-        act._duration = duration
-        act.act_type = self.act_type
-        act.patient = self.patient
+        if not act.is_billed:
+            delta = self.timedelta()
+            duration = delta.seconds // 60
+            act._duration = duration
+            act.act_type = self.act_type
+            act.patient = self.patient
+            act.date = self.start_datetime.date()
+            act.time = self.start_datetime.time()
         act.parent_event = self
-        act.date = self.start_datetime.date()
-        act.time = self.start_datetime.time()

     def save(self, *args, **kwargs):
         '''Force event_type to be patient meeting.'''
diff --git a/calebasse/agenda/templates/agenda/ajax-worker-tab.html b/calebasse/agenda/templates/agenda/ajax-worker-tab.html
index cb643bd..ffa25d6 100644
--- a/calebasse/agenda/templates/agenda/ajax-worker-tab.html
+++ b/calebasse/agenda/templates/agenda/ajax-worker-tab.html
@@ -58,7 +58,7 @@
           {% else %}
             <button title="Éditer un événement" class="edit-event icon-edit" data-event-id="{{ appointment.event_id }}">
           {% endif %}
-          {% if not appointment.is_billed %}
+          {% if not appointment.already_billed %}
           <button class="remove-appointment icon-remove-sign" title="Supprimer un rendez-vous" data-url="{% url 'delete-occurrence' service=service date=date pk=appointment.event_id %}" data-rdv="{{ appointment.title }}"></button>
           {% endif %}
          {% endif %}
diff --git a/calebasse/agenda/templates/agenda/appointment.html b/calebasse/agenda/templates/agenda/appointment.html
index 37d355e..93052de 100644
--- a/calebasse/agenda/templates/agenda/appointment.html
+++ b/calebasse/agenda/templates/agenda/appointment.html
@@ -3,23 +3,32 @@
 {{ form.non_field_errors }}
 {{ form.start_datetime }}
 {{ form.start_datetime.errors }}
+   {% if object.is_recurring and object.one_act_is_billed %}<p><em>Le rendez-vous périodique a un acte qui est facturé ce qui empêche de le modifier à l'exception de la description, de la ressource et des dates de début et de fin.</em></p>{% endif %}
+   {% if object.is_recurring and object.one_act_already_billed %}<p><em>Le rendez-vous périodique a un acte qui a déjà été facturé ce qui empêche de le supprimer.</em></p>{% endif %}
    <table id="new-appointment-table">
        <tr>
            <td {% if form.time.field.required %}class="required"{% endif %}>
             <p>
            {{ form.time.label_tag }}
+           {% if object.is_recurring and object.one_act_is_billed %}
+           {{ object.time }}
+           {{ form.time.as_hidden }}
+           {% else %}
            {{ form.time }}
+           {% endif %}
            {{ form.time.errors }}
            </p>
            </td>
            <td {% if form.duration.field.required %}class="required"{% endif %}>
            <p>
            {{ form.duration.label_tag }}
-           {{ form.duration|add_class:"mousewheel"|attr:"data-mousewheel-increment:5" }}
+           {% if object.is_recurring and object.one_act_is_billed %}
+           {{ object.duration }}
+           {{ form.duration.as_hidden }}
+           {% else %}
+           {{ form.duration }}
+           {% endif %}
            {{ form.duration.errors }}
-           <div>
-           {{ form.duration.help_text }}
-           </div>
            </p>
            </td>
            <td {% if form.date.field.required %}class="required"{% endif %}>
@@ -43,15 +52,21 @@
            <td {% if form.participants.field.required %}class="required"{% endif %}>
            <h4>{{ form.participants.label_tag }}</h4>
            <div id="intervenants">
+           {% if object.is_recurring and object.one_act_is_billed %}
+           <ul>{% for p in object.participants.all %}<li>{{ p }}</li>{% endfor %}</ul>
+           <input id="id_participants" name="participants" value="|{% for p in object.participants.all %}{{ p.id }}|{% endfor %}" type="hidden"/>
+           {% else %}
            {{ form.participants }}
+           {% endif %}
            {{ form.participants.errors }}
            </div>
            </td>
            <td {% if form.patient.field.required %}class="required"{% endif %}>
            <h4>{{ form.patient.label_tag }}</h4>
            <div id="patient">
-           {% if object.exception_to and not object.exception_to.canceled %}
+           {% if object.is_recurring or object.exception_to or object.act.already_billed %}
            {{ object.patient }}
+           {{ form.patient.as_hidden }}
            {% else %}
            {{ form.patient }}
            {{ form.patient.errors }}
@@ -60,7 +75,12 @@
            </td>
            <td {% if form.act_type.field.required %}class="required"{% endif %}>
            <h4>{{ form.act_type.label_tag }}</h4>
+           {% if object.is_recurring and object.one_act_is_billed %}
+           {{ object.act_type }}
+           {{ form.act_type.as_hidden }}
+           {% else %}
            {{ form.act_type }}
+           {% endif %}
            {{ form.act_type.errors }}
            </td>
        </tr>
@@ -79,13 +99,16 @@
   <hr/>
   {% if object.id != object.exception_to.id %}
   <p><em>Attention: cet objet est une exception à un rendez-vous périodique; si
-  vous modifiez ou supprimiez ce rendez-vous périodique, l'exception n'en serait pas
+  vous modifiez ou supprimez le rendez-vous périodique, l'exception n'en sera pas
   affectée.</em></p>
   {% endif %}
-  <div>Occurence du {{object.exception_date}} d'un rendez-vous périodique
-    {% if object.exception_to.canceled %}<em>supprimée</em> et initialement prévue{% endif %}
-    {{ object.exception_to.recurrence_description|lower }}</div>
+
+  <p>Occurence du {{object.exception_date}} d'un rendez-vous périodique
+    {% if object.exception_to.canceled %}<em>supprimé</em> et initialement prévu{% endif %}
+    {{ object.exception_to.recurrence_description|lower }}</p>
+
   {% if not object.exception_to.canceled %}
-  <button type="button" data-delete-url="{% url 'delete-event' service=service date=date pk=object.exception_to.pk %}" data-id="{{ object.exception_to.id }}" class="update-periodic-rdv">Éditer le rendez-vous périodique</button>
+  <p><button type="button" data-delete-url="{% url 'delete-event' service=service date=date pk=object.exception_to.pk %}" data-id="{{ object.exception_to.id }}" data-one_act_already_billed="{{ object.exception_to.one_act_already_billed }}"  class="update-periodic-rdv">Éditer le rendez-vous périodique</button></p>
   {% endif %}
+
 {% endif %}
diff --git a/calebasse/agenda/templates/agenda/periodicity.html b/calebasse/agenda/templates/agenda/periodicity.html
index cbea278..013042d 100644
--- a/calebasse/agenda/templates/agenda/periodicity.html
+++ b/calebasse/agenda/templates/agenda/periodicity.html
@@ -4,8 +4,13 @@
            <td {% if form.recurrence_periodicity.field.required %}class="required"{% endif %}>
             <p>
            {{ form.recurrence_periodicity.label_tag }}
+           {% if object.one_act_already_billed %}
+           {{ object.recurrence_description }}
+           {{ form.recurrence_periodicity.as_hidden }}
+           {% else %}
            {{ form.recurrence_periodicity }}
            {{ form.recurrence_periodicity.errors }}
+           {% endif %}
            </p>
            </td>
            <td {% if form.recurrence_end_date.field.required %}class="required"{% endif %}>
diff --git a/calebasse/agenda/views.py b/calebasse/agenda/views.py
index 9f70863..60dbc28 100644
--- a/calebasse/agenda/views.py
+++ b/calebasse/agenda/views.py
@@ -274,22 +276,6 @@ class UpdatePeriodicEventView(BaseEventView):
     form_class = UpdatePeriodicEventForm
     template_name = 'agenda/new-event.html'

-def delete_eventwithact(event):
-    assert event.event_type_id == 1
-
-    # in case of "event" is an instance of "Event" model and not "EventWithAct"
-    # and so doesn't have 'act' attribute
-    try:
-        if event.act.id \
-           and not event.act.is_billed:
-            event.act.delete()
-
-        if not event.act.id or \
-           not event.act.is_billed:
-            event.delete()
-    except AttributeError:
-        event.delete()
-
 class DeleteOccurrenceView(TodayOccurrenceMixin, cbv.DeleteView):
     model = Event
     success_url = '..'
@@ -297,11 +283,9 @@ class DeleteOccurrenceView(TodayOccurrenceMixin, cbv.DeleteView):

     def delete(self, request, *args, **kwargs):
         self.object = self.get_object()
-        if self.object.event_type_id == 1:
-            delete_eventwithact(self.object)
-        else:
-            self.object.delete()
-
+        # If the exception does not exist we need to create it before set it canceled
+        self.object.save()
+        self.object.delete()
         return HttpResponse(status=204)

 class DeleteEventView(cbv.DeleteView):
@@ -311,20 +295,7 @@ class DeleteEventView(cbv.DeleteView):

     def delete(self, request, *args, **kwargs):
         self.object = self.get_object()
-        # If exceptions remove them only if act is not billed
-        for exception in self.object.exceptions.all():
-            exception.recurrence_periodicity = None
-            exception.exception_to = None
-            exception.save()
-            if exception.event_type_id == 1:
-                delete_eventwithact(exception)
-            else:
-                exception.delete()
-
-        if self.object.event_type_id == 1:
-            delete_eventwithact(self.object)
-        else:
-            self.object.delete()
+        self.object.delete()
         return HttpResponse(status=204)

 class AgendaServiceActValidationView(TemplateView):
diff --git a/calebasse/static/js/calebasse.agenda.js b/calebasse/static/js/calebasse.agenda.js
index 5c04cb7..8247c9a 100644
--- a/calebasse/static/js/calebasse.agenda.js
+++ b/calebasse/static/js/calebasse.agenda.js
@@ -290,25 +290,30 @@ function event_dialog(url, title, width, btn_text) {
       $(base).on('click', '.update-periodic-rdv', function () {
         $('.ui-icon-closethick').click();
         var id = $(this).data('id');
-        var delete_url = $(this).data('delete-url');
-        var delete_button = {
-            text: "Supprimer",
-            id: "delete-btn",
-            click: function () {
-                var r = delete_prompt("Etes-vous sûr de vouloir supprimer ce rendez-vous récurrent ?");
-                if (r == true)
-                {
-                  $.ajax({
-                    url: delete_url,
-                    type: 'DELETE',
-                    success: function(data) {
-                        window.location.reload(true);
-                        return false;
+        var one_act_already_billed = $(this).data('one_act_already_billed');
+        var delete_button = null
+        if (one_act_already_billed == 'False') {
+            var delete_url = $(this).data('delete-url');
+            var delete_button = {
+                text: "Supprimer",
+                id: "delete-btn",
+                click: function () {
+                    var r = delete_prompt("Etes-vous sûr de vouloir supprimer ce rendez-vous récurrent ?");
+                    if (r == true)
+                    {
+                      $.ajax({
+                        url: delete_url,
+                        type: 'DELETE',
+                        success: function(data) {
+                            window.location.reload(true);
+                            return false;
+                        }
+                      });
                     }
-                  });
                 }
-            }
-        };
+            };
+        }
         generic_ajaxform_dialog('/' + service + '/' + app_name + '/' + current_date + '/update-periodic-rdv/' + id,
           'Modifier un rendez-vous périodique', '#ajax-dlg', '900px', 'Modifier', null, init_datepickers, null, delete_button);
       });
