From 309edbdf6f806cad97bd45902f60eedaf5e91255 Mon Sep 17 00:00:00 2001 From: Brian Ndwiga Date: Wed, 1 Nov 2017 08:11:25 +0800 Subject: [PATCH 1/5] ps: forgot to add the invoice column header --- parkstay/reports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parkstay/reports.py b/parkstay/reports.py index 375f02cc67..f5766be9fe 100644 --- a/parkstay/reports.py +++ b/parkstay/reports.py @@ -49,7 +49,7 @@ def booking_refunds(start,end): cash.extend([x for x in CashTransaction.objects.filter(created__gte=start, created__lte=end,type='refund')]) strIO = StringIO() - fieldnames = ['Confirmation Number', 'Name', 'Type','Amount','Oracle Code','Date','Refunded By'] + fieldnames = ['Confirmation Number', 'Name', 'Type','Amount','Oracle Code','Date','Refunded By','Invoice'] writer = csv.writer(strIO) writer.writerow(fieldnames) From f1821a02e32ec3b5d263c8dc325efe7597384792 Mon Sep 17 00:00:00 2001 From: Brian Ndwiga Date: Thu, 2 Nov 2017 10:46:06 +0800 Subject: [PATCH 2/5] ps: add cancelation time to Booking --- .../0039_booking_cancelation_time.py | 20 +++++++++++++++++++ parkstay/models.py | 2 ++ 2 files changed, 22 insertions(+) create mode 100644 parkstay/migrations/0039_booking_cancelation_time.py diff --git a/parkstay/migrations/0039_booking_cancelation_time.py b/parkstay/migrations/0039_booking_cancelation_time.py new file mode 100644 index 0000000000..3cacad69d7 --- /dev/null +++ b/parkstay/migrations/0039_booking_cancelation_time.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.8 on 2017-11-02 02:45 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('parkstay', '0038_auto_20171019_1402'), + ] + + operations = [ + migrations.AddField( + model_name='booking', + name='cancelation_time', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/parkstay/models.py b/parkstay/models.py index f31e4cdeeb..c9841968cb 100644 --- a/parkstay/models.py +++ b/parkstay/models.py @@ -915,6 +915,7 @@ class Booking(models.Model): campground = models.ForeignKey('Campground', null=True) is_canceled = models.BooleanField(default=False) cancellation_reason = models.TextField(null=True,blank=True) + cancelation_time = models.DateTimeField(null=True,blank=True) confirmation_sent = models.BooleanField(default=False) created = models.DateTimeField(default=timezone.now) @@ -1133,6 +1134,7 @@ def cancelBooking(self,reason): raise ValidationError('You cannot cancel a booking past the departure date.') self.cancellation_reason = reason self.is_canceled = True + self.cancelation_time = timezone.now() self.campsites.all().delete() references = self.invoices.all().values('invoice_reference') for r in references: From 06c37e828db6984aacbba9a2e6da999baa5b0116 Mon Sep 17 00:00:00 2001 From: Brian Ndwiga Date: Thu, 2 Nov 2017 14:47:37 +0800 Subject: [PATCH 3/5] ps: prevent situations where users were trying to circumvent the payment process --- parkstay/views.py | 51 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/parkstay/views.py b/parkstay/views.py index 4a428a4935..2ad43f9132 100644 --- a/parkstay/views.py +++ b/parkstay/views.py @@ -1,4 +1,4 @@ - +import logging from django.db.models import Q from django.http import Http404, HttpResponse, JsonResponse from django.shortcuts import render, get_object_or_404, redirect @@ -29,6 +29,7 @@ ) from parkstay import emails from ledger.accounts.models import EmailUser, Address +from ledger.payments.models import Invoice from django_ical.views import ICalFeed from datetime import datetime, timedelta from decimal import * @@ -36,6 +37,8 @@ from parkstay.helpers import is_officer from parkstay import utils +logger = logging.getLogger('booking_checkout') + class CampsiteBookingSelector(TemplateView): template_name = 'ps/campsite_booking_selector.html' @@ -311,22 +314,38 @@ def get(self, request, *args, **kwargs): booking = utils.get_session_booking(request.session) invoice_ref = request.GET.get('invoice') - # FIXME: replace with server side notify_url callback - book_inv, created = BookingInvoice.objects.get_or_create(booking=booking, invoice_reference=invoice_ref) - - # set booking to be permanent fixture - booking.booking_type = 1 # internet booking - booking.expiry_time = None - booking.save() + try: + inv = Invoice.objects.get(reference=invoice_ref) + except Invoice.DoesNotExist: + logger.error('User {} with id {} tried making a booking with an incorrect invoice'.format(booking.customer.get_full_name(),booking.customer.id)) + return redirect('public_make_booking') - utils.delete_session_booking(request.session) - request.session['ps_last_booking'] = booking.id - - # send out the invoice before the confirmation is sent - emails.send_booking_invoice(booking) - # for fully paid bookings, fire off confirmation email - if booking.paid: - emails.send_booking_confirmation(booking,request) + if inv.system not in ['0019']: + logger.error('User {} with id {} tried making a booking with an invoice from another system with reference number {}'.format(booking.customer.get_full_name(),booking.customer.id,inv.reference)) + return redirect('public_make_booking') + + try: + b = BookingInvoice.objects.get(invoice_reference=invoice_ref) + logger.error('User {} with id {} tried making a booking with an already used invoice with reference number {}'.format(booking.customer.get_full_name(),booking.customer.id,inv.reference)) + return redirect('public_make_booking') + except BookingInvoice.DoesNotExist: + + # FIXME: replace with server side notify_url callback + book_inv, created = BookingInvoice.objects.get_or_create(booking=booking, invoice_reference=invoice_ref) + + # set booking to be permanent fixture + booking.booking_type = 1 # internet booking + booking.expiry_time = None + booking.save() + + utils.delete_session_booking(request.session) + request.session['ps_last_booking'] = booking.id + + # send out the invoice before the confirmation is sent + emails.send_booking_invoice(booking) + # for fully paid bookings, fire off confirmation email + if booking.paid: + emails.send_booking_confirmation(booking,request) except Exception as e: if ('ps_last_booking' in request.session) and Booking.objects.filter(id=request.session['ps_last_booking']).exists(): From 7d19991892c33260c5185bd94990800fa48105fc Mon Sep 17 00:00:00 2001 From: Brian Ndwiga Date: Thu, 2 Nov 2017 14:49:08 +0800 Subject: [PATCH 4/5] ps: additional logging for users trying to circumvent the checkout process --- parkstay/settings.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/parkstay/settings.py b/parkstay/settings.py index ac561585b6..63d9910286 100755 --- a/parkstay/settings.py +++ b/parkstay/settings.py @@ -78,6 +78,19 @@ 'parkstay.cron.OracleIntegrationCronJob', ] +# Additional logging for parkstay +LOGGING['handlers']['booking_checkout'] = { + 'level': 'INFO', + 'class': 'logging.handlers.RotatingFileHandler', + 'filename': os.path.join(BASE_DIR, 'logs', 'parkstay_booking_checkout.log'), + 'formatter': 'verbose', + 'maxBytes': 5242880 + } +LOGGING['loggers']['booking_checkout'] = { + 'handlers': ['booking_checkout'], + 'level': 'INFO' + } + CAMPGROUNDS_EMAIL = env('CAMPGROUNDS_EMAIL','parkstaybookings@dbca.wa.gov.au') EXPLORE_PARKS_URL = env('EXPLORE_PARKS_URL','https://parks-oim.dpaw.wa.gov.au') PARKSTAY_EXTERNAL_URL = env('PARKSTAY_EXTERNAL_URL','https://parkstay.dbca.wa.gov.au') From a551580b9f97c34bfb713b4a91174cc6cd05ac29 Mon Sep 17 00:00:00 2001 From: Brian Ndwiga Date: Thu, 2 Nov 2017 15:14:39 +0800 Subject: [PATCH 5/5] ps: update to prevent situations where users were trying to circumvent the payment process --- parkstay/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/parkstay/views.py b/parkstay/views.py index 2ad43f9132..cc884c4e3d 100644 --- a/parkstay/views.py +++ b/parkstay/views.py @@ -317,16 +317,16 @@ def get(self, request, *args, **kwargs): try: inv = Invoice.objects.get(reference=invoice_ref) except Invoice.DoesNotExist: - logger.error('User {} with id {} tried making a booking with an incorrect invoice'.format(booking.customer.get_full_name(),booking.customer.id)) + logger.error('{} tried making a booking with an incorrect invoice'.format('User {} with id {}'.format(booking.customer.get_full_name(),booking.customer.id) if booking.customer else 'An anonymous user')) return redirect('public_make_booking') if inv.system not in ['0019']: - logger.error('User {} with id {} tried making a booking with an invoice from another system with reference number {}'.format(booking.customer.get_full_name(),booking.customer.id,inv.reference)) + logger.error('{} tried making a booking with an invoice from another system with reference number {}'.format('User {} with id {}'.format(booking.customer.get_full_name(),booking.customer.id) if booking.customer else 'An anonymous user',inv.reference)) return redirect('public_make_booking') try: b = BookingInvoice.objects.get(invoice_reference=invoice_ref) - logger.error('User {} with id {} tried making a booking with an already used invoice with reference number {}'.format(booking.customer.get_full_name(),booking.customer.id,inv.reference)) + logger.error('{} tried making a booking with an already used invoice with reference number {}'.format('User {} with id {}'.format(booking.customer.get_full_name(),booking.customer.id) if booking.customer else 'An anonymous user',inv.reference)) return redirect('public_make_booking') except BookingInvoice.DoesNotExist: