Implement OrdersView
authorTero Marttila <terom@fixme.fi>
Thu, 23 Dec 2010 17:38:34 +0200
changeset 13 cb18f86e38d9
parent 12 2d3fb967cd30
child 14 5b2cc88412f7
Implement OrdersView
static/style.css
static/tables.css
svv/controllers.py
svv/customers.py
svv/orders.py
--- a/static/style.css	Thu Dec 23 02:59:53 2010 +0200
+++ b/static/style.css	Thu Dec 23 17:38:34 2010 +0200
@@ -3,13 +3,26 @@
  */
 
 /* Links */
-a {
+a
+{
     color: black;
+}
+
+a:hover
+{
+
+}
+
+div#menu a,
+div#nav a
+{
     text-decoration: none;
     font-weight: bold;
 }
 
-a:hover {
+div#menu a:hover,
+div#nav a:hover
+{
     text-decoration: underline;
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/static/tables.css	Thu Dec 23 17:38:34 2010 +0200
@@ -0,0 +1,46 @@
+table
+{
+    width: 80%;
+
+    padding: 0px;
+
+    border-collapse: collapse;
+
+    font-size: small;
+
+    margin: 2em 1em;
+}
+
+thead tr
+{
+    background-color: #d8d8d8;
+}
+
+tr
+{
+    background-color: #fefefe;
+}
+
+tr.alternate
+{
+    background-color: #e8e8e8;
+}
+
+td, th
+{
+    border: thin solid #ffffff;
+
+    padding: 0.25em 1em;
+}
+
+td a,
+th a
+{
+    display: block;
+}
+
+td.row-header
+{
+    text-align: right;
+    font-weight: bold;
+}
--- a/svv/controllers.py	Thu Dec 23 02:59:53 2010 +0200
+++ b/svv/controllers.py	Thu Dec 23 17:38:34 2010 +0200
@@ -88,6 +88,8 @@
                 "/static/layout.css", 
                 "/static/style.css", 
                 "/static/forms.css",
+                "/static/tables.css",
+
                 "/static/treelist.css",
 
                 "/static/jquery-ui/jquery-ui.css",
--- a/svv/customers.py	Thu Dec 23 02:59:53 2010 +0200
+++ b/svv/customers.py	Thu Dec 23 17:38:34 2010 +0200
@@ -30,36 +30,44 @@
             tags.p(u"Tunnen %d asiakasta ja %d yhteyshenkilöä." % (len(customers), len(contacts))),
 
             tags.table(
-                tags.tr(
-                    tags.th("ID #"),
-                    tags.th("Nimi"),
+                tags.thead(
+                    tags.tr(
+                        tags.th("ID #"),
+                        tags.th("Nimi"),
+                    ),
                 ),
-                (tags.tr(
-                    tags.td(tags.a(href=self.url_for(CustomerView, id=customer[db.customers.c.id]))('#%d' % customer[db.customers.c.id])),
-                    tags.td(tags.a(href=self.url_for(CustomerView, id=customer[db.customers.c.id]))(customer[db.customers.c.name])),
-                ) for customer in customers)
+                tags.tbody(
+                    tags.tr(class_=('alternate' if idx % 2 else None))(
+                        tags.td(tags.a(href=self.url_for(CustomerView, id=row[db.customers.c.id]))('#%d' % row[db.customers.c.id])),
+                        tags.td(tags.a(href=self.url_for(CustomerView, id=row[db.customers.c.id]))(row[db.customers.c.name])),
+                    ) for idx, row in enumerate(customers)
+                ),
             ),
 
             tags.table(
-                tags.tr(
-                    tags.th("ID #"),
-                    tags.th("Asiakas"),
-                    tags.th("Nimi"),
-                    tags.th("Puhelinnumero"),
-                    tags.th(u"Sähköpostiosoite"),
+                tags.thead(
+                    tags.tr(
+                        tags.th("ID #"),
+                        tags.th("Asiakas"),
+                        tags.th("Nimi"),
+                        tags.th("Puhelinnumero"),
+                        tags.th(u"Sähköpostiosoite"),
+                    ),
                 ),
-                (tags.tr(
-                    tags.td(tags.a(href='#')('#%d' % row[db.contacts.c.id])),
-                    tags.td(
-                        tags.a(href=self.url_for(CustomerView, id=row[db.customers.c.id]))(row[db.customers.c.name])
-                            if row[db.customers.c.id] else " "
-                    ),
-                    tags.td(
-                        tags.a(href='#')(row[db.contacts.c.name]),
-                    ),
-                    tags.td(row[db.contacts.c.phone]),
-                    tags.td(row[db.contacts.c.email]),
-                ) for row in contacts)
+                tags.tbody(
+                    tags.tr(class_=('alternate' if idx % 2 else None))(
+                        tags.td(tags.a(href='#')('#%d' % row[db.contacts.c.id])),
+                        tags.td(
+                            tags.a(href=self.url_for(CustomerView, id=row[db.customers.c.id]))(row[db.customers.c.name])
+                                if row[db.customers.c.id] else " "
+                        ),
+                        tags.td(
+                            tags.a(href='#')(row[db.contacts.c.name]),
+                        ),
+                        tags.td(row[db.contacts.c.phone]),
+                        tags.td(row[db.contacts.c.email]),
+                    ) for idx, row in enumerate(contacts)
+                ),
             ),
         )
 
--- a/svv/orders.py	Thu Dec 23 02:59:53 2010 +0200
+++ b/svv/orders.py	Thu Dec 23 17:38:34 2010 +0200
@@ -346,6 +346,8 @@
     def load (self, id) :
         """
             Load our field values from the database using the given id
+
+            XXX: move SQL stuff out into an OrderModel class or something
         """
         
         # query tables from db
@@ -605,8 +607,145 @@
 
 
 class OrdersView (PageHandler) :
+    """
+        Render list of orders, so as to access upcoming orders, current orders, and old orders..
+    """
+
+    def build_orders_list (self, order_by=(db.orders.c.event_start)) :
+        """
+            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
+        """
+        
+        sql_from = db.orders.join(db.customers).join(db.contacts, (db.contacts.c.id == db.orders.c.contact))
+        sql = db.select(
+            [
+                db.orders.c.id,
+                db.orders.c.customer,
+                db.customers.c.name,
+                db.orders.c.event_name,
+                db.orders.c.contact,
+                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,
+        )
+
+        return self.app.query(sql)
+    
+    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.stftime("%m.%Y"))
+        
+        else : # start.date() == end.date()
+            # single day
+            date = start.strftime("%d.%m.%Y")
+
+        # time
+        if start.minute == 0 and end.minute == 0 :
+            time = "%s-%s" % (start.strftime("%H"), end.startfime("%H"))
+
+        else :
+            time = "%s-%s" % (start.strftime("%H:%M"), end.strftime("%H:%M"))
+
+        # format
+        return "%s %s" % (date, time)
+
+    def render_orders_list (self, sort) :
+        """
+            Render HTML for sorted order list
+        """
+        
+        # XXX: still broken
+        from svv import urls
+        
+        # columns for sorting
+        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),
+        )
+
+
+        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)
+
+        return tags.table(cellspacing="0")(
+            tags.thead(
+                tags.tr(
+                    tags.th(
+                        tags.a(href="?sort=" + name)(title)
+                            if sort != col else
+                        (title)
+                    ) for name, title, col in columns
+                ),
+            ),
+            tags.tbody(
+                tags.tr(class_=('alternate' if idx % 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])
+                        )
+                    ),
+
+                    # Tilaaja
+                    tags.td(
+                        tags.a(href=self.url_for(urls.CustomerView, id=row[db.orders.c.customer]))(
+                            row[db.customers.c.name]
+                        ) if row[db.orders.c.customer] else "-"
+                    ),
+
+                    # Tapahtuma
+                    tags.td(
+                        tags.a(href=self.url_for(OrderView, id=row[db.orders.c.id]))(
+                            row[db.orders.c.event_name]
+                        )
+                    ),
+
+                    # Yhteyshenkilö
+                    tags.td(
+                        tags.a(href='#')(
+                            row[db.contacts.c.name]
+                        ) if row[db.orders.c.contact] else "-"
+                    ),
+
+                    # Ajankohta
+                    tags.td(
+                        self.render_event_time(row[db.orders.c.event_start], row[db.orders.c.event_end])
+                    ),
+                ) for idx, row in enumerate(orders)
+            )
+        )
+
     def render_content (self) :
-        return tags.h1("Orders list")
+        return (
+            tags.h1("Tilauslista"),
+
+            self.render_orders_list(self.request.args.get('sort')),
+        )
 
 class OrderView (PageHandler) :
     """