def delete(self, request, *args, **kwargs): instance = self.get_object() form = DiningListDeleteForm(request.user, instance) if form.is_valid(): day_view_url = super(DiningListMixin, self).reverse("day_view") # Evaluate the query to obtain diners before the dining list is removed from the database to_notify = list(instance.diners.exclude(id=request.user.id)) # Get dining list with related fields, necessary for sending mail because then the object is no longer in db dining_list = DiningList.objects.prefetch_related( 'owners', 'association').get(pk=instance.pk) with transaction.atomic(): form.execute() # Send mail to the people on the dining list send_templated_mail('mail/dining_list_deleted', to_notify, { 'dining_list': dining_list, 'cancelled_by': request.user, 'day_view_url': day_view_url }, request=request) messages.success(request, "Dining list is deleted") return HttpResponseRedirect(day_view_url) # Could not delete for error in form.non_field_errors(): messages.add_message(request, messages.ERROR, error) return HttpResponseRedirect(self.reverse("slot_delete"))
def post(self, request, *args, **kwargs): unpaid_user_entries = DiningEntryUser.objects.filter( dining_list=self.dining_list, has_paid=False) unpaid_guest_entries = DiningEntryExternal.objects.filter( dining_list=self.dining_list, has_paid=False) is_reminder = datetime.now().date( ) > self.dining_list.date # ?? Please explain non-trivial operations is_informed = False context = { 'dining_list': self.dining_list, 'reminder': request.user, 'is_reminder': is_reminder } if unpaid_user_entries.count() > 0: send_templated_mail( 'mail/dining_payment_reminder', User.objects.filter(diningentry__in=unpaid_user_entries), context=context, request=request) is_informed = True if unpaid_guest_entries.count() > 0: for user in User.objects.filter( diningentry__in=unpaid_guest_entries).distinct(): guests = [] for external_entry in unpaid_guest_entries.filter(user=user): guests.append(external_entry.name) # Call a different message if a the user added multiple guests who hadn't paid # Things like this can also be done in the template if len(guests) == 1: context["guest"] = guests[0] context["guests"] = None else: context["guest"] = None context["guests"] = guests send_templated_mail('mail/dining_payment_reminder_external', user, context, request) is_informed = True if is_informed: messages.success(request, "Diners have been informed") else: messages.info(request, "There was nobody to inform, everybody has paid") return HttpResponseRedirect(self.reverse('slot_details'))
def post(self, request, *args, **kwargs): # This post method always redirects, does not show the form again on validation errors, so that we don't have # to write HTML for displaying these errors (they are already in a Django message). # Do form shenanigans if 'add_external' in request.POST: entry = DiningEntryExternal(user=request.user, dining_list=self.dining_list, created_by=request.user) form = DiningEntryExternalCreateForm(request.POST, instance=entry) else: entry = DiningEntryUser(dining_list=self.dining_list, created_by=request.user) form = DiningEntryUserCreateForm(request.POST, instance=entry) if form.is_valid(): entry = form.save() # Construct success message if isinstance(entry, DiningEntryUser): if entry.user == request.user: msg = "You successfully joined the dining list" else: # Send mail to the diner send_templated_mail('mail/dining_entry_added_by', entry.user, context={ 'entry': entry, 'dining_list': entry.dining_list }, request=request) msg = "You successfully added {} to the dining list".format( entry.user.get_short_name()) else: msg = "You successfully added {} to the dining list".format( entry.name) messages.success(request, msg) else: # Apply error messages for field, errors in form.errors.items(): for error in errors: messages.error( request, "{}: {}".format(field, error) if field != NON_FIELD_ERRORS else error) # Redirect to next if provided, else to the diner list if successful, else to self next_url = request.GET.get('next') if next_url and is_safe_url(next_url, request.get_host()): return HttpResponseRedirect(next_url) if form.is_valid(): # Todo: Check if user is on multiple dining lists today, then show warning? return HttpResponseRedirect(self.reverse('slot_list')) return HttpResponseRedirect(self.reverse('entry_add'))
def save(self, commit=True, request=None): """This method sends an email to the source user on save. Provide the request for email template rendering. """ instance = super().save(commit=False) if commit: with transaction.atomic(): # We do this in a DB transaction so that when the e-mail failed, # the transaction is not saved. (Not sure whether it's a good idea, but doesn't really matter) instance.save() # Send mail if the source is a user source = self.instance.source if source.user: send_templated_mail('mail/transaction_created', source.user, {'transaction': instance}, request) return instance
def post(self, request, *args, **kwargs): entry = self.get_object().get_subclass() # Process deletion form = DiningEntryDeleteForm(entry, request.user, {}) if form.is_valid(): form.execute() # Success message if entry.is_internal() and entry.user == request.user: success_msg = "You are removed from the dining list" elif entry.is_external(): success_msg = "The external diner is removed from the dining list" else: success_msg = "The user is removed from the dining list" messages.success(request, success_msg) # Send a mail when someone else does the removal if entry.user != request.user: context = { 'entry': entry, 'dining_list': entry.dining_list, 'remover': request.user } if entry.is_external(): send_templated_mail( 'mail/dining_entry_external_removed_by', entry.user, context, request) else: send_templated_mail('mail/dining_entry_removed_by', entry.user, context, request) else: for error in form.non_field_errors(): messages.error(request, error) # Go to next next_url = request.GET.get('next') if not next_url or not is_safe_url(next_url, request.get_host()): next_url = entry.dining_list.get_absolute_url() return HttpResponseRedirect(next_url)
def send_test_mail(self, request, queryset): send_templated_mail('mail/test', queryset, request=request)