Exemple #1
0
    def send_prepare_ride_mails(self):
        if self.prepare_ride_mails_sent is True:
            log_event(event="Not sending prepare ride mails for round %d "
                            "because prepare_ride_mails_sent is True" %
                            self.pk)
            return

        log_event(event="Sending prepare ride mails for round %d" % self.pk)

        mail_template = get_template_by_id(config.PREPARE_RIDE_MAIL)

        self.prepare_ride_mails_sent = True
        self.save()

        rides = self.rides.all()
        for ride in rides:
            drivers = [ride.driver, ride.codriver]
            for user in drivers:
                rendered_template_vars = render_mail_template(
                    mail_template,
                    user=user,
                    ride=ride,
                    base_url=settings.BASE_URL
                )
                mail_user(user, *rendered_template_vars)
Exemple #2
0
def mail_user(user, subject, html_body, plain_body):
    send_mail(subject=subject,
              message=plain_body,
              from_email="VOKO Utrecht <info@vokoutrecht.nl>",
              recipient_list=["%s <%s>" % (user.get_full_name(), user.email)],
              html_message=html_body)
    log.log_event(user=user, event="Mail sent: %s" % subject, extra=html_body)
Exemple #3
0
    def send_ride_mails(self):
        if self.rides_mails_sent is True:
            log_event(event="Not sending ride mails for round %d because "
                            "rides_mails_sent is True" % self.pk)
            return

        log_event(event="Sending ride mails for round %d" % self.pk)

        mail_template = get_template_by_id(config.RIDE_MAIL)

        self.rides_mails_sent = True
        self.save()

        rides = self.rides.all()
        for ride in rides:
            involved = {
                ride.driver,
                ride.codriver,
                self.distribution_coordinator
            }
            for user in involved:
                if user is None:
                    continue
                rendered_template_vars = render_mail_template(
                    mail_template,
                    user=user,
                    ride=ride,
                    base_url=settings.BASE_URL
                )
                mail_user(user, *rendered_template_vars)
Exemple #4
0
def force_confirm_email(modeladmin, request, queryset):
    for user in queryset:
        user.email_confirmation.is_confirmed = True
        user.email_confirmation.save()

        log.log_event(operator=request.user,
                      event="User's e-mail forcefully confirmed: %s" % user,
                      user=user)
Exemple #5
0
def mail_user(user, subject, html_body, plain_body, from_email):
    default_from_email = settings.DEFAULT_FROM_EMAIL
    send_mail(subject=subject,
              message=plain_body,
              from_email=from_email if from_email else default_from_email,
              recipient_list=["%s <%s>" % (user.get_full_name(), user.email)],
              html_message=html_body)
    log.log_event(user=user, event="Mail sent: %s" % subject, extra=html_body)
Exemple #6
0
 def complete_after_payment(self):
     """
     Complete order by setting the 'paid' boolean, creating debit and mailing the user.
     """
     log_event(event="Completing (paid) order %s" % self.id, user=self.user)
     self.paid = True
     self.save()
     self.create_debit()
     self.mail_confirmation()
Exemple #7
0
 def create_debit(self):
     """
     Create debit for order and create one-to-one relation
     """
     log_event(event="Creating debit for order %s" % self.id)
     self.debit = Balance.objects.create(user=self.user,
                                         type="DR",
                                         amount=self.total_price,
                                         notes="Debit van %s voor bestelling #%d" % (self.total_price, self.pk))
     self.save()
Exemple #8
0
    def form_valid(self, form):
        try:
            user = VokoUser.objects.get(email=form.cleaned_data['email'].lower())
            request = PasswordResetRequest(user=user)
            request.save()
            request.send_email()

        except VokoUser.DoesNotExist:
            # Do not notify user
            log.log_event(event="Password reset requested for unknown email address: %s" % form.cleaned_data['email'])

        return super(RequestPasswordResetView, self).form_valid(form)
Exemple #9
0
    def post(self, request, *args, **kwargs):
        Form = self.get_form_class()
        form = Form(data=request.POST)
        form.full_clean()

        if form.is_valid() is False:
            # Should not happen, as the form has just one input field.
            # Redirect back to previous view
            return redirect(reverse('finance.choosebank'))

        order_to_pay = get_order_to_pay(request.user)
        if not order_to_pay:
            messages.error(request, "Geen bestelling gevonden")
            return redirect(reverse('view_products'))

        amount_to_pay = order_to_pay\
            .total_price_to_pay_with_balances_taken_into_account()
        log_event(
            event="Initiating payment (creating transaction) for order %d "
                  "and amount %f" %
                  (order_to_pay.id, amount_to_pay), user=order_to_pay.user)

        # Sanity checks. If one of these fails, it's very likely that someone
        # is tampering.
        assert order_to_pay.user == request.user
        assert order_to_pay.finalized is True
        assert order_to_pay.paid is False
        assert order_to_pay.payments.filter(succeeded=True).exists() is False

        if order_to_pay.order_round.is_open is not True:
            messages.error(request,
                           "De bestelronde is gesloten, "
                           "je kunt niet meer betalen.")
            log_event(
                event="Payment for order %s canceled because "
                      "order round %s is closed" %
                      (order_to_pay.id, order_to_pay.order_round.id),
                user=order_to_pay.user)
            return redirect(reverse('finish_order', args=(order_to_pay.id,)))

        bank_id = form.cleaned_data['bank']
        results = self.create_payment(amount=float(amount_to_pay),
                                      description="VOKO Utrecht %d"
                                                  % order_to_pay.id,
                                      issuer_id=bank_id,
                                      order_id=order_to_pay.id)

        Payment.objects.create(amount=amount_to_pay,
                               order=order_to_pay,
                               mollie_id=results["id"])

        redirect_url = results.getPaymentUrl()
        return redirect(redirect_url)
Exemple #10
0
    def get(self, request, *args, **kwargs):
        order_to_pay = Order.objects.get(id=request.session['order_to_pay'])

        # Sanity checks
        assert order_to_pay.finalized is True
        assert order_to_pay.paid is False

        order_to_pay.finalized = False
        order_to_pay.save()

        log_event(event="Payment for order %s canceled" % order_to_pay.id,
                  user=order_to_pay.user)

        return HttpResponseRedirect(
            reverse("finish_order", args=(order_to_pay.pk,)))
Exemple #11
0
    def _send_mails(self):
        for user in self.users:
            subject, html_message, plain_message = render_mail_template(self.template,
                                                                        user=user,
                                                                        order_round=self.current_order_round)

            send_mail(subject=subject,
                      message=plain_message,
                      from_email="VOKO Utrecht <info@vokoutrecht.nl>",
                      recipient_list=["%s <%s>" % (user.get_full_name(), user.email)],
                      html_message=html_message)

            log_event(operator=self.request.user,
                      user=user,
                      event="Mail verstuurd met onderwerp '%s'" % subject,
                      extra=html_message)
Exemple #12
0
def enable_user(modeladmin, request, queryset):
    for user in queryset:
        if not user.email_confirmation.is_confirmed or user.is_active:
            return

    queryset.update(can_activate=True)

    for user in queryset:
        ## send mail
        mail_template = get_template_by_id(ACTIVATE_ACCOUNT_MAILTEMPLATE_ID)
        subject, html_message, plain_message = render_mail_template(mail_template, user=user)
        send_mail(subject=subject,
                  message=plain_message,
                  from_email="VOKO Utrecht <info@vokoutrecht.nl>",
                  recipient_list=["%s <%s>" % (user.get_full_name(), user.email)],
                  html_message=html_message)
        log.log_event(user=user, event="User set to 'can_activate=True' and activation mail sent", extra=html_message)
Exemple #13
0
    def determine_if_product_is_new_and_set_label(self):
        """
        Set new=True on product when similar product cannot be found in previous order round.
        'new' attribute is used to show 'New' label in product list.
        """
        try:
            prev_round = OrderRound.objects.get(id=self.order_round.id-1)
        except OrderRound.DoesNotExist:
            return

        if not prev_round.products.filter(name=self.name,
                                          supplier=self.supplier,
                                          unit=self.unit):
            self.new = True
            self.save()
            log_event(event="Setting product %s to 'new' because I could not find a "
                            "similar product in order round %d" % (self, prev_round.id))
Exemple #14
0
    def send_reminder_mails(self):
        if self.reminder_sent is True:
            log_event(event="Not sending order reminder for round %d because "
                            "reminder_sent is True" % self.pk)

            return

        log_event(event="Sending order reminder for round %d" % self.pk)

        mail_template = get_template_by_id(config.ORDER_REMINDER_MAIL)

        self.reminder_sent = True
        self.save()

        for user in self.get_users_without_orders():
            rendered_template_vars = render_mail_template(
                mail_template, user=user, order_round=self)
            mail_user(user, *rendered_template_vars)
Exemple #15
0
    def get(self, request, *args, **kwargs):
        order_to_pay = get_order_to_pay(request.user)
        if not order_to_pay:
            messages.error(request, "Geen bestelling gevonden")
            return redirect(reverse('view_products'))

        # Sanity checks
        assert order_to_pay.finalized is True
        assert order_to_pay.paid is False

        order_to_pay.finalized = False
        order_to_pay.save()

        log_event(event="Payment for order %s canceled" % order_to_pay.id,
                  user=order_to_pay.user)

        return HttpResponseRedirect(
            reverse("finish_order", args=(order_to_pay.pk,)))
Exemple #16
0
    def _send_mails(self):
        for user in self.users:
            (
                subject,
                html_message,
                plain_message,
                from_email
            ) = render_mail_template(
                self.template,
                user=user,
                order_round=self.current_order_round
            )

            mail_user(user, subject, html_message, plain_message, from_email)

            log_event(operator=self.request.user,
                      user=user,
                      event="Mail verstuurd met onderwerp '%s'" % subject,
                      extra=html_message)
Exemple #17
0
    def save(self, commit=True):
        with transaction.atomic():
            # Save zip code in address
            address = Address.objects.create(zip_code=self.cleaned_data['zip_code'])

            # Create user
            user = super(VokoUserFinishForm, self).save(commit=False)
            user.set_password(self.cleaned_data["password1"])
            user.is_active = True

            if commit:
                user.save()

            # Lastly, link the two
            UserProfile.objects.create(user=user, address=address,
                                       notes=self.cleaned_data['notes'],
                                       phone_number=self.cleaned_data['phone_number'])

            self._notify_admins_about_activated_user(user)
            log.log_event(user=user, event="User finished registration")

        return user
Exemple #18
0
    def get_context_data(self, **kwargs):
        context = super(ConfirmTransactionView, self).get_context_data(
            **kwargs)

        order_id = self.request.GET.get('order')

        # Payment may already be confirmed by the webhook
        try:
            order = Order.objects.get(id=order_id, user=self.request.user)
        except Order.DoesNotExist:
            raise Http404

        if order.paid is True:
            context['payment_succeeded'] = True
            return context

        payment = Payment.objects.filter(order__id=order_id,
                                         succeeded=False,)\
            .order_by('id').last()

        if payment is None:
            raise Http404

        mollie_payment = self.get_payment(payment.mollie_id)
        success = mollie_payment.isPaid()

        if success:
            if (payment.order.finalized is True and
                    payment.order.paid is False and
                    payment.order.order_round.is_open is True):

                payment.succeeded = True
                payment.save()

                payment.create_and_link_credit()
                payment.order.complete_after_payment()

                log_event(
                    event="Payment %s for order %s and amount %f succeeded" %
                          (payment.id, payment.order.id, payment.amount),
                    user=payment.order.user)

            else:
                log_event(event="Payment %s was already paid" % payment.id,
                          user=payment.order.user)

            try:
                del self.request.session['order_to_pay']
            except KeyError:
                pass

        else:
            log_event(event="Payment %s for order %s and amount %f failed" %
                            (payment.id, payment.order.id, payment.amount),
                      user=payment.order.user)

        context['payment_succeeded'] = success
        return context
Exemple #19
0
    def post(self, request, *args, **kwargs):
        order = self.get_object()

        user_notes = request.POST.get('notes').strip()
        if user_notes:
            order.user_notes = user_notes

        log_event(event="Finalizing order %s" % order.id, user=order.user)
        order.finalized = True  # Freeze order
        order.save()

        if self.calculate_payment() == 0:
            log_event(event="Payment for order %d not necessary because order total is %f and user's credit is %f" %
                            (order.id, order.total_price, order.user.balance.credit()), user=order.user)
            messages.add_message(self.request, messages.SUCCESS,
                                 'Omdat je genoeg krediet had was betalen niet nodig. '
                                 'Je bestelling is bevestigd.')
            order.complete_after_payment()
            return redirect(reverse('order_summary', args=(order.pk,)))

        # Store order_id in session
        request.session['order_to_pay'] = order.id
        return redirect('finance.choosebank')
Exemple #20
0
    def save(self, commit=True):
        with transaction.atomic():
            # Update user
            user = super(ChangeProfileForm, self).save()

            if self.cleaned_data['password1']:
                user.set_password(self.cleaned_data["password1"])

            # Profile
            userprofile = user.userprofile
            userprofile.phone_number = self.cleaned_data['phone_number']

            # And address
            address = user.userprofile.address
            address.zip_code = self.cleaned_data['zip_code']

            if commit:
                user.save()
                userprofile.save()
                address.save()

            log.log_event(user=user, event="User changed profile")

        return user
Exemple #21
0
def enable_user(modeladmin, request, queryset):
    for user in queryset:
        if not user.email_confirmation.is_confirmed or user.is_active:
            return

    queryset.update(can_activate=True)

    for user in queryset:
        # send mail
        mail_template = get_template_by_id(config.ACTIVATE_ACCOUNT_MAIL)
        (
            subject,
            html_message,
            plain_message,
            from_email
        ) = render_mail_template(
            mail_template, user=user
        )
        mail_user(user, subject, html_message, plain_message, from_email)
        log.log_event(
            user=user,
            event="User set to 'can_activate=True' and activation mail sent",
            extra=html_message
        )
Exemple #22
0
    def post(self, request, *args, **kwargs):
        mollie_id = request.POST.get('id')

        payment = get_object_or_404(Payment, mollie_id=mollie_id)
        mollie_payment = self.get_payment(payment.mollie_id)
        success = mollie_payment.isPaid()

        if not success:
            log_event(
                event="Payment %s for order %s and amount %f "
                      "failed via callback" %
                      (payment.id, payment.order.id, payment.amount),
                user=payment.order.user)
            return HttpResponse("")

        # Successful payment!
        payment.succeeded = True
        payment.save()

        payment.create_and_link_credit()
        log_event(
            event="Payment %s for order %s and amount %f "
                  "succeeded via callback" %
                  (payment.id, payment.order.id, payment.amount),
            user=payment.order.user)

        if payment.order.paid is False:
            # Order has not been paid, but the payment has now been confirmed
            # and credit has been created.
            # Time to finish the order, if the order round is still open.

            # Sanity Check
            assert payment.order.finalized is True

            if payment.order.order_round.is_open:
                payment.order.complete_after_payment()
            else:
                # Corner case where payment was executed before closing time,
                # but never finished (user closed browser tab),
                # the payment is now validated by callback, but order round is
                # closed and our suppliers likely have been mailed the totals.
                # Credit for the user has just been created, but we don't
                # want to complete the order because it was placed too late.
                log_event(
                    event="Order round %s is closed, so not finishing "
                          "order %s via callback!" % (
                              payment.order.order_round.id,
                              payment.order.id),
                    user=payment.order.user)

                payment.order.mail_failure_notification()

        return HttpResponse("")
Exemple #23
0
    def do(self):
        order_round = get_current_order_round()
        print(("Order round: %s" % order_round))
        if order_round.is_open:
            print("Order round is closed")
            return

        if order_round.is_not_open_yet():
            print("Order round is not open yet")
            return

        if order_round.order_placed:
            print("Order has already been placed")
            return

        # To prevent mail loops
        order_round.order_placed = True
        order_round.save()

        for supplier in Supplier.objects.all():
            if not supplier.has_orders_in_current_order_round():
                print(("No orders for supplier %s" % supplier))
                log_event(event="Supplier %s has no orders in current round, "
                                "so not sending order list." % supplier)
                continue

            print(("Generating lists for supplier %s" % supplier))

            # Generate CSV
            in_mem_file = io.BytesIO()
            csv_writer = csv.writer(in_mem_file, delimiter=';', quotechar='|')

            # Write header row
            csv_writer.writerow(
                ["Aantal", "Eenheid", "Product", "Omschrijving",
                 "Inkoopprijs Euro", "Subtotaal"])

            ordered_products = supplier.products. \
                exclude(orderproducts=None). \
                filter(orderproducts__order__paid=True). \
                filter(order_round=order_round). \
                annotate(amount_sum=Sum('orderproducts__amount'))

            if not ordered_products:
                log_event(event="Supplier %s has only STOCK orders "
                                "in current round, "
                                "so not sending order list." % supplier)
                continue

            # Write products and amounts
            for obj in ordered_products:
                csv_writer.writerow([
                    fix_decimal_separator(obj.amount_sum),
                    obj.unit_of_measurement,
                    obj.name,
                    obj.description.replace("\n", " ").replace("\r", " "),
                    # TODO make sure newlines aren't stored
                    # in our products
                    fix_decimal_separator(obj.base_price),
                    fix_decimal_separator(obj.amount_sum * obj.base_price)
                ])

            # Write 'total' row
            total = fix_decimal_separator(sum(
                [obj.amount_sum * obj.base_price for obj in ordered_products]))
            csv_writer.writerow([])
            csv_writer.writerow(["TOTAAL", "", "", "", "", total])

            in_mem_file.seek(0)
            in_mem_file.seek(0)  # Why is this here twice?

            # Generate mail
            subject = ('VOKO Utrecht - Bestellijst voor %s' %
                       order_round.collect_datetime.strftime("%d %B %Y"))
            from_email = 'VOKO Utrecht Boerencontact <boeren@vokoutrecht.nl>'
            to = '%s <%s>' % (supplier.name, supplier.email)

            text_content = """
Hoi %s,

Hierbij sturen we onze bestelling voor bestelronde %d
voor ons uitlevermoment op %s.

De bestelling is in CSV-formaat, dit is te openen in bijvoorbeeld Excel.

Dit is een geautomatiseerd bericht, maar reageren is gewoon mogelijk.

Vriendelijke groeten,
VOKO Utrecht
""" % (
                supplier,
                order_round.pk,
                order_round.collect_datetime.strftime("%d %B %Y")
            )

            msg = EmailMultiAlternatives(
                subject,
                text_content,
                from_email,
                [to],
                cc=["VOKO Utrecht Boerencontact <boeren@vokoutrecht.nl>"]
            )

            msg.attach('voko_utrecht_bestelling_ronde_%d.csv' % order_round.pk,
                       in_mem_file.read().decode("utf-8"), 'text/csv')
            msg.send()