summaryrefslogtreecommitdiff
path: root/postgresqleu/util
diff options
context:
space:
mode:
Diffstat (limited to 'postgresqleu/util')
-rw-r--r--postgresqleu/util/backendforms.py4
-rw-r--r--postgresqleu/util/db.py52
-rwxr-xr-xpostgresqleu/util/misc/baseinvoice.py11
-rw-r--r--postgresqleu/util/time.py9
4 files changed, 59 insertions, 17 deletions
diff --git a/postgresqleu/util/backendforms.py b/postgresqleu/util/backendforms.py
index 069061eb..b285d1bf 100644
--- a/postgresqleu/util/backendforms.py
+++ b/postgresqleu/util/backendforms.py
@@ -86,8 +86,8 @@ class BackendForm(ConcurrentProtectedModelForm):
if self.conference:
if isinstance(v, django.forms.fields.DateTimeField) and k not in self.exclude_date_validators:
v.validators.extend([
- MinValueValidator(datetime.datetime.combine(self.conference.startdate, datetime.time(0, 0, 0))),
- MaxValueValidator(datetime.datetime.combine(self.conference.enddate + datetime.timedelta(days=1), datetime.time(0, 0, 0))),
+ MinValueValidator(conference.localize_datetime(datetime.datetime.combine(self.conference.startdate, datetime.time(0, 0, 0)))),
+ MaxValueValidator(conference.localize_datetime(datetime.datetime.combine(self.conference.enddate + datetime.timedelta(days=1), datetime.time(0, 0, 0)))),
])
elif isinstance(v, django.forms.fields.DateField) and k not in self.exclude_date_validators:
v.validators.extend([
diff --git a/postgresqleu/util/db.py b/postgresqleu/util/db.py
index c9d8f5c3..e0a07381 100644
--- a/postgresqleu/util/db.py
+++ b/postgresqleu/util/db.py
@@ -1,33 +1,43 @@
from django.db import connection
+from django.conf import settings
import collections
+from psycopg2.tz import LocalTimezone
-def exec_no_result(query, params=None):
+
+def get_native_cursor():
+ # Remove djangos dumb prevention of us to change the timezone
curs = connection.cursor()
+ curs.cursor.tzinfo_factory = LocalTimezone
+ return curs
+
+
+def exec_no_result(query, params=None):
+ curs = get_native_cursor()
curs.execute(query, params)
def exec_to_list(query, params=None):
- curs = connection.cursor()
+ curs = get_native_cursor()
curs.execute(query, params)
return curs.fetchall()
def exec_to_single_list(query, params=None):
- curs = connection.cursor()
+ curs = get_native_cursor()
curs.execute(query, params)
return [r[0] for r in curs.fetchall()]
def exec_to_dict(query, params=None):
- curs = connection.cursor()
+ curs = get_native_cursor()
curs.execute(query, params)
columns = [col[0] for col in curs.description]
return [dict(list(zip(columns, row)))for row in curs.fetchall()]
def exec_to_scalar(query, params=None):
- curs = connection.cursor()
+ curs = get_native_cursor()
curs.execute(query, params)
r = curs.fetchone()
if r:
@@ -44,20 +54,20 @@ def conditional_exec_to_scalar(condition, query, params=None):
def exec_to_keyed_dict(query, params=None):
- curs = connection.cursor()
+ curs = get_native_cursor()
curs.execute(query, params)
columns = [col[0] for col in curs.description]
return {r[columns[0]]: r for r in (dict(list(zip(columns, row)))for row in curs.fetchall())}
def exec_to_keyed_scalar(query, params=None):
- curs = connection.cursor()
+ curs = get_native_cursor()
curs.execute(query, params)
return dict(curs.fetchall())
def exec_to_grouped_dict(query, params=None):
- curs = connection.cursor()
+ curs = get_native_cursor()
curs.execute(query, params)
columns = [col[0] for col in curs.description[1:]]
full = collections.OrderedDict()
@@ -73,3 +83,29 @@ def exec_to_grouped_dict(query, params=None):
if last:
full[last] = curr
return full
+
+
+class ensure_conference_timezone():
+ """
+ This context handler will set the timezone *in PostgreSQL* to the one from the
+ specified conference, and reset it back to UTC when it's done. During this time,
+ calls from django's own ORM will fail, it's intended only to wrap native SQL
+ querying that needs to use the appropriate timezone.
+ If None is specified as the conference, set the timezone to the global one for
+ the installation (otherwise the default is UTC).
+ """
+ def __init__(self, conference):
+ if conference is None:
+ self.tzname = settings.TIME_ZONE
+ else:
+ self.tzname = conference.tzname
+
+ def __enter__(self):
+ c = connection.cursor()
+ c.execute("SET TIMEZONE=%(tz)s", {
+ 'tz': self.tzname,
+ })
+ return c
+
+ def __exit__(self, *args):
+ connection.cursor().execute("SET TIMEZONE='UTC'")
diff --git a/postgresqleu/util/misc/baseinvoice.py b/postgresqleu/util/misc/baseinvoice.py
index 834f37bc..c36a493d 100755
--- a/postgresqleu/util/misc/baseinvoice.py
+++ b/postgresqleu/util/misc/baseinvoice.py
@@ -15,6 +15,7 @@ from reportlab.pdfbase.pdfmetrics import registerFont, getFont
from reportlab.pdfbase.ttfonts import TTFont
from io import BytesIO
+from django.utils import timezone
from django.conf import settings
from postgresqleu.util.reporttools import cm
@@ -156,7 +157,7 @@ class BaseInvoice(PDFBase):
if self.receipt:
self.canvas.drawCentredString(cm(10.5), cm(18.5), "Receipt for invoice number %s%s" % (self.invoicenum, suffix))
else:
- self.canvas.drawCentredString(cm(10.5), cm(18.5), "Invoice number %s - %s%s" % (self.invoicenum, self.invoicedate.strftime("%B %d, %Y"), suffix))
+ self.canvas.drawCentredString(cm(10.5), cm(18.5), "Invoice number %s - %s%s" % (self.invoicenum, timezone.localtime(self.invoicedate).strftime("%B %d, %Y"), suffix))
self.canvas.setFont('DejaVu Serif Bold', 10)
if self.receipt:
self.canvas.drawString(cm(15), cm(28), "Receipt #%s" % self.invoicenum)
@@ -166,7 +167,7 @@ class BaseInvoice(PDFBase):
self.canvas.setFont('DejaVu Serif Bold', 8)
self.canvas.drawString(cm(15), cm(27.5), "Payment ref: %s" % self.paymentref)
else:
- self.canvas.drawCentredString(cm(10.5), cm(18.5), "Receipt - %s%s" % (self.invoicedate.strftime("%B %d, %Y"), suffix))
+ self.canvas.drawCentredString(cm(10.5), cm(18.5), "Receipt - %s%s" % (timezone.localtime(self.invoicedate).strftime("%B %d, %Y"), suffix))
if pagenum == 0:
firstcol = "Item"
@@ -268,9 +269,9 @@ class BaseInvoice(PDFBase):
self.canvas.setFont('DejaVu Serif Bold', 10)
if self.receipt:
- self.canvas.drawCentredString(cm(10.5), cm(17.3) - h, "This invoice was paid %s" % self.duedate.strftime("%B %d, %Y"))
+ self.canvas.drawCentredString(cm(10.5), cm(17.3) - h, "This invoice was paid %s" % timezone.localtime(self.duedate).strftime("%B %d, %Y"))
else:
- self.canvas.drawCentredString(cm(10.5), cm(17.3) - h, "This invoice is due: %s" % self.duedate.strftime("%B %d, %Y"))
+ self.canvas.drawCentredString(cm(10.5), cm(17.3) - h, "This invoice is due: %s" % timezone.localtime(self.duedate).strftime("%B %d, %Y"))
if self.bankinfo:
self.canvas.setFont('DejaVu Serif', 8)
self.canvas.drawCentredString(cm(10.5), cm(16.8) - h, "If paying with bank transfer, use payment reference %s" % self.paymentref)
@@ -431,7 +432,7 @@ class BaseRefund(PDFBase):
w, h = t.wrapOn(self.canvas, cm(10), cm(10))
t.drawOn(self.canvas, (self.canvas._pagesize[0] - w) // 2, cm(17) - h * 2 - cm(1) - extraofs)
- self.canvas.drawCentredString(cm(10.5), cm(16.3) - h * 2 - cm(2) - extraofs, "This refund was issued {0}".format(self.refunddate.strftime("%B %d, %Y")))
+ self.canvas.drawCentredString(cm(10.5), cm(16.3) - h * 2 - cm(2) - extraofs, "This refund was issued {0}".format(timezone.localtime(self.refunddate).strftime("%B %d, %Y")))
if self.paymentmethod:
self.canvas.drawCentredString(cm(10.5), cm(16.3) - h * 2 - cm(3) - extraofs, "Refunded to the original form of payment: {0}.".format(self.paymentmethod))
diff --git a/postgresqleu/util/time.py b/postgresqleu/util/time.py
index 76567187..eab66cab 100644
--- a/postgresqleu/util/time.py
+++ b/postgresqleu/util/time.py
@@ -1,9 +1,14 @@
from django.utils import timezone
+# Return a date represeting today in the timezone of the currently
+# selected conference. If no conference is selected, the date will
+# be returned in the global default timezone.
def today_conference():
- return timezone.now().date()
+ return timezone.localdate(timezone.now())
+# Return a date represeting today ihn the global default timezone
+# (making it suitable for everything that is not conference-related).
def today_global():
- return timezone.now().date()
+ return timezone.localdate(timezone.now(), timezone.get_default_timezone())