Index: main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 9685)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 9687)
@@ -1037,11 +1037,4 @@
             'b':level_title})
 
-    @property
-    def total_credits(self):
-        total_credits = 0
-        for key, val in self.context.items():
-            total_credits += val.credits
-        return total_credits
-
 class ExportPDFCourseRegistrationSlipPage(UtilityView, grok.View):
     """Deliver a PDF slip of the context.
@@ -2213,11 +2206,4 @@
 
     @property
-    def total_credits(self):
-        total_credits = 0
-        for key, val in self.context.items():
-            total_credits += val.credits
-        return total_credits
-
-    @property
     def translated_values(self):
         return translated_values(self)
@@ -2263,5 +2249,5 @@
             self.redirect(self.url(self.context))
             return
-        if self.total_credits > self.max_credits:
+        if self.context.total_credits > self.max_credits:
             self.flash(_('Maximum credits of ${a} exceeded.',
                 mapping = {'a':self.max_credits}))
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/studyleveleditpage.pt
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/studyleveleditpage.pt	(revision 9685)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/studyleveleditpage.pt	(revision 9687)
@@ -5,5 +5,6 @@
     Course Tickets
     (Total Credits:
-    <span i18n:name="total_credits" tal:replace="view/total_credits">TOTAL</span>)
+    <span i18n:name="total_credits"
+      tal:replace="view/context/total_credits">TOTAL</span>)
   </h3>
   <table class="display dataTableManage">
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/studylevelpage.pt
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/studylevelpage.pt	(revision 9685)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/studylevelpage.pt	(revision 9687)
@@ -20,5 +20,13 @@
       </td>
       <td>
-        <span tal:replace="view/total_credits">TOTAL</span>
+        <span tal:replace="view/context/total_credits">26</span>
+      </td>
+    </tr>
+    <tr>
+      <td i18n:translate="">
+        Momentary GPA:
+      </td>
+      <td>
+        <span tal:replace="python: '%4.2f' % view.context.gpa">2.33</span>
       </td>
     </tr>
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py	(revision 9685)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py	(revision 9687)
@@ -481,4 +481,5 @@
     is_current_level = Attribute('Is this level the current level of the student?')
     total_credits = Attribute('Total of all ticket credits in this study level.')
+    gpa = Attribute('Grade point average in this study level.')
 
     level_session = schema.Choice(
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/studylevel.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/studylevel.py	(revision 9685)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/studylevel.py	(revision 9687)
@@ -81,4 +81,16 @@
 
     @property
+    def gpa(self):
+        gpa = 0
+        credits_counted = 0
+        for ticket in self.values():
+            if ticket.score:
+                credits_counted += ticket.credits
+                gpa += ticket.credits * ticket.weight
+        if credits_counted:
+            gpa = float(gpa)/credits_counted
+        return gpa
+
+    @property
     def is_current_level(self):
         try:
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 9685)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 9687)
@@ -765,4 +765,8 @@
         self.assertEqual(self.student['studycourse']['100']['COURSE1'].grade, 'C')
         self.assertEqual(self.student['studycourse']['100']['COURSE1'].weight, 3)
+        # GPA has been properly calculated and is shown on the page
+        self.browser.open(self.student_path + '/studycourse/100')
+        self.assertTrue('3.00' in self.browser.contents)
+        self.assertEqual(self.student['studycourse']['100'].gpa, 3.0)
         # Carry-over courses will be collected when next level is created
         self.browser.open(self.student_path + '/studycourse/manage')
