Use Order model for OrdersView table
authorTero Marttila <terom@fixme.fi>
Fri, 31 Dec 2010 02:26:52 +0200
changeset 27 1cb8b78101f9
parent 26 04bf578d358a
child 28 1bfe14d74dcf
Use Order model for OrdersView table
svv/database.py
svv/orders.py
--- a/svv/database.py	Fri Dec 31 02:26:32 2010 +0200
+++ b/svv/database.py	Fri Dec 31 02:26:52 2010 +0200
@@ -6,19 +6,25 @@
 
 from sqlalchemy import *
 
+#
+# Object Mapping
+# (used externally)
+#
+
 # for ORM definitions; outside of this module
-from sqlalchemy.orm import mapper, sessionmaker
+from sqlalchemy.orm import mapper, sessionmaker, relation
+from sqlalchemy.orm import eagerload, eagerload_all
 
 # used by Application.session
 session_factory = sessionmaker()
 
+#
+# Table Schema
+#
+
 # our schema
 schema = MetaData()
 
-#
-# tables
-#
-
 # customers are organizations or natural persons who are serving as the renting side of an order
 customers = Table('customers', schema,
         Column('id', Integer, primary_key=True),
--- a/svv/orders.py	Fri Dec 31 02:26:32 2010 +0200
+++ b/svv/orders.py	Fri Dec 31 02:26:52 2010 +0200
@@ -72,11 +72,43 @@
         # default to tomorrow afternoon
         self.event_start = datetime.datetime.combine(tomorrow, datetime.time(16, 00))
         self.event_end = None   # determined by UI behaviour
+            
+
+    def format_event_time (self) :
+        """
+            Return a concise string describing the event's approximate time span.
+        """
+
+        start = self.event_start
+        end = self.event_end
+
+        # different days
+        if (start.year, start.month) != (end.year, end.month) :
+            # the full dates
+            date = "%s - %s" % (start.strftime("%d.%m.%Y"), end.strftime("%d.%m.%Y"))
+
+        elif (start.day != end.day) :
+            # day range
+            date = "%s-%s.%s" % (start.strftime("%d"), end.strftime("%d"), start.strftime("%m.%Y"))
         
+        else : # start.date() == end.date()
+            # single day
+            date = start.strftime("%d.%m.%Y")
+
+        # time
+        time = "%s-%s" % (start.strftime("%H:%M"), end.strftime("%H:%M"))
+
+        # format
+        return "%s %s" % (date, time)
+
+
 # bind against database schema
 db.mapper(Customer, db.customers)
 db.mapper(Contact, db.contacts)
-db.mapper(Order, db.orders)
+db.mapper(Order, db.orders, properties=dict(
+    customer    = db.relation(Customer),
+    contact     = db.relation(Contact),
+))
 
 class FormError (Exception) :
     """
@@ -858,34 +890,25 @@
 
 class OrdersView (PageHandler) :
     """
-        Render list of orders, so as to access upcoming orders, current orders, and old orders..
+        Render overview list of all orders in database.
+
+        Currently divided into current/upcoming/past listings
     """
 
-    def build_orders_list (self, order_by=(db.orders.c.event_start)) :
+    def process (self) :
         """
-            Build summary list of orders, returning a series of 
-                (order_id, customer_id, customer_name, event_name, contact_id, contact_name, event_start, event_end)
-            tuples, ordered by event_start, per default
+            prepare
         """
         
-        sql_from = db.orders.join(db.customers).join(db.contacts, (db.contacts.c.id == db.orders.c.contact_id))
-        sql = db.select(
-            [
-                db.orders.c.id,
-                db.orders.c.customer_id,
-                db.customers.c.name,
-                db.orders.c.event_name,
-                db.orders.c.contact_id,
-                db.contacts.c.name,
-                db.orders.c.event_start,
-                db.orders.c.event_end,
-            ],
-            from_obj = sql_from,
-            order_by = order_by,
-            use_labels = True,
-        )
+        # database sesssion
+        self.session = self.app.session()
 
-        return self.app.query(sql)
+    def build_orders_list (self, order_by=(Order.event_start)) :
+        """
+            Build summary list of orders, returning a series of Order objects, ordered by event_start, per default.
+        """
+
+        return self.session.query(Order).options(db.eagerload(Order.customer), db.eagerload(Order.contact)).order_by(order_by).all()
     
     def group_orders_by_time (self, orders) :
         """
@@ -902,55 +925,42 @@
 
         today = datetime.date.today()
 
-        for row in orders :
-            if row[db.orders.c.event_end].date() < today :
-                past.append(row)
+        def _classify (order) :
+            """
+                Return list to append order to
+            """
 
-            elif row[db.orders.c.event_start].date() <= today :
-                current.append(row)
+            if order.event_end.date() < today :
+                return past
+
+            elif order.event_start.date() <= today :
+                return current
 
             else :
-                future.append(row)
+                return future
         
+        for order in orders :
+            # resolve list for order
+            category = _classify(order)
+
+            category.append(order)
+
         return past, current, future
 
-    def render_event_time (self, start, end) :
-        """
-            Render concise start - end description
-        """
-
-        # different days
-        if (start.year, start.month) != (end.year, end.month) :
-            # just the full dates
-            return "%s - %s" % (start.strftime("%d.%m.%Y"), end.strftime("%d.%m.%Y"))
-
-        elif (start.day != end.day) :
-            # day range
-            date = "%s-%s.%s" % (start.strftime("%d"), end.strftime("%d"), start.strftime("%m.%Y"))
-        
-        else : # start.date() == end.date()
-            # single day
-            date = start.strftime("%d.%m.%Y")
-
-        # time
-        time = "%s-%s" % (start.strftime("%H:%M"), end.strftime("%H:%M"))
-
-        # format
-        return "%s %s" % (date, time)
-
     # columns for sorting
+    # XXX: sorting not actually implemented...
     COLUMNS = (
-        ('order_id',        u"ID",              db.orders.c.id),
-        ('customer_name',   u"Tilaaja",         db.customers.c.name),
-        ('event_name',      u"Tapahtuma",       db.orders.c.event_name),
-        ('contact_name',    u"Yhteyshenkilö",   db.contacts.c.name),
-        ('event_start',     u"Ajankohta",       db.orders.c.event_start),
+        ('order_id',        u"ID",              Order.id),
+        ('customer_name',   u"Tilaaja",         Customer.name),
+        ('event_name',      u"Tapahtuma",       Order.event_name),
+        ('contact_name',    u"Yhteyshenkilö",   Contact.name),
+        ('event_start',     u"Ajankohta",       Order.event_start),
     )
 
 
     def render_orders_list_rows (self, orders) :
         """
-            Render HTML for each of the orders in the order list, inserting sub-captions for various months
+            Render HTML for each of the orders in the order list, inserting sub-captions when the month changes
         """
         
         # XXX: still broken
@@ -958,11 +968,13 @@
         
         # track each row's year/month
         last_date = None
+
+        # alternating rows
         row_counter = 0
 
-        for row in orders :
+        for order in orders :
             # this order's date - only consider the starting datetime
-            date = row[db.orders.c.event_start].date()
+            date = order.event_start.date()
             
             # month changed?
             if last_date and (date.year, date.month) != (last_date.year, last_date.month) :
@@ -983,35 +995,35 @@
             yield tags.tr(class_=('alternate' if row_counter % 2 else None))(
                 # Id
                 tags.td(class_='row-header')(
-                    tags.a(href=self.url_for(OrderView, id=row[db.orders.c.id]))(
-                        u"#%d" % (row[db.orders.c.id])
+                    tags.a(href=self.url_for(OrderView, id=order.id))(
+                        u"#%d" % (order.id)
                     )
                 ),
 
                 # Tilaaja
                 tags.td(
-                    tags.a(href=self.url_for(urls.CustomerView, id=row[db.orders.c.customer_id]))(
-                        row[db.customers.c.name]
-                    ) if row[db.orders.c.customer_id] else "-"
+                    tags.a(href=self.url_for(urls.CustomerView, id=order.customer.id))(
+                        order.customer.name
+                    ) if order.customer else "-"
                 ),
 
                 # Tapahtuma
                 tags.td(
-                    tags.a(href=self.url_for(OrderView, id=row[db.orders.c.id]))(
-                        row[db.orders.c.event_name]
+                    tags.a(href=self.url_for(OrderView, id=order.id))(
+                        order.event_name
                     )
                 ),
 
                 # Yhteyshenkilö
                 tags.td(
                     tags.a(href='#')(
-                        row[db.contacts.c.name]
-                    ) if row[db.orders.c.contact_id] else "-"
+                        order.contact.name
+                    ) if order.contact else "-"
                 ),
 
                 # Ajankohta
                 tags.td(
-                    self.render_event_time(row[db.orders.c.event_start], row[db.orders.c.event_end])
+                    order.format_event_time(),
                 ),
             )
 
@@ -1028,9 +1040,7 @@
             tags.thead(
                 tags.tr(
                     tags.th(
-                        tags.a(href="?sort=" + name)(title)
-                            if False else
-                        (title)
+                        title
                     ) for name, title, col in self.COLUMNS
                 ),
             ),
@@ -1041,18 +1051,6 @@
         )
 
     def render_content (self) :
-#        # sort criteria
-#        sort = self.request.args.get('sort')
-#
-#        if sort :
-#            sort_col = (dict((name, col) for name, title, col in columns).get(sort), db.orders.c.event_start)
-#
-#        else :
-#            sort = 'event_start'
-#            sort_col = db.orders.c.event_start
-#
-#        orders = self.build_orders_list(sort_col)
-
 
         # full order list
         orders_full = self.build_orders_list()