[med-svn] [openmolar] 09/17: New upstream version 1.0.15-gd81f9e5

Andreas Tille tille at debian.org
Sat Dec 17 19:03:26 UTC 2016


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository openmolar.

commit f7ad827ab53950d21f2355d188b4a0e693958aeb
Author: Andreas Tille <tille at debian.org>
Date:   Sat Dec 17 18:59:49 2016 +0100

    New upstream version 1.0.15-gd81f9e5
---
 MANIFEST                                           |   15 +-
 PKG-INFO                                           |    2 +-
 src/openmolar/__init__.py                          |   13 +-
 src/openmolar/create_db.py                         |   97 +-
 src/openmolar/dbtools/appointments.py              |   19 +-
 src/openmolar/dbtools/db_settings.py               |    7 +
 .../{settings/version.py => dbtools/locations.py}  |   53 +-
 src/openmolar/dbtools/patient_write_changes.py     |    5 +-
 src/openmolar/dbtools/search.py                    |   75 +-
 src/openmolar/dbtools/writeNewPatient.py           |   61 +-
 src/openmolar/ptModules/patientDetails.py          |    5 +-
 src/openmolar/qt-designer/main.ui                  |  402 +++--
 src/openmolar/qt4gui/contract_gui_module.py        |   21 +-
 .../qt4gui/customwidgets/appointmentwidget.py      |   38 +-
 .../qt4gui/dialogs/advanced_names_dialog.py        |  276 +++
 .../dialogs/advanced_record_management_dialog.py   |    1 +
 src/openmolar/qt4gui/dialogs/base_dialogs.py       |    2 +-
 src/openmolar/qt4gui/dialogs/dialog_collection.py  |    6 +
 src/openmolar/qt4gui/dialogs/first_run_dialog.py   |  500 ++++--
 src/openmolar/qt4gui/dialogs/newCourse.py          |    2 +-
 .../qt4gui/dialogs/patient_location_dialog.py      |  143 ++
 src/openmolar/qt4gui/diary_widget.py               |    5 +
 src/openmolar/qt4gui/forum_widget.py               |   72 +-
 src/openmolar/qt4gui/maingui.py                    |   94 +-
 src/openmolar/qt4gui/schema_updater.py             |    2 +
 src/openmolar/resources/demo_data.sql              |  145 ++
 src/openmolar/resources/hdp.png                    |  Bin 23276 -> 0 bytes
 src/openmolar/resources/hdp_maintenance.png        |  Bin 0 -> 11730 bytes
 .../resources/{schema.sql => minimal_data.sql}     | 1763 +-------------------
 src/openmolar/resources/resources.qrc              |    1 -
 src/openmolar/resources/schema.sql                 |  591 +------
 src/openmolar/resources/triggers.sql               |   94 ++
 src/openmolar/schema_upgrades/schema3_5to3_6.py    |  110 ++
 .../schema3_6to3_7.py}                             |  106 +-
 src/openmolar/settings/fee_tables.py               |   15 +-
 src/openmolar/settings/localsettings.py            |   19 +-
 src/openmolar/settings/version.py                  |    2 +-
 37 files changed, 1996 insertions(+), 2766 deletions(-)

diff --git a/MANIFEST b/MANIFEST
index ac21928..eb60b09 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -30,10 +30,12 @@ setup.py
 /home/neil/openmolar/openmolar1/src/openmolar/locale/tr.po
 /home/neil/openmolar/openmolar1/src/openmolar/resources/appointment_shortcuts.xml
 /home/neil/openmolar/openmolar1/src/openmolar/resources/appt_ov.png
-/home/neil/openmolar/openmolar1/src/openmolar/resources/hdp.png
+/home/neil/openmolar/openmolar1/src/openmolar/resources/demo_data.sql
+/home/neil/openmolar/openmolar1/src/openmolar/resources/hdp_maintenance.png
 /home/neil/openmolar/openmolar1/src/openmolar/resources/hdp_small.png
 /home/neil/openmolar/openmolar1/src/openmolar/resources/logo.png
 /home/neil/openmolar/openmolar1/src/openmolar/resources/logo1.png
+/home/neil/openmolar/openmolar1/src/openmolar/resources/minimal_data.sql
 /home/neil/openmolar/openmolar1/src/openmolar/resources/newlogo.png
 /home/neil/openmolar/openmolar1/src/openmolar/resources/newlogo_launchpadSize.png
 /home/neil/openmolar/openmolar1/src/openmolar/resources/nhs_scot.png
@@ -42,6 +44,7 @@ setup.py
 /home/neil/openmolar/openmolar1/src/openmolar/resources/resources.qrc
 /home/neil/openmolar/openmolar1/src/openmolar/resources/schema.sql
 /home/neil/openmolar/openmolar1/src/openmolar/resources/style.css
+/home/neil/openmolar/openmolar1/src/openmolar/resources/triggers.sql
 /home/neil/openmolar/openmolar1/src/openmolar/resources/win_install_banner.bmp
 /home/neil/openmolar/openmolar1/src/openmolar/resources/win_install_dialog.bmp
 /home/neil/openmolar/openmolar1/src/openmolar/resources/feescales/example_feescale.xml
@@ -167,6 +170,7 @@ src/openmolar/dbtools/estimatesHistory.py
 src/openmolar/dbtools/families.py
 src/openmolar/dbtools/feescales.py
 src/openmolar/dbtools/forum.py
+src/openmolar/dbtools/locations.py
 src/openmolar/dbtools/medform_check.py
 src/openmolar/dbtools/medhist.py
 src/openmolar/dbtools/memos.py
@@ -297,6 +301,7 @@ src/openmolar/qt4gui/dialogs/add_clinician_dialog.py
 src/openmolar/qt4gui/dialogs/add_treatment_dialog.py
 src/openmolar/qt4gui/dialogs/add_user_dialog.py
 src/openmolar/qt4gui/dialogs/address_match_dialog.py
+src/openmolar/qt4gui/dialogs/advanced_names_dialog.py
 src/openmolar/qt4gui/dialogs/advanced_record_management_dialog.py
 src/openmolar/qt4gui/dialogs/advanced_tx_planning_dialog.py
 src/openmolar/qt4gui/dialogs/alterAday.py
@@ -364,6 +369,7 @@ src/openmolar/qt4gui/dialogs/new_bridge_dialog.py
 src/openmolar/qt4gui/dialogs/new_denture_dialog.py
 src/openmolar/qt4gui/dialogs/nhs_forms_config_dialog.py
 src/openmolar/qt4gui/dialogs/other_treatment_dialog.py
+src/openmolar/qt4gui/dialogs/patient_location_dialog.py
 src/openmolar/qt4gui/dialogs/payment_dialog.py
 src/openmolar/qt4gui/dialogs/permissions.py
 src/openmolar/qt4gui/dialogs/post_choice_dialog.py
@@ -420,10 +426,12 @@ src/openmolar/qt4gui/printing/gp17/gp17v1_back.py
 src/openmolar/qt4gui/printing/gp17/gp17v1_front.py
 src/openmolar/resources/appointment_shortcuts.xml
 src/openmolar/resources/appt_ov.png
-src/openmolar/resources/hdp.png
+src/openmolar/resources/demo_data.sql
+src/openmolar/resources/hdp_maintenance.png
 src/openmolar/resources/hdp_small.png
 src/openmolar/resources/logo.png
 src/openmolar/resources/logo1.png
+src/openmolar/resources/minimal_data.sql
 src/openmolar/resources/newlogo.png
 src/openmolar/resources/newlogo_launchpadSize.png
 src/openmolar/resources/nhs_scot.png
@@ -432,6 +440,7 @@ src/openmolar/resources/private.png
 src/openmolar/resources/resources.qrc
 src/openmolar/resources/schema.sql
 src/openmolar/resources/style.css
+src/openmolar/resources/triggers.sql
 src/openmolar/resources/feescales/example_feescale.xml
 src/openmolar/resources/feescales/feescale_schema.xsd
 src/openmolar/resources/gp17/back.jpg
@@ -550,6 +559,8 @@ src/openmolar/schema_upgrades/schema3_1to3_2.py
 src/openmolar/schema_upgrades/schema3_2to3_3.py
 src/openmolar/schema_upgrades/schema3_3to3_4.py
 src/openmolar/schema_upgrades/schema3_4to3_5.py
+src/openmolar/schema_upgrades/schema3_5to3_6.py
+src/openmolar/schema_upgrades/schema3_6to3_7.py
 src/openmolar/settings/__init__.py
 src/openmolar/settings/allowed.py
 src/openmolar/settings/appointment_shortcuts.py
diff --git a/PKG-INFO b/PKG-INFO
index 3822e9e..d452c73 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: openmolar
-Version: 1.0
+Version: 1.0.15-gd81f9e5
 Summary: Open Source Dental Practice Management Software
 Home-page: https://www.openmolar.com
 Author: Neil Wallace
diff --git a/src/openmolar/__init__.py b/src/openmolar/__init__.py
index bfaf5f6..2e09f7b 100755
--- a/src/openmolar/__init__.py
+++ b/src/openmolar/__init__.py
@@ -52,10 +52,15 @@ class MyFormatter(logging.Formatter):
 
     def format(self, record):
         filename = "{%s:%s}" % (record.filename, record.lineno)
-        return "%s\t %s %s - %s" % (record.levelname,
-                                    filename.ljust(25),
-                                    record.funcName[:15].ljust(15),
-                                    record.getMessage())
+        if record.exc_info:
+            exc_info = "\n" + self.formatException(record.exc_info)
+        else:
+            exc_info = ""
+        return "%s\t %s %s - %s%s" % (
+            record.levelname,
+            filename.ljust(25),
+            record.funcName[:15].ljust(15),
+            record.getMessage(), exc_info)
 
 
 def initialise_logging():
diff --git a/src/openmolar/create_db.py b/src/openmolar/create_db.py
index 6b9063f..e36bd48 100644
--- a/src/openmolar/create_db.py
+++ b/src/openmolar/create_db.py
@@ -41,6 +41,10 @@ CREATE_QUERY = "CREATE DATABASE %s"
 # select,insert,update,delete privileges
 PRIVS_QUERY = "GRANT ALL PRIVILEGES ON %s.* TO '%s'@'%s' IDENTIFIED BY '%s'"
 
+CHECK_SUPERVISOR_QUERY = '''
+SELECT Create_priv, Drop_priv, Trigger_priv FROM user WHERE User=%s and Host=%s
+'''
+
 
 def exists_already(host_, port_, db_name, privileged_user_pass,
                    privileged_user="root"):
@@ -57,16 +61,59 @@ def exists_already(host_, port_, db_name, privileged_user_pass,
             db.close()
             return True
     except:
-        LOGGER.warning("exists already through error, passing silently")
+        LOGGER.warning("exists_already threw error, passing silently")
     return False
 
 
+def check_superuser(host_, port_, passwd, user="root"):
+    '''
+    returns true if database 'db_name' exists
+    '''
+    result = False
+    messages = []
+    try:
+        LOGGER.info("Connecting to mysql to check superuser")
+        db = MySQLdb.connect(host=host_,
+                             port=port_,
+                             user=user,
+                             passwd=passwd,
+                             db='mysql')
+        if db.open:
+            cursor = db.cursor()
+            cursor.execute(CHECK_SUPERVISOR_QUERY, (user, host_))
+            rows = cursor.fetchall()
+            db.close()
+            for create, drop, trigger in rows:
+                if create == "Y" and drop =="Y":
+                    result = True
+                if create == "N":
+                    messages.append(
+                        "'%s'on'%s' does not have create database privileges")
+                if drop == "N":
+                    messages.append(
+                        "'%s'on'%s' does not have drop database privileges")
+                if trigger == "N":
+                    messages.append(
+                        "'%s'on'%s' does not have trigger privileges")
+    except MySQLdb.OperationalError as exc:
+        LOGGER.exception("error caught")
+        return False, [str(s) for s in exc.args]
+    except:
+        LOGGER.exception("check_supervisor threw error, passing silently")
+        messages.append("%s - %s '%%s' %s '%%s'" % (
+            _("Unable to connect to mysql"),
+            _("please check password for"),
+            _("on")))
+    return result, [m % (user, host_) for m in messages]
+
+
 def create_database(host_, port_, user_, pass_wd, db_name,
                     privileged_user_pass, privileged_user="root"):
     '''
     creates a database called "db_name" on host_, port_, passwd,
     '''
     try:
+        LOGGER.info("Connecting to mysql")
         # connect as mysqlroot to create the database
         db = MySQLdb.connect(host=host_,
                              port=port_,
@@ -86,16 +133,19 @@ def create_database(host_, port_, user_, pass_wd, db_name,
         db.commit()
         db.close()
         LOGGER.info("db created successfully")
-        return True
-    except:
+        return True, "success"
+    except Exception as exc:
         LOGGER.exception("error creating database")
+        return False, exc.args[1]
 
 
 def create_tables(host_, port_, user_, pass_wd, db_name):
     try:
-        f = open(os.path.join(localsettings.RESOURCE_DIR, "schema.sql"), "r")
+        fp = os.path.join(localsettings.RESOURCE_DIR, "schema.sql")
+        f = open(fp, "r")
         sql_statements = f.read()
         f.close()
+        LOGGER.info("Connecting to mysql")
 
         db = MySQLdb.connect(host=host_,
                              port=port_,
@@ -104,6 +154,7 @@ def create_tables(host_, port_, user_, pass_wd, db_name):
                              passwd=pass_wd)
 
         cursor = db.cursor()
+        LOGGER.info("Executing sql statements from %s", fp)
         cursor.execute(sql_statements)
         cursor.close()
         db.commit()
@@ -113,15 +164,49 @@ def create_tables(host_, port_, user_, pass_wd, db_name):
         LOGGER.exception("error creating database tables")
 
 
+def insert_data(host_, port_, user_, pass_wd, db_name, minimal_only=False):
+    '''
+    An openmolar database requires some userdata before the application can
+    run.
+    if minimal_only is False (the default) a demo patient is installed also.
+    '''
+    result = False
+    try:
+        for i, fp in enumerate(("minimal_data.sql", "demo_data.sql")):
+            if minimal_only and i == 1:
+                continue
+            f = open(os.path.join(localsettings.RESOURCE_DIR, fp), "r")
+            sql_statements = f.read()
+            f.close()
+
+            db = MySQLdb.connect(host=host_,
+                                port=port_,
+                                user=user_,
+                                db=db_name,
+                                passwd=pass_wd)
+
+            cursor = db.cursor()
+            cursor.execute(sql_statements)
+            cursor.close()
+            db.commit()
+            db.close()
+        result = True
+    except:
+        LOGGER.exception("error inserting minimal data")
+    return result
+
+
 if __name__ == "__main__":
+    import getpass
     LOGGER.setLevel(logging.DEBUG)
-    root_pass = input("please enter your MySQL root users password :")
+    root_pass = getpass.getpass("please enter your MySQL root users password :")
     print("exists already = %s" %
           exists_already("localhost", 3306, "openmolar_demo", root_pass))
 
     if create_database("localhost", 3306, "openmolar", "password",
                        "openmolar_demo", root_pass):
         LOGGER.debug("New database created successfully")
-
         create_tables("localhost", 3306, "openmolar", "password",
                       "openmolar_demo")
+        insert_data("localhost", 3306, "openmolar", "password",
+                      "openmolar_demo")
diff --git a/src/openmolar/dbtools/appointments.py b/src/openmolar/dbtools/appointments.py
index 62d8b5d..424e28e 100755
--- a/src/openmolar/dbtools/appointments.py
+++ b/src/openmolar/dbtools/appointments.py
@@ -441,6 +441,7 @@ class DayAppointmentData(DaySummary):
         workingDents = []
         self.inOffice = {}
         self.memos = {}
+        self._snos = None
         self.startTimes = {}
         self.endTimes = {}
         self.earliest_start = 2359
@@ -504,6 +505,7 @@ class DayAppointmentData(DaySummary):
         '''
         get the appointments for the date.
         '''
+        self._snos = None
         working_dents = []
         for dent in localsettings.activedents + localsettings.activehygs:
             apptix = localsettings.apptix[dent]
@@ -579,6 +581,18 @@ class DayAppointmentData(DaySummary):
         self.appointments.sort(key=lambda x: x.start)
         self.appointments.sort(key=lambda x: x.apptix)
 
+    @property
+    def serialnos(self):
+        if self._snos is None:
+            self._snos = set()
+            for app in self.appointments:
+                self._snos.add(app.serialno)
+            try:
+                self._snos.remove(0)
+            except KeyError:
+                pass
+        return self._snos
+
 
 class DentistDay(object):
 
@@ -1353,7 +1367,10 @@ def get_pts_appts(pt, printing=False):
         appt.serialno = row[0]
         appt.aprix = row[1]
         appt.name = name
-        appt.cset = pt.cset
+        if pt.cset == "M":
+            appt.cset = "I"
+        else:
+            appt.cset = pt.cset[0]
         appt.dent = row[2]
         appt.date = row[7]
         appt.atime = row[8]
diff --git a/src/openmolar/dbtools/db_settings.py b/src/openmolar/dbtools/db_settings.py
index 045bc84..1ac5151 100644
--- a/src/openmolar/dbtools/db_settings.py
+++ b/src/openmolar/dbtools/db_settings.py
@@ -352,6 +352,12 @@ class SettingsFetcher(object):
         debt_col = self.get_unique_value("debt collector")
         return debt_col if debt_col else _("DEBT COLLECTOR NOT SET")
 
+    @property
+    def disallowed_forum_posters(self):
+        rows = self.getData("disallowed forum poster")
+        return [fields[0] for fields in rows]
+
+
 if __name__ == "__main__":
     sf = SettingsFetcher()
     sf.fetch()
@@ -366,3 +372,4 @@ if __name__ == "__main__":
     print(sf.dentist_data)
     print(sf.account_footer)
     print(sf.debt_collector)
+    print(sf.disallowed_forum_posters)
diff --git a/src/openmolar/settings/version.py b/src/openmolar/dbtools/locations.py
similarity index 58%
copy from src/openmolar/settings/version.py
copy to src/openmolar/dbtools/locations.py
index 8422a4a..1e0626a 100644
--- a/src/openmolar/settings/version.py
+++ b/src/openmolar/dbtools/locations.py
@@ -22,13 +22,54 @@
 # ########################################################################### #
 
 '''
-This file contains the version number for openmolar
-Do not edit this file manually, as it should be updated by make version
-when git tag is updated.
+tools to access the locations table
+(which is a record of where patients are eg. "waiting room")
 '''
 
-VERSION = "1.0"
+from openmolar import connect
 
+QUERY = "SELECT serialno, location FROM locations"
+WAIT_QUERY = "SELECT serialno FROM locations WHERE location NOT REGEXP '[0-9]'"
 
-if __name__ == '__main__':
-    print("version = %s" % VERSION)
+
+def all_snos():
+    db = connect.connect()
+    cursor = db.cursor()
+    if cursor.execute(QUERY):
+        values = [serialno for serialno, location in cursor.fetchall()]
+    else:
+        values = ()
+    cursor.close()
+    return values
+
+
+def no_of_patients_waiting():
+
+    db = connect.connect()
+    cursor = db.cursor()
+    if cursor.execute(WAIT_QUERY):
+        values = [row[0] for row in cursor.fetchall()]
+    else:
+        values = ()
+    cursor.close()
+    return values
+
+
+def locations():
+    '''
+    query the database locations table, and return a dictionary of key:value
+    pairs serialno:location
+    '''
+    location_dict = {}
+    db = connect.connect()
+    cursor = db.cursor()
+    cursor.execute(QUERY)
+    for key, value in cursor.fetchall():
+        location_dict[key] = value
+    cursor.close()
+
+    return location_dict
+
+
+if __name__ == "__main__":
+    print(locations())
diff --git a/src/openmolar/dbtools/patient_write_changes.py b/src/openmolar/dbtools/patient_write_changes.py
index 5c65d8c..3cfd5dd 100644
--- a/src/openmolar/dbtools/patient_write_changes.py
+++ b/src/openmolar/dbtools/patient_write_changes.py
@@ -309,10 +309,7 @@ def toNotes(serialno, newnotes):
     if values:
         db = connect()
         cursor = db.cursor()
-        # this (superior code?) didn't work on older MySQLdb versions.
-        # rows = cursor.executemany(query, tuple(values))
-        for value in values:
-            rows += cursor.execute(INSERT_NOTE_QUERY, value)
+        rows = cursor.executemany(INSERT_NOTE_QUERY, values)
         cursor.close()
         db.commit()
 
diff --git a/src/openmolar/dbtools/search.py b/src/openmolar/dbtools/search.py
index f99ff24..e85331f 100644
--- a/src/openmolar/dbtools/search.py
+++ b/src/openmolar/dbtools/search.py
@@ -32,15 +32,17 @@ from openmolar.settings import localsettings
 
 LOGGER = logging.getLogger("openmolar")
 
-ALL_PATIENTS_QUERY = \
-    '''SELECT serialno, status, title, fname, sname, dob, addr1, addr2, town,
-pcde, tel1, tel2, mobile FROM new_patients ORDER BY sname, fname'''
+ALL_PATIENTS_QUERY = '''SELECT new_patients.serialno, status, title, fname,
+sname, dob, addr1, addr2, town, pcde, tel1, tel2, mobile, alt_fname, alt_sname
+FROM new_patients
+LEFT JOIN pseudonyms ON new_patients.serialno = pseudonyms.serialno
+{{CONDITIONS}} GROUP BY serialno ORDER BY sname, fname'''
 
 
 def all_patients():
     db = connect()
     cursor = db.cursor()
-    cursor.execute(ALL_PATIENTS_QUERY)
+    cursor.execute(ALL_PATIENTS_QUERY.replace("{{CONDITIONS}}", ""))
     results = cursor.fetchall()
     cursor.close()
 
@@ -68,41 +70,50 @@ def getcandidates(dob, addr, tel, sname, similar_sname, fname,
         values.append("%" + pcde + "%")
     if sname != '':
         if similar_sname:
-            conditions.append('sname sounds like %s')
-            values.append(sname)
+            conditions.append(
+                '(sname sounds like %s OR alt_sname sounds like %s)')
+            values += [sname, sname]
         else:
             sname += "%"
-            if "'" in sname:
-                conditions.append('(sname like %s or sname like %s)')
-                values.append(sname)
-                values.append(sname.replace("'", ""))
-            elif sname[:1] == "o":
-                conditions.append('(sname like %s or sname like %s)')
-                values.append(sname)
-                values.append("o'" + sname[1:])
-            elif sname[:2] == "mc":
-                conditions.append('(sname like %s or sname like %s)')
-                values.append(sname)
-                values.append(sname.replace("mc", "mac"))
-            elif sname[:3] == "mac":
-                conditions.append('(sname like %s or sname like %s)')
-                values.append(sname)
-                values.append(sname.replace("mac", "mc"))
-            else:
-                conditions.append('sname like %s')
-                values.append(sname)
+            sname_conds = []
+            for field in ('sname', 'alt_sname'):
+                if "'" in sname:
+                    sname_conds.append(
+                        '(%s like %%s or %s like %%s)' % (field, field))
+                    values.append(sname)
+                    values.append(sname.replace("'", ""))
+                elif sname[:1] == "o":
+                    sname_conds.append(
+                        '(%s like %%s or %s like %%s)' % (field, field))
+                    values.append(sname)
+                    values.append("o'" + sname[1:])
+                elif sname[:2] == "mc":
+                    sname_conds.append(
+                        '(%s like %%s or %s like %%s)' % (field, field))
+                    values.append(sname)
+                    values.append(sname.replace("mc", "mac"))
+                elif sname[:3] == "mac":
+                    sname_conds.append(
+                        '(%s like %%s or %s like %%s)' % (field, field))
+                    values.append(sname)
+                    values.append(sname.replace("mac", "mc"))
+                else:
+                    sname_conds.append('%s like %%s' % field)
+                    values.append(sname)
+            conditions.append("(%s)" % " OR ".join(sname_conds))
 
     if fname != '':
         if similar_fname:
             conditions.append('fname sounds like %s')
             values.append(fname)
         else:
-            conditions.append('fname like %s')
+            conditions.append('(fname LIKE %s OR alt_fname LIKE %s)')
+            values.append(fname + "%")
             values.append(fname + "%")
 
     if conditions:
-        conditional = "WHERE %s ORDER BY" % " AND ".join(conditions)
-        query = ALL_PATIENTS_QUERY.replace("ORDER BY", conditional)
+        conditional = "WHERE %s" % " AND ".join(conditions)
+        query = ALL_PATIENTS_QUERY.replace("{{CONDITIONS}}", conditional)
 
         LOGGER.debug(query.replace("\n", " "))
         LOGGER.debug(values)
@@ -123,8 +134,8 @@ def getcandidates_from_serialnos(list_of_snos):
     "double appointments" were commonplace.
     '''
     format_snos = ",". join(('%s',) * len(list_of_snos))  # %s,%s,%s
-    conditional = "WHERE serialno in (%s) ORDER BY" % format_snos
-    query = ALL_PATIENTS_QUERY.replace("ORDER BY", conditional)
+    conditional = "WHERE new_patients.serialno in (%s)" % format_snos
+    query = ALL_PATIENTS_QUERY.replace("{{CONDITIONS}} ", conditional)
 
     db = connect()
     cursor = db.cursor()
@@ -135,9 +146,9 @@ def getcandidates_from_serialnos(list_of_snos):
 
 
 if __name__ == '__main__':
-    values = (datetime.date(1969, 12, 9), "Gables", "772378",
+    values_ = (datetime.date(1969, 12, 9), "Gables", "772378",
               "wallace", "", "neil", "", "IV2")
-    new_vals = getcandidates(*values)
+    new_vals = getcandidates(*values_)
     for candidate in new_vals:
         print(candidate)
 
diff --git a/src/openmolar/dbtools/writeNewPatient.py b/src/openmolar/dbtools/writeNewPatient.py
index 0eb880d..5658b4e 100644
--- a/src/openmolar/dbtools/writeNewPatient.py
+++ b/src/openmolar/dbtools/writeNewPatient.py
@@ -21,38 +21,38 @@
 # #                                                                         # #
 # ########################################################################### #
 
-import MySQLdb
 from openmolar import connect
 from openmolar.dbtools import patient_class
-from openmolar.settings import localsettings
+
+NEXT_SNO_QUERY = "SELECT MAX(serialno) + 1 FROM new_patients"
+QUERY = '''INSERT INTO new_patients (serialno, %s) VALUES (%%s, %s)'''
 
 
 def commit(pt):
-    sqlcond = ""
-    values = []
+    db = connect.connect()
+    cursor = db.cursor()
+    cursor.execute(NEXT_SNO_QUERY)
+    sno = cursor.fetchone()[0]
+    cursor.close()
+    if sno is None:
+        sno = 1
+
+    attrs, vals = [], []
     for attr in patient_class.patientTableAtts:
         value = pt.__dict__[attr]
         if value:
-            sqlcond += '%s = %%s,' % attr
-            values.append(value)
+            attrs.append(attr)
+            vals.append(value)
 
-    sqlcommand = "insert into new_patients SET %s serialno=%%s" % sqlcond
+    query = QUERY % (",".join([a for a in attrs]),
+                     ",".join(['%s' for a in attrs]))
 
-    query = "select max(serialno) from new_patients"
-
-    Attempts = 0
+    _attempts = 0
     while True:
-        db = connect.connect()
-        cursor = db.cursor()
-        cursor.execute(query)
-        currentMax = cursor.fetchone()[0]
-
-        if currentMax:
-            newSerialno = currentMax + 1
-        else:
-            newSerialno = 1
         try:
-            cursor.execute(sqlcommand, tuple(values + [newSerialno]))
+            db = connect.connect()
+            cursor = db.cursor()
+            cursor.execute(query, [sno] + vals)
             cursor.close()
             db.commit()
             break
@@ -60,21 +60,18 @@ def commit(pt):
         except connect.IntegrityError as exc:
             print("error saving new patient, will retry with new serialno")
             print(exc)
-            newSerialno = -1
+            sno += 1
 
-        Attempts += 1
-        if Attempts > 20:
+        _attempts += 1
+        if _attempts > 20:
+            sno = -1
             break
-    # db.close()
-    return newSerialno
+    return sno
 
 
 if __name__ == "__main__":
-    global pt
-    from openmolar.dbtools import patient_class
-    import copy
-    pt = patient_class.patient(0)
-    pt.fname = "Norman"
-    pt.sname = "Wisdom"
+    test_pt = patient_class.patient(0)
+    test_pt.fname = "Norman"
+    test_pt.sname = "Wisdom"
     # ok - so a trivial change has been made - now write to the database
-    print(commit(pt))
+    print(commit(test_pt))
diff --git a/src/openmolar/ptModules/patientDetails.py b/src/openmolar/ptModules/patientDetails.py
index 43e8de9..2b565a3 100644
--- a/src/openmolar/ptModules/patientDetails.py
+++ b/src/openmolar/ptModules/patientDetails.py
@@ -97,11 +97,12 @@ def details(pt):
         elif "I" in pt.cset:
             html += '''<img src="%s/hdp_small.png" alt="HDP" />
             <br />''' % localsettings.resources_path
-
+        elif "M" in pt.cset:
+            html += '''<img src="%s/hdp_maintenance.png" alt="HDP-Maint" />
+            <br />''' % localsettings.resources_path
         elif "P" in pt.cset:
             html += '''<img src="%s/private.png" alt="PRIVATE" />
             <br />''' % localsettings.resources_path
-
         else:
             html += '%s = %s <br />' % (_("UNKNOWN COURSETYPE"), pt.cset)
 
diff --git a/src/openmolar/qt-designer/main.ui b/src/openmolar/qt-designer/main.ui
index b6fbb5b..de2811b 100644
--- a/src/openmolar/qt-designer/main.ui
+++ b/src/openmolar/qt-designer/main.ui
@@ -463,7 +463,7 @@
                      <rect>
                       <x>0</x>
                       <y>0</y>
-                      <width>521</width>
+                      <width>770</width>
                       <height>646</height>
                      </rect>
                     </property>
@@ -804,22 +804,6 @@
                           </property>
                          </widget>
                         </item>
-                        <item row="2" column="1" colspan="3">
-                         <widget class="QLineEdit" name="snameEdit">
-                          <property name="maximumSize">
-                           <size>
-                            <width>16777215</width>
-                            <height>16777215</height>
-                           </size>
-                          </property>
-                          <property name="autoFillBackground">
-                           <bool>false</bool>
-                          </property>
-                          <property name="maxLength">
-                           <number>30</number>
-                          </property>
-                         </widget>
-                        </item>
                         <item row="2" column="4">
                          <widget class="QLabel" name="label_14">
                           <property name="maximumSize">
@@ -1093,7 +1077,7 @@
                         <item row="1" column="0">
                          <widget class="QLabel" name="label_2">
                           <property name="text">
-                           <string>First Name</string>
+                           <string>First Name(s)</string>
                           </property>
                           <property name="alignment">
                            <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -1103,22 +1087,6 @@
                           </property>
                          </widget>
                         </item>
-                        <item row="1" column="1" colspan="3">
-                         <widget class="QLineEdit" name="fnameEdit">
-                          <property name="maximumSize">
-                           <size>
-                            <width>16777215</width>
-                            <height>16777215</height>
-                           </size>
-                          </property>
-                          <property name="autoFillBackground">
-                           <bool>false</bool>
-                          </property>
-                          <property name="maxLength">
-                           <number>30</number>
-                          </property>
-                         </widget>
-                        </item>
                         <item row="1" column="4">
                          <widget class="QLabel" name="label_13">
                           <property name="maximumSize">
@@ -1214,6 +1182,45 @@
                           </property>
                          </widget>
                         </item>
+                        <item row="1" column="1" colspan="3">
+                         <widget class="QLineEdit" name="fnameEdit">
+                          <property name="maximumSize">
+                           <size>
+                            <width>16777215</width>
+                            <height>16777215</height>
+                           </size>
+                          </property>
+                          <property name="autoFillBackground">
+                           <bool>false</bool>
+                          </property>
+                          <property name="maxLength">
+                           <number>30</number>
+                          </property>
+                         </widget>
+                        </item>
+                        <item row="2" column="1" colspan="2">
+                         <widget class="QLineEdit" name="snameEdit">
+                          <property name="maximumSize">
+                           <size>
+                            <width>16777215</width>
+                            <height>16777215</height>
+                           </size>
+                          </property>
+                          <property name="autoFillBackground">
+                           <bool>false</bool>
+                          </property>
+                          <property name="maxLength">
+                           <number>30</number>
+                          </property>
+                         </widget>
+                        </item>
+                        <item row="2" column="3">
+                         <widget class="QPushButton" name="advanced_names_pushButton">
+                          <property name="text">
+                           <string>Advanced</string>
+                          </property>
+                         </widget>
+                        </item>
                        </layout>
                       </widget>
                      </item>
@@ -1624,6 +1631,20 @@
                     <zorder>editHDP_pushButton</zorder>
                     <zorder>label_20</zorder>
                    </widget>
+                   <widget class="QWidget" name="tab">
+                    <attribute name="title">
+                     <string>HDP Maintenance Plan</string>
+                    </attribute>
+                    <layout class="QHBoxLayout" name="horizontalLayout_13">
+                     <item>
+                      <widget class="QLabel" name="maintenance_contract_label">
+                       <property name="text">
+                        <string>Maintenance Label</string>
+                       </property>
+                      </widget>
+                     </item>
+                    </layout>
+                   </widget>
                    <widget class="QWidget" name="tab_20">
                     <attribute name="title">
                      <string>NHS</string>
@@ -1797,7 +1818,7 @@
                      <rect>
                       <x>0</x>
                       <y>0</y>
-                      <width>457</width>
+                      <width>752</width>
                       <height>423</height>
                      </rect>
                     </property>
@@ -2090,8 +2111,8 @@
                      <rect>
                       <x>0</x>
                       <y>0</y>
-                      <width>491</width>
-                      <height>457</height>
+                      <width>766</width>
+                      <height>471</height>
                      </rect>
                     </property>
                     <layout class="QHBoxLayout" name="horizontalLayout_26">
@@ -2355,13 +2376,7 @@
                             <property name="title">
                              <string>Miscellaneous</string>
                             </property>
-                            <layout class="QHBoxLayout" name="horizontalLayout_14">
-                             <property name="spacing">
-                              <number>3</number>
-                             </property>
-                             <property name="margin">
-                              <number>2</number>
-                             </property>
+                            <layout class="QVBoxLayout" name="verticalLayout_11">
                              <item>
                               <widget class="QPushButton" name="recall_settings_pushButton">
                                <property name="text">
@@ -2480,7 +2495,7 @@
                       <x>0</x>
                       <y>0</y>
                       <width>766</width>
-                      <height>457</height>
+                      <height>468</height>
                      </rect>
                     </property>
                     <layout class="QGridLayout" name="gridLayout_4">
@@ -2637,108 +2652,130 @@
                        </property>
                       </widget>
                      </item>
-                     <item row="4" column="0" colspan="2">
-                      <layout class="QHBoxLayout" name="horizontalLayout_13">
-                       <item>
-                        <widget class="QPushButton" name="exampushButton">
-                         <property name="maximumSize">
-                          <size>
-                           <width>16777215</width>
-                           <height>28</height>
-                          </size>
-                         </property>
-                         <property name="toolTip">
-                          <string>perform a clinical exam</string>
-                         </property>
-                         <property name="text">
-                          <string>Exam</string>
-                         </property>
-                        </widget>
-                       </item>
-                       <item>
-                        <widget class="QPushButton" name="xray_pushButton">
-                         <property name="toolTip">
-                          <string>add x-rays to the patient's current course.</string>
-                         </property>
-                         <property name="text">
-                          <string>X-ray</string>
-                         </property>
-                        </widget>
-                       </item>
-                       <item>
-                        <widget class="QPushButton" name="hygWizard_pushButton">
-                         <property name="toolTip">
-                          <string>perform common perio treatments</string>
-                         </property>
-                         <property name="text">
-                          <string>Hyg</string>
-                         </property>
-                        </widget>
-                       </item>
-                       <item>
-                        <widget class="Line" name="line_4">
-                         <property name="orientation">
-                          <enum>Qt::Vertical</enum>
-                         </property>
-                        </widget>
-                       </item>
-                       <item>
-                        <widget class="QPushButton" name="closeCourse_pushButton">
-                         <property name="text">
-                          <string>Close This Course</string>
-                         </property>
-                        </widget>
-                       </item>
-                       <item>
-                        <spacer name="horizontalSpacer_3">
-                         <property name="orientation">
-                          <enum>Qt::Horizontal</enum>
-                         </property>
-                         <property name="sizeHint" stdset="0">
-                          <size>
-                           <width>28</width>
-                           <height>17</height>
-                          </size>
-                         </property>
-                        </spacer>
-                       </item>
-                       <item>
-                        <widget class="QPushButton" name="childsmile_button">
-                         <property name="text">
-                          <string>ChildSmile</string>
-                         </property>
-                        </widget>
-                       </item>
-                       <item>
-                        <spacer name="horizontalSpacer_2">
-                         <property name="orientation">
-                          <enum>Qt::Horizontal</enum>
-                         </property>
-                         <property name="sizeHint" stdset="0">
-                          <size>
-                           <width>40</width>
-                           <height>20</height>
-                          </size>
-                         </property>
-                        </spacer>
-                       </item>
-                       <item>
-                        <widget class="QPushButton" name="medNotes_pushButton">
-                         <property name="minimumSize">
-                          <size>
-                           <width>200</width>
-                           <height>0</height>
-                          </size>
-                         </property>
-                         <property name="toolTip">
-                          <string>check / update the patients medical history</string>
-                         </property>
-                         <property name="text">
-                          <string>Medical History Dialog</string>
-                         </property>
-                        </widget>
-                       </item>
-                      </layout>
+                     <item row="9" column="0" colspan="2">
+                      <widget class="QFrame" name="clincal_summary_button_frame">
+                       <property name="sizePolicy">
+                        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+                         <horstretch>0</horstretch>
+                         <verstretch>40</verstretch>
+                        </sizepolicy>
+                       </property>
+                       <property name="minimumSize">
+                        <size>
+                         <width>0</width>
+                         <height>40</height>
+                        </size>
+                       </property>
+                       <property name="frameShape">
+                        <enum>QFrame::StyledPanel</enum>
+                       </property>
+                       <property name="frameShadow">
+                        <enum>QFrame::Raised</enum>
+                       </property>
+                       <layout class="QHBoxLayout" name="horizontalLayout_6">
+                        <property name="margin">
+                         <number>2</number>
+                        </property>
+                        <item>
+                         <widget class="QPushButton" name="exampushButton">
+                          <property name="maximumSize">
+                           <size>
+                            <width>16777215</width>
+                            <height>28</height>
+                           </size>
+                          </property>
+                          <property name="toolTip">
+                           <string>perform a clinical exam</string>
+                          </property>
+                          <property name="text">
+                           <string>Exam</string>
+                          </property>
+                         </widget>
+                        </item>
+                        <item>
+                         <widget class="QPushButton" name="xray_pushButton">
+                          <property name="toolTip">
+                           <string>add x-rays to the patient's current course.</string>
+                          </property>
+                          <property name="text">
+                           <string>X-ray</string>
+                          </property>
+                         </widget>
+                        </item>
+                        <item>
+                         <widget class="QPushButton" name="hygWizard_pushButton">
+                          <property name="toolTip">
+                           <string>perform common perio treatments</string>
+                          </property>
+                          <property name="text">
+                           <string>Hyg</string>
+                          </property>
+                         </widget>
+                        </item>
+                        <item>
+                         <spacer name="horizontalSpacer_3">
+                          <property name="orientation">
+                           <enum>Qt::Horizontal</enum>
+                          </property>
+                          <property name="sizeHint" stdset="0">
+                           <size>
+                            <width>40</width>
+                            <height>20</height>
+                           </size>
+                          </property>
+                         </spacer>
+                        </item>
+                        <item>
+                         <widget class="QPushButton" name="closeCourse_pushButton">
+                          <property name="text">
+                           <string>Close This Course</string>
+                          </property>
+                         </widget>
+                        </item>
+                        <item>
+                         <widget class="QPushButton" name="childsmile_button">
+                          <property name="text">
+                           <string>ChildSmile</string>
+                          </property>
+                         </widget>
+                        </item>
+                        <item>
+                         <spacer name="horizontalSpacer_2">
+                          <property name="orientation">
+                           <enum>Qt::Horizontal</enum>
+                          </property>
+                          <property name="sizeHint" stdset="0">
+                           <size>
+                            <width>40</width>
+                            <height>20</height>
+                           </size>
+                          </property>
+                         </spacer>
+                        </item>
+                        <item>
+                         <widget class="QPushButton" name="medNotes_pushButton">
+                          <property name="sizePolicy">
+                           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                            <horstretch>0</horstretch>
+                            <verstretch>0</verstretch>
+                           </sizepolicy>
+                          </property>
+                          <property name="minimumSize">
+                           <size>
+                            <width>100</width>
+                            <height>0</height>
+                           </size>
+                          </property>
+                          <property name="toolTip">
+                           <string>check / update the patients medical history</string>
+                          </property>
+                          <property name="text">
+                           <string>Medical History</string>
+                          </property>
+                         </widget>
+                        </item>
+                       </layout>
+                      </widget>
                      </item>
                     </layout>
                    </widget>
@@ -3130,8 +3167,8 @@
                      <rect>
                       <x>0</x>
                       <y>0</y>
-                      <width>98</width>
-                      <height>200</height>
+                      <width>559</width>
+                      <height>377</height>
                      </rect>
                     </property>
                     <layout class="QHBoxLayout" name="horizontalLayout_19"/>
@@ -3160,8 +3197,8 @@
                      <rect>
                       <x>0</x>
                       <y>0</y>
-                      <width>166</width>
-                      <height>218</height>
+                      <width>198</width>
+                      <height>377</height>
                      </rect>
                     </property>
                     <layout class="QVBoxLayout" name="verticalLayout_9">
@@ -3280,8 +3317,8 @@ Note - this will not remove items which are currently there. </string>
                      <rect>
                       <x>0</x>
                       <y>0</y>
-                      <width>98</width>
-                      <height>28</height>
+                      <width>783</width>
+                      <height>395</height>
                      </rect>
                     </property>
                    </widget>
@@ -3518,7 +3555,7 @@ If the "changes only" checkbox is checked, only data which has been ch
                 <property name="spacing">
                  <number>3</number>
                 </property>
-                <item row="0" column="1" rowspan="3">
+                <item row="0" column="2" rowspan="3">
                  <widget class="Line" name="line">
                   <property name="sizePolicy">
                    <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
@@ -3531,7 +3568,7 @@ If the "changes only" checkbox is checked, only data which has been ch
                   </property>
                  </widget>
                 </item>
-                <item row="0" column="2" rowspan="3">
+                <item row="0" column="3" rowspan="3">
                  <widget class="QScrollArea" name="scrollArea_8">
                   <property name="sizePolicy">
                    <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
@@ -3596,7 +3633,7 @@ If the "changes only" checkbox is checked, only data which has been ch
                   </widget>
                  </widget>
                 </item>
-                <item row="0" column="4">
+                <item row="0" column="5">
                  <widget class="QLabel" name="label_39">
                   <property name="sizePolicy">
                    <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -3607,9 +3644,12 @@ If the "changes only" checkbox is checked, only data which has been ch
                   <property name="text">
                    <string>Today's Notes</string>
                   </property>
+                  <property name="alignment">
+                   <set>Qt::AlignCenter</set>
+                  </property>
                  </widget>
                 </item>
-                <item row="0" column="5" rowspan="3">
+                <item row="0" column="6" rowspan="3">
                  <widget class="Line" name="line_2">
                   <property name="sizePolicy">
                    <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
@@ -3622,7 +3662,7 @@ If the "changes only" checkbox is checked, only data which has been ch
                   </property>
                  </widget>
                 </item>
-                <item row="2" column="4">
+                <item row="2" column="5">
                  <widget class="QPushButton" name="phraseBook_pushButton">
                   <property name="text">
                    <string>PhraseBook</string>
@@ -3636,7 +3676,7 @@ If the "changes only" checkbox is checked, only data which has been ch
                   </property>
                  </widget>
                 </item>
-                <item row="0" column="6" rowspan="3">
+                <item row="0" column="7" rowspan="3">
                  <widget class="QPushButton" name="saveButton">
                   <property name="sizePolicy">
                    <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
@@ -3665,7 +3705,7 @@ If the "changes only" checkbox is checked, only data which has been ch
                   </property>
                  </widget>
                 </item>
-                <item row="0" column="3" rowspan="3">
+                <item row="0" column="4" rowspan="3">
                  <widget class="QTextEdit" name="notesEnter_textEdit">
                   <property name="sizePolicy">
                    <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
@@ -3687,10 +3727,21 @@ If the "changes only" checkbox is checked, only data which has been ch
                   </property>
                  </widget>
                 </item>
-                <item row="0" column="0" rowspan="3">
+                <item row="1" column="5">
+                 <widget class="QPushButton" name="clinician_phrasebook_pushButton">
+                  <property name="text">
+                   <string>Phrases</string>
+                  </property>
+                  <property name="icon">
+                   <iconset resource="../resources/resources.qrc">
+                    <normaloff>:/txt.png</normaloff>:/txt.png</iconset>
+                  </property>
+                 </widget>
+                </item>
+                <item row="1" column="0" rowspan="2">
                  <widget class="QPushButton" name="memos_pushButton">
                   <property name="sizePolicy">
-                   <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+                   <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
                     <horstretch>0</horstretch>
                     <verstretch>0</verstretch>
                    </sizepolicy>
@@ -3704,14 +3755,16 @@ If the "changes only" checkbox is checked, only data which has been ch
                   </property>
                  </widget>
                 </item>
-                <item row="1" column="4">
-                 <widget class="QPushButton" name="clinician_phrasebook_pushButton">
-                  <property name="text">
-                   <string>Phrases</string>
+                <item row="0" column="0">
+                 <widget class="QPushButton" name="set_location_button">
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
                   </property>
-                  <property name="icon">
-                   <iconset resource="../resources/resources.qrc">
-                    <normaloff>:/txt.png</normaloff>:/txt.png</iconset>
+                  <property name="text">
+                   <string>Location</string>
                   </property>
                  </widget>
                 </item>
@@ -4863,8 +4916,10 @@ If the "changes only" checkbox is checked, only data which has been ch
     </property>
     <addaction name="actionClear_Today_s_Emergency_Slots"/>
     <addaction name="separator"/>
-    <addaction name="actionInsert_Regular_Blocks"/>
+    <addaction name="actionClear_Locations"/>
+    <addaction name="separator"/>
     <addaction name="actionSet_Bookend"/>
+    <addaction name="actionInsert_Regular_Blocks"/>
    </widget>
    <addaction name="menuMenu"/>
    <addaction name="menu_Prefences"/>
@@ -5121,6 +5176,11 @@ If the "changes only" checkbox is checked, only data which has been ch
     <string>Edit Account Letter Settings</string>
    </property>
   </action>
+  <action name="actionClear_Locations">
+   <property name="text">
+    <string>Clear All Patient Locations</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
@@ -5176,8 +5236,6 @@ If the "changes only" checkbox is checked, only data which has been ch
   <tabstop>bpe_textBrowser</tabstop>
   <tabstop>newBPE_pushButton</tabstop>
   <tabstop>planSummary_textBrowser</tabstop>
-  <tabstop>exampushButton</tabstop>
-  <tabstop>medNotes_pushButton</tabstop>
   <tabstop>contract_tabWidget</tabstop>
   <tabstop>notesPrintButton</tabstop>
  </tabstops>
diff --git a/src/openmolar/qt4gui/contract_gui_module.py b/src/openmolar/qt4gui/contract_gui_module.py
index 9244596..ed7ebb5 100644
--- a/src/openmolar/qt4gui/contract_gui_module.py
+++ b/src/openmolar/qt4gui/contract_gui_module.py
@@ -25,9 +25,13 @@
 provides functions which act on the contract of the patient
 at gui level
 '''
+
+import logging
+
 from openmolar.settings import localsettings
 from openmolar.ptModules import planDetails, nhsDetails
 
+LOGGER = logging.getLogger("openmolar")
 
 def handle_ContractTab(om_gui):
     '''
@@ -59,14 +63,14 @@ def changeContractedDentist(om_gui, inits):
     newdentist = localsettings.ops_reverse[str(inits)]
     if newdentist == om_gui.pt.dnt1:
         return
-    if om_gui.pt.cset == "I":
-        om_gui.advise("Let Highland Dental Plan know of this change", 1)
+    if om_gui.pt.cset in ("I", "M"):
+        om_gui.advise(_("Let Highland Dental Plan know of this change"), 1)
     elif om_gui.pt.cset == "N":
         om_gui.advise(
-            "Get an NHS form signed to change the patients contract", 1)
+            _("Get an NHS form signed to change the patients contract"), 1)
     else:
         om_gui.advise("changed dentist to %s" % inits, 1)
-    print("changing contracted dentist to ", inits)
+    LOGGER.debug("changing contracted dentist to %s", inits)
     om_gui.pt.dnt1 = newdentist
     om_gui.updateDetails()
 
@@ -82,11 +86,12 @@ def changeCourseDentist(om_gui, inits):
         return
     if om_gui.pt.cset == "N" and om_gui.pt.underTreatment:
         om_gui.advise(
-            "think about getting some nhs forms signed for both dentists", 1)
+            _("think about getting some nhs forms signed for both dentists"),
+            1)
     else:
-        om_gui.advise("changed course dentist to %s" % inits, 1)
+        om_gui.advise("%s %s" % (_("Changed course dentist to"), inits), 1)
 
-    print("changing course dentist to ", inits)
+    LOGGER.debug("changing course dentist to %s", inits)
     om_gui.pt.dnt2 = newdentist
     om_gui.updateDetails()
 
@@ -97,7 +102,7 @@ def changeCourseType(om_gui, cset):
     '''
     om_gui.pt.cset = str(cset)
     om_gui.updateDetails()
-    i = ["P", "I", "N"].index(om_gui.pt.cset[:1])
+    i = localsettings.CSETYPES.index(om_gui.pt.cset[:1])
     om_gui.ui.contract_tabWidget.setCurrentIndex(i)
     # do this so that the table is reset at any lookup
     om_gui.pt.forget_fee_table()
diff --git a/src/openmolar/qt4gui/customwidgets/appointmentwidget.py b/src/openmolar/qt4gui/customwidgets/appointmentwidget.py
index 9b0b394..57d6dac 100644
--- a/src/openmolar/qt4gui/customwidgets/appointmentwidget.py
+++ b/src/openmolar/qt4gui/customwidgets/appointmentwidget.py
@@ -57,6 +57,7 @@ BLUE_PEN = QtGui.QPen(QtCore.Qt.blue, 2)
 CENTRE_OPTION = QtGui.QTextOption(QtCore.Qt.AlignCenter)
 CENTRE_OPTION.setWrapMode(QtGui.QTextOption.WordWrap)
 
+RIGHT_OPTION = QtGui.QTextOption(QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter)
 
 class AppointmentWidget(QtWidgets.QFrame):
 
@@ -69,6 +70,7 @@ class AppointmentWidget(QtWidgets.QFrame):
     parentWidget =optional
     '''
     selected_serialno = None
+    locations = {}
     BROWSING_MODE = 0
     SCHEDULING_MODE = 1
     BLOCKING_MODE = 2
@@ -81,6 +83,7 @@ class AppointmentWidget(QtWidgets.QFrame):
     print_mh_signal = QtCore.pyqtSignal(object)
     mh_form_date_signal = QtCore.pyqtSignal(object)
     new_memo_signal = QtCore.pyqtSignal(object, object)
+    location_signal = QtCore.pyqtSignal(object)
     edit_memo_signal = QtCore.pyqtSignal(object, object, object)
     block_empty_slot_signal = QtCore.pyqtSignal(object)
     appt_empty_slot_signal = QtCore.pyqtSignal(object)
@@ -231,6 +234,7 @@ class AppointmentWidget(QtWidgets.QFrame):
         self.canvas._drag_rows = None
         self.canvas.freeslots = []
         self.clear_active_slots()
+        self.locations = {}
 
     def clear_active_slots(self):
         self.canvas.active_slots = []
@@ -282,6 +286,7 @@ class AppointmentWidget(QtWidgets.QFrame):
 
         app.startcell = self.canvas.getCell_from_time(str(app.start))
         app.endcell = self.canvas.getCell_from_time(str(app.end))
+        app.location = self.locations.get(app.serialno)
         if app.endcell == app.startcell:  # double and family appointments!!
             app.endcell += 1
             self.canvas.doubleAppts.append(app)
@@ -296,6 +301,13 @@ class AppointmentWidget(QtWidgets.QFrame):
             else:
                 self.canvas.rows[row] = [app.serialno]
 
+
+    def set_locations(self, locations):
+        '''
+        pass a dictionary of patients who are in the building
+        '''
+        self.locations = locations
+
     def addSlot(self, slot):
         '''
         adds a slot to the widget's data
@@ -368,6 +380,7 @@ class AppointmentCanvas(QtWidgets.QWidget):
 
     enabled_slots = True
     ensure_slot_visible = True
+    LOCATION_FONT = QtGui.QFont("Sans", 14, 75)
 
     def __init__(self, pWidget):
         QtWidgets.QWidget.__init__(self, pWidget)
@@ -789,6 +802,8 @@ class AppointmentCanvas(QtWidgets.QWidget):
             elif result.text() == _("Add/Edit Memo"):
                 self.pWidget.edit_memo_signal.emit(tuple(sno_list),
                                                    start, dent)
+            elif result.text() == _("Set Patient Location"):
+                self.pWidget.location_signal.emit(sno_list[0])
             elif result.text() == _("Cancel Appointment"):
                 self.pWidget.cancel_appt(tuple(sno_list), start, dent)
             elif result.text() == _("Clear Block"):
@@ -821,13 +836,13 @@ class AppointmentCanvas(QtWidgets.QWidget):
 
             if sno_list[0] > 0:
                 actions.append(_("Load Patient"))
-
                 actions.append(None)
+                actions.append(_("Set Patient Location"))
                 actions.append(_("Add/Edit Memo"))
                 actions.append(_("Cancel Appointment"))
                 actions.append(None)
-                actions.append(_("Save Medical Form Check Date"))
                 actions.append(_("Print A Medical Form"))
+                actions.append(_("Save Medical Form Check Date"))
 
                 # this next function will emit the appt_clicked_signal
                 self.appointment_clicked(start, finish, sno_list[0])
@@ -939,12 +954,16 @@ class AppointmentCanvas(QtWidgets.QWidget):
 
         selected_rect, highlighted_rect = None, None
         highlighted_rects = []
+        locations = []
         for app in self.appts:
             painter.save()
             rect = QtCore.QRectF(
                 self.timeWidth, app.startcell * self.slotHeight,
                 colwidth - painter.pen().width(),
                 (app.endcell - app.startcell) * self.slotHeight)
+            if app.location:
+                locations.append((app.location, rect.adjusted(0,-10, 0, 10)))
+
             if (app.serialno != 0 and
                     app.serialno == self.pWidget.selected_serialno):
                 painter.setBrush(QtGui.QColor("orange"))
@@ -966,7 +985,8 @@ class AppointmentCanvas(QtWidgets.QWidget):
                 painter.drawRoundedRect(rect, 5, 5)
                 mytext = " ".join((app.name.title(), app.trt1, app.trt2,
                                    app.trt3, app.memo))
-
+                if app.location == "waiting room":
+                    painter.setPen(BLUE_PEN)
                 painter.drawText(rect, mytext, CENTRE_OPTION)
 
             # highlight any appointments booked today
@@ -989,6 +1009,7 @@ class AppointmentCanvas(QtWidgets.QWidget):
                     painter.setBrush(colours.BOOKED_TODAY)
                     painter.drawEllipse(e_rect)
 
+
                 if app.mh_form_required:
                     m_height = app.endcell - app.startcell
                     if m_height > 3:
@@ -1082,6 +1103,15 @@ class AppointmentCanvas(QtWidgets.QWidget):
             polygon.setPoints(triangle)
             painter.drawPolygon(polygon)
 
+        painter.setBrush(QtGui.QBrush(BGCOLOR))
+        painter.save()
+        painter.setPen(BLUE_PEN)
+        painter.setFont(self.LOCATION_FONT)
+        painter.setBrush(colours.BOOKED_TODAY)
+        for location, rect in locations:
+            painter.drawText(rect, "%s " % location[0], RIGHT_OPTION)
+
+        painter.restore()
         if self.dragging:
             painter.setPen(RED_PEN)
             y = self.drag_startrow * self.slotHeight
@@ -1106,7 +1136,7 @@ class AppointmentCanvas(QtWidgets.QWidget):
                 startcell * self.slotHeight,
                 colwidth - 3,
                 (endcell - startcell) * self.slotHeight)
-        painter.setBrush(QtGui.QBrush(BGCOLOR))
+
         if selected_rect:
             painter.setPen(QtGui.QPen(QtGui.QColor("orange"), 3))
             painter.drawRect(selected_rect)
diff --git a/src/openmolar/qt4gui/dialogs/advanced_names_dialog.py b/src/openmolar/qt4gui/dialogs/advanced_names_dialog.py
new file mode 100644
index 0000000..017535a
--- /dev/null
+++ b/src/openmolar/qt4gui/dialogs/advanced_names_dialog.py
@@ -0,0 +1,276 @@
+#! /usr/bin/python
+
+# ########################################################################### #
+# #                                                                         # #
+# # Copyright (c) 2009-2016 Neil Wallace <neil at openmolar.com>               # #
+# #                                                                         # #
+# # This file is part of OpenMolar.                                         # #
+# #                                                                         # #
+# # OpenMolar is free software: you can redistribute it and/or modify       # #
+# # it under the terms of the GNU General Public License as published by    # #
+# # the Free Software Foundation, either version 3 of the License, or       # #
+# # (at your option) any later version.                                     # #
+# #                                                                         # #
+# # OpenMolar is distributed in the hope that it will be useful,            # #
+# # but WITHOUT ANY WARRANTY; without even the implied warranty of          # #
+# # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           # #
+# # GNU General Public License for more details.                            # #
+# #                                                                         # #
+# # You should have received a copy of the GNU General Public License       # #
+# # along with OpenMolar.  If not, see <http://www.gnu.org/licenses/>.      # #
+# #                                                                         # #
+# ########################################################################### #
+
+import logging
+import re
+
+from PyQt5 import QtCore
+from PyQt5 import QtWidgets
+from PyQt5 import QtWebKitWidgets
+
+from openmolar.connect import connect
+
+from openmolar.qt4gui.customwidgets.warning_label import WarningLabel
+from openmolar.qt4gui.customwidgets.upper_case_line_edit \
+    import UpperCaseLineEdit
+from openmolar.qt4gui.dialogs.base_dialogs import BaseDialog
+
+LOGGER = logging.getLogger("openmolar")
+
+PSEUDONYMS_QUERY = '''SELECT ix, alt_fname, alt_sname, comment, search_include
+FROM pseudonyms WHERE serialno=%s'''
+
+INSERT_PSN_QUERY = '''INSERT INTO pseudonyms (serialno, alt_sname, comment)
+VALUES (%s, %s, 'previous surname')'''
+
+INSERT_ALT_QUERY = '''INSERT INTO pseudonyms
+(serialno, alt_fname, alt_sname, comment) VALUES (%s, %s, %s, %s)'''
+
+UPDATE_ALT_QUERY = \
+    'UPDATE pseudonyms SET alt_fname=%s, alt_sname=%s, comment=%s WHERE ix=%s'
+
+DELETE_QUERY = 'DELETE FROM pseudonyms WHERE ix=%s'
+
+HTML = '''
+<html>
+<body>
+<div align="center">
+<h3>%%s %%s</h3>
+</div>
+<h4>%s</h4>
+<ul><li>%%s</li></ul>
+<h4>%s</h4>
+<ul><li>%%s</li></ul>
+''' % (_("Previous Surname(s)"), _("Alternative Name(s)"))
+
+LINK = '''
+%s %s
+<a href='edit_name_%s'>
+<img src='qrc:/icons/pencil.png' height='25' width='25'/>
+</a>
+%s%s'''
+
+class AltNameEntryDialog(BaseDialog):
+
+    def __init__(self, parent=None):
+        BaseDialog.__init__(self, parent)
+        self.setWindowTitle(_("Alternative Name Dialog"))
+
+        self.label = WarningLabel(_("Please enter an alternate name"))
+        self.fname_le = UpperCaseLineEdit()
+        self.sname_le = UpperCaseLineEdit()
+        self.comment_le = QtWidgets.QLineEdit()
+        self.comment_le.setText(_("Alternative Name"))
+
+        frame = QtWidgets.QFrame()
+        layout = QtWidgets.QFormLayout(frame)
+        layout.addRow(_("Alternative First Name"), self.fname_le)
+        layout.addRow(_("Alternative Surname"), self.sname_le)
+        layout.addRow(_("Reason"), self.comment_le)
+
+        self.insertWidget(self.label)
+        self.insertWidget(frame)
+
+        for le in (self.fname_le, self.sname_le, self.comment_le):
+            le.textChanged.connect(self._enable)
+
+    def _enable(self, text):
+        self.enableApply(True)
+
+
+class Pseudonym(object):
+    def __init__(self, ix, fname, sname, comment, search_include):
+        self.ix = ix
+        self.fname = fname if fname else ""
+        self.sname = sname if sname else ""
+        self.comment = comment
+        self.search_include = search_include
+
+    def html(self):
+        comment = "" if self.comment == "previous surname" else \
+            "<br /><em>(%s)</em>" % self.comment
+        inc = "<br />%s" % _("NOT included in searches") \
+            if not self.search_include else ""
+        return LINK % (self.fname, self.sname, self.ix, comment, inc)
+
+
+class AdvancedNamesDialog(BaseDialog):
+    pt = None
+    pseudonyms = []
+
+    def __init__(self, parent=None):
+        BaseDialog.__init__(self, parent)
+        self.setWindowTitle(_("Advanced Names Dialog"))
+
+        label = WarningLabel(_("Previous Surnames, Nicknames, and alternate "
+            "spelling can help when searching for patients"))
+
+        self.browser = QtWebKitWidgets.QWebView(self)
+        self.browser.linkClicked.connect(self.link_clicked)
+
+        self.insertWidget(label)
+        self.insertWidget(self.browser)
+
+        self.cancel_but.hide()
+        self.enableApply()
+
+    def link_clicked(self, url):
+        url_text = url.toString()
+        if url_text == "add_psn":
+            self.add_previous_surname()
+        elif url_text == "add_alt":
+            self.add_alt_name()
+        else:
+            m = re.match(r"edit_name_(\d+)", url_text)
+            if m:
+                ix = int(m.groups()[0])
+                self.edit_name(ix)
+
+    def add_previous_surname(self, psn=""):
+        LOGGER.info("add a surname")
+        if psn == "":
+            message = _("Please enter a previous surname")
+        else:
+            message = "%s '%s' %s" % (_("Save"),
+                                    psn,
+                                    _("as a previous surname?"))
+
+        surname, result = \
+            QtWidgets.QInputDialog.getText(self,
+                                           _("Input required"),
+                                           message,
+                                           QtWidgets.QLineEdit.Normal,
+                                           psn)
+        if result:
+            LOGGER.info("adding %s as a previous surname", surname)
+            db = connect()
+            cursor = db.cursor()
+            cursor.execute(INSERT_PSN_QUERY,
+                           (self.pt.serialno, surname.upper()))
+            cursor.close()
+            self.set_patient(self.pt)
+            return True
+
+    def add_alt_name(self):
+        LOGGER.info("add an alternative name")
+        dl = AltNameEntryDialog(self)
+        if dl.exec_():
+            fname = dl.fname_le.text()
+            sname = dl.sname_le.text()
+            comment = dl.comment_le.text()
+            db = connect()
+            cursor = db.cursor()
+
+            cursor.execute(INSERT_ALT_QUERY, (self.pt.serialno,
+                                              None if not fname else fname,
+                                              None if not sname else sname,
+                                              comment))
+            cursor.close()
+            self.set_patient(self.pt)
+
+    def edit_name(self, ix):
+        LOGGER.info("edit name %s", ix)
+        for pseudonym in self.pseudonyms:
+            if pseudonym.ix == ix:
+                break
+        dl = AltNameEntryDialog(self)
+        dl.label.setText(_("Edit this name (or leave both name fields blank "
+                           "to delete a reference to this name)"))
+        dl.fname_le.setText(pseudonym.fname)
+        dl.sname_le.setText(pseudonym.sname)
+        dl.comment_le.setText(pseudonym.comment)
+        dl.enableApply(False)
+        if dl.exec_():
+            fname = dl.fname_le.text()
+            sname = dl.sname_le.text()
+            comment = dl.comment_le.text()
+            db = connect()
+            cursor = db.cursor()
+            if sname == "" and fname =="":
+                cursor.execute(DELETE_QUERY, (ix,))
+            else:
+                cursor.execute(UPDATE_QUERY, (None if not fname else fname,
+                                              None if not sname else sname,
+                                              comment, ix))
+            cursor.close()
+            self.set_patient(self.pt)
+
+    def set_patient(self, pt):
+        '''
+        pass a patient object to set the serialnumber and name fields.
+        '''
+        self.pt = pt
+        db = connect()
+        cursor = db.cursor()
+        cursor.execute(PSEUDONYMS_QUERY, (pt.serialno,))
+        alts = []
+        for row in cursor.fetchall():
+            pseudonym = Pseudonym(*row)
+            alts.append(pseudonym)
+        self.pseudonyms = alts
+
+        previous = '</li><li>'.join(
+            [p.html() for p in alts if p.comment=="previous surname"] +
+            ['<a href="add_psn">%s</a>' % _("Add New")])
+        alts = '</li><li>'.join(
+            [p.html() for p in alts if p.comment!="previous surname"] +
+            ['<a href="add_alt">%s</a>' % _("Add New")])
+        self.browser.setHtml(HTML % (self.fname, self.sname, previous, alts))
+        page = self.browser.page()
+        page.setLinkDelegationPolicy(page.DelegateAllLinks)
+
+    @property
+    def sname(self):
+        try:
+            return self.pt.sname
+        except AttributeError:
+            pass
+
+    @property
+    def fname(self):
+        try:
+            return self.pt.fname
+        except AttributeError:
+            pass
+
+    def check_save_previous_surname(self, surname):
+        self.show()
+        if self.add_previous_surname(surname):
+            self.exec_()
+
+    def sizeHint(self):
+        return QtCore.QSize(400, 500)
+
+
+if __name__ == "__main__":
+    from openmolar.dbtools import patient_class
+
+    LOGGER.setLevel(logging.DEBUG)
+    app = QtWidgets.QApplication([])
+
+    pt_ = patient_class.patient(32809)
+
+    dl = AdvancedNamesDialog()
+    dl.set_patient(pt_)
+    if dl.exec_():
+       LOGGER.info("changed advanced names for %s %s", dl.sname, dl.fname)
diff --git a/src/openmolar/qt4gui/dialogs/advanced_record_management_dialog.py b/src/openmolar/qt4gui/dialogs/advanced_record_management_dialog.py
index 988a703..cc703e4 100644
--- a/src/openmolar/qt4gui/dialogs/advanced_record_management_dialog.py
+++ b/src/openmolar/qt4gui/dialogs/advanced_record_management_dialog.py
@@ -76,6 +76,7 @@ class AdvancedRecordManagementDialog(BaseDialog):
         '''
         self.ui.total_label.setText(
             localsettings.formatMoney(self.pt.fees))
+        self.ui.money0_spinBox.setValue(self.pt.money0)
         self.ui.money1_spinBox.setValue(self.pt.money1)
         self.ui.money2_spinBox.setValue(self.pt.money2)
         self.ui.money3_spinBox.setValue(self.pt.money3)
diff --git a/src/openmolar/qt4gui/dialogs/base_dialogs.py b/src/openmolar/qt4gui/dialogs/base_dialogs.py
index bf2fefb..61964f3 100644
--- a/src/openmolar/qt4gui/dialogs/base_dialogs.py
+++ b/src/openmolar/qt4gui/dialogs/base_dialogs.py
@@ -125,7 +125,7 @@ class BaseDialog(QtWidgets.QDialog):
                 insertpos -= 1
             if self.extension_frame:
                 insertpos -= 1
-        LOGGER.debug("inserting %s at position %s", widg, insertpos)
+        # LOGGER.debug("inserting %s at position %s", widg, insertpos)
         self.layout_.insertWidget(insertpos, widg)
 
     def _clicked(self, but):
diff --git a/src/openmolar/qt4gui/dialogs/dialog_collection.py b/src/openmolar/qt4gui/dialogs/dialog_collection.py
index 2f504a0..4129021 100644
--- a/src/openmolar/qt4gui/dialogs/dialog_collection.py
+++ b/src/openmolar/qt4gui/dialogs/dialog_collection.py
@@ -90,11 +90,15 @@ from openmolar.qt4gui.dialogs.check_version_dialog import CheckVersionDialog
 from openmolar.qt4gui.dialogs.database_connection_progress_dialog import \
     DatabaseConnectionProgressDialog
 from openmolar.qt4gui.dialogs.account_letter_dialog import AccountLetterDialog
+from openmolar.qt4gui.dialogs.advanced_names_dialog import AdvancedNamesDialog
+from openmolar.qt4gui.dialogs.patient_location_dialog import \
+    PatientLocationDialog, ClearLocationsDialog
 
 __all__ = ['AccountLetterDialog',
            'AccountSeverityDialog',
            'AddClinicianDialog',
            'AddUserDialog',
+           'AdvancedNamesDialog',
            'AdvancedRecordManagementDialog',
            'AdvancedTxPlanningDialog',
            'AlterTodaysNotesDialog',
@@ -107,6 +111,7 @@ __all__ = ['AccountLetterDialog',
            'CheckVersionDialog',
            'ChildSmileDialog',
            'ChooseToothDialog',
+           'ClearLocationsDialog',
            'ClinicianSelectDialog',
            'CorrespondenceDialog',
            'CourseConsistencyDialog',
@@ -135,6 +140,7 @@ __all__ = ['AccountLetterDialog',
            'MedicalHistoryDialog',
            'MedFormCheckDialog',
            'NHSFormsConfigDialog',
+           'PatientLocationDialog',
            'ResetSupervisorPasswordDialog',
            'RecallDialog',
            'SaveDiscardCancelDialog',
diff --git a/src/openmolar/qt4gui/dialogs/first_run_dialog.py b/src/openmolar/qt4gui/dialogs/first_run_dialog.py
index be87771..fea6280 100644
--- a/src/openmolar/qt4gui/dialogs/first_run_dialog.py
+++ b/src/openmolar/qt4gui/dialogs/first_run_dialog.py
@@ -22,6 +22,7 @@
 # ########################################################################### #
 
 import base64
+from functools import partial
 import hashlib
 import logging
 import os
@@ -33,6 +34,8 @@ from PyQt5 import QtCore
 from PyQt5 import QtWidgets
 
 from openmolar.settings import localsettings
+from openmolar import create_db
+
 from openmolar.qt4gui.customwidgets.warning_label import WarningLabel
 from openmolar.qt4gui.dialogs.base_dialogs import BaseDialog
 
@@ -57,10 +60,11 @@ XML_TEMPLATE = '''<?xml version="1.1" ?>
 
 HOST = "localhost"
 PORT = 3306
-DB_USER = "openmolar"
+DB_USER = "openmolar_user"
 DB_PASS = "password"
-DB_NAME = "openmolar"
+DB_NAME = "openmolar_demo"
 
+USER_QUERY = 'SELECT id FROM opid'
 
 class _InputPage(QtWidgets.QWidget):
 
@@ -94,6 +98,18 @@ class _InputPage(QtWidgets.QWidget):
         '''
         return "input error! - try again"
 
+    def unfinished_business(self):
+        '''
+        overwrite if you want to interact with the user before leaving
+        return True to prevent moving on.
+        '''
+        return False
+
+    def enable_next(self, enable=True):
+        QtCore.QTimer.singleShot(100,
+                                 partial(self.dialog.next_but.setEnabled,
+                                         enable))
+
 
 class PageZero(_InputPage):
 
@@ -114,6 +130,9 @@ class PageZero(_InputPage):
         layout = QtWidgets.QVBoxLayout(self.frame)
         layout.addWidget(label)
 
+    def showEvent(self, event):
+        self.enable_next()
+
     @property
     def header_text(self):
         return "<b>%s</b><hr />%s" % (
@@ -155,6 +174,7 @@ class PageOne(_InputPage):
 
     def showEvent(self, event):
         self.line_edit1.setFocus()
+        self.enable_next()
 
     def show_passwords(self, show=False):
         if show:
@@ -216,6 +236,7 @@ class PageTwo(_InputPage):
 
     def showEvent(self, event):
         self.line_edit1.setFocus()
+        self.enable_next()
 
     @property
     def port(self):
@@ -273,32 +294,33 @@ class PageThree(_InputPage):
 
     def showEvent(self, event):
         self.radio_button1.setFocus()
+        self.enable_next()
 
     @property
     def create_new(self):
         return self.radio_button1.isChecked()
 
 
-class PageFour(_InputPage):
+class PageFive(_InputPage):
+    '''
+    Provide a name for the new database and create a user.
+    '''
+    create_new = False
 
     def __init__(self, parent=None):
         _InputPage.__init__(self, parent)
 
-        message = "%s<br />%s" % (
-            _("Please enter connection criteria for the database."),
-            _("If the user and/or database does not exist, "
-              "you will be given an opportunity to create them ")
-        )
-        self.label.setText(message)
-
+        self.m1 = _("Please enter connection criteria for the database.")
+        self.m2 = _("WARNING - If the database of this name already exists on "
+                    "this server, it will be deleted.")
+        self.header_text1 = _("Step 5 - Name Your Database")
+        self.header_text2 = _(
+            "Step 4 - Provide Details of the Existing  Database")
         layout = QtWidgets.QFormLayout(self.frame)
         self.line_edit1 = QtWidgets.QLineEdit()
         self.line_edit2 = QtWidgets.QLineEdit()
         self.line_edit3 = QtWidgets.QLineEdit()
 
-        self.line_edit1.setText(DB_NAME)
-        self.line_edit2.setText(DB_USER)
-        self.line_edit3.setText(DB_PASS)
         self.show_cb = QtWidgets.QCheckBox(_("Show Password"))
 
         layout.addRow(_("Database Name"), self.line_edit1)
@@ -309,12 +331,29 @@ class PageFour(_InputPage):
 
         self.show_cb.toggled.connect(self.show_passwords)
 
+    def set_creating_new(self, create_new):
+        LOGGER.debug("Page 5 creating new = %s", create_new)
+        self.create_new = create_new
+
     @property
     def header_text(self):
-        return "<b>%s</b>" % _("Step 5(a) - Your Database Details")
+        if self.create_new:
+            return "<b>%s</b>" % self.header_text1
+        return "<b>%s</b>" % self.header_text2
 
     def showEvent(self, event):
+        if self.create_new:
+            self.label.setText("%s<hr />%s" % (self.m1, self.m2))
+            if self.line_edit1.text() == "":
+                self.line_edit1.setText(DB_NAME)
+            if self.line_edit2.text() == "":
+                self.line_edit2.setText(DB_USER)
+            if self.line_edit3.text() == "":
+                self.line_edit3.setText(DB_PASS)
+        else:
+            self.label.setText(self.m1)
         self.line_edit1.setFocus()
+        self.enable_next()
 
     def show_passwords(self, show=False):
         if show:
@@ -323,10 +362,30 @@ class PageFour(_InputPage):
             e_mode = QtWidgets.QLineEdit.Password
         self.line_edit3.setEchoMode(e_mode)
 
+    def unfinished_business(self):
+        chosen_dbname = self.line_edit1.text().strip(" ")
+        if chosen_dbname == "" or not self.create_new:
+            return False
+        if (create_db.exists_already(self.dialog.host,
+                                        self.dialog.port,
+                                        chosen_dbname,
+                                        self.dialog.privileged_user_pass,
+                                        self.dialog.privileged_user) and
+                QtWidgets.QMessageBox.question(
+                    self, _("Confirm"),
+                    "%s '%s' %s<hr />%s" % (_("A database named"),
+                                            chosen_dbname,
+                                            _("exists already"),
+                                            _("Overwrite this database?")),
+                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
+                    QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No):
+            return True
+        return False
+
     @property
     def is_completed(self):
         for le in (self.line_edit1, self.line_edit2, self.line_edit3):
-            if le.text() == "":
+            if le.text().strip(" ") == "":
                 return False
         return True
 
@@ -343,7 +402,12 @@ class PageFour(_InputPage):
         return message + "</ul>"
 
 
-class PageFive(_InputPage):
+class PageFour(_InputPage):
+    '''
+    get information about the privileged user and check it has drop and create
+    capabilities
+    '''
+    _messages = []
 
     def __init__(self, parent=None):
         _InputPage.__init__(self, parent)
@@ -369,22 +433,25 @@ class PageFive(_InputPage):
         self.line_edit2 = QtWidgets.QLineEdit()
         self.show_cb = QtWidgets.QCheckBox(_("Show Password"))
 
-        layout.addRow(_("Privileged user"), self.line_edit1)
+        layout.addRow(_("Privileged user (normally 'root')"), self.line_edit1)
         layout.addRow(_("Password for this user"), self.line_edit2)
         layout.addRow("", self.show_cb)
 
         self.show_passwords()
-
         self.show_cb.toggled.connect(self.show_passwords)
+        self.line_edit2.textChanged.connect(self.enable)
 
     @property
     def header_text(self):
         return "<b>%s</b>" % _(
-            "Step 5b - Create an authenticated user and database")
+            "Step 4 - authenticate with MySQL")
 
     def showEvent(self, event):
         self.line_edit2.setFocus()
 
+    def enable(self, *args):
+        self.enable_next(self.input_completed)
+
     def show_passwords(self, show=False):
         if show:
             e_mode = QtWidgets.QLineEdit.Normal
@@ -392,9 +459,25 @@ class PageFive(_InputPage):
             e_mode = QtWidgets.QLineEdit.Password
         self.line_edit2.setEchoMode(e_mode)
 
+    def check_connect(self):
+        result, self._messages = create_db.check_superuser(
+            self.dialog.host,
+            self.dialog.port,
+            self.dialog.privileged_user_pass,
+            self.dialog.privileged_user)
+        return result
+
+    @property
+    def input_completed(self):
+        if self.line_edit1.text() == "":
+            return False
+        if self.line_edit2.text() == "":
+            return False
+        return True
+
     @property
     def is_completed(self):
-        return self.line_edit1.text() != "" and self.line_edit2.text() != ""
+        return self.input_completed and self.check_connect()
 
     @property
     def error_message(self):
@@ -403,19 +486,38 @@ class PageFive(_InputPage):
             message += "<li>%s</li>" % _("Privileged User Field is Blank")
         if self.line_edit2.text() == "":
             message += "<li>%s</li>" % _("Password Field is Blank")
+        message += "<li>%s</li>" % "</li><li>".join (self._messages)
 
         return message + "</ul>"
 
 
+class WorkerThread(QtCore.QThread):
+    '''
+    an example of how to use this
+    wt = WorkerThread()
+    wt.setFunction(some_long_function)
+    wt.finished.connect(something)
+    wt.run()
+    '''
+    result = None
+    def setFunction(self, function):
+        self.function = function
+
+    def run(self):
+        self.result = self.function()
+
+
 class PageSix(_InputPage):
 
     def __init__(self, parent=None):
         _InputPage.__init__(self, parent)
+        self.label.setText(_("Create Database"))
 
         self.db_created = False
-        message = _("Creating Database")
-        self.label.setText(message)
+        self.message = ""
         self.progress_bar = QtWidgets.QProgressBar()
+        self.timer1 = QtCore.QTimer()
+        self.timer1.timeout.connect(self.updatePB)
 
         layout = QtWidgets.QVBoxLayout(self.frame)
         layout.addWidget(self.progress_bar)
@@ -425,77 +527,207 @@ class PageSix(_InputPage):
         return "<b>%s</b>" % _("Step 6 - Create Database")
 
     def showEvent(self, event):
+        self.progress_bar.setValue(0)
+        self.label.setText("%s %s<br />%s '%s' %s '%s'" % (
+            _("Creating Database"),
+            self.dialog.db_name,
+            _("and granting privileges to"),
+            self.dialog.db_user,
+            _("identified by"),
+            "*" * len(self.dialog.db_pass)))
         if not self.db_created:
-            QtCore.QTimer.singleShot(100, self.create_database)
+            self.create_database()
+
+    def hideEvent(self, event):
+        self.timer1.stop()
+
+    def updatePB(self):
+        val = self.progress_bar.value()
+        if val < 90:
+            self.progress_bar.setValue(val + 5)
+            self.progress_bar.update()
 
     def create_database(self):
+        def finished():
+            LOGGER.info("QThread has finished")
+            self.timer1.stop()
+            self.progress_bar.setValue(100)
+            self.db_created, self.message = self.wt.result
+            self.enable_next()
+
+        self.timer1.start(500)  # 1/100thsecond
+        self.progress_bar.setValue(10)
+        self.wt = WorkerThread(self)
+        self.wt.setFunction(partial(create_db.create_database,
+                                    self.dialog.host,
+                                    self.dialog.port,
+                                    self.dialog.db_user,
+                                    self.dialog.db_pass,
+                                    self.dialog.db_name,
+                                    self.dialog.privileged_user_pass,
+                                    self.dialog.privileged_user))
+        self.wt.finished.connect(finished)
+        LOGGER.info("Starting thread")
+        self.wt.start()
+
+    @property
+    def is_completed(self):
+        return self.db_created
+
+    @property
+    def error_message(self):
+        return "%s<hr />%s" % (_("Error Creating Database"), self.message)
+
+
+class PageSeven(_InputPage):
+
+    def __init__(self, parent=None):
+        _InputPage.__init__(self, parent)
+
+        self._schema_installed = False
+        message = _("Creating database tables - this may take some time.")
+        self.label.setText(message)
+        self.progress_bar = QtWidgets.QProgressBar()
+        self.timer1 = QtCore.QTimer()
+        self.timer1.timeout.connect(self.updatePB)
+
+        layout = QtWidgets.QVBoxLayout(self.frame)
+        layout.addWidget(self.progress_bar)
+
+    @property
+    def header_text(self):
+        return "<b>%s</b>" % _("Step 7 - Layout Schema")
+
+    def showEvent(self, event):
         self.progress_bar.setValue(0)
-        PB_LIMIT = 50
+        if not self._schema_installed:
+            self.install_schema()
+
+    def hideEvent(self, event):
+        self.timer1.stop()
+
+    def updatePB(self):
+        val = self.progress_bar.value()
+        if val < 90:
+            self.progress_bar.setValue(val + 5)
+            self.progress_bar.update()
+
+    def install_schema(self):
+        def finished():
+            LOGGER.info("QThread has finished")
+            self.timer1.stop()
+            self.progress_bar.setValue(100)
+            self._schema_installed = self.wt.result
+            self.enable_next()
+
+        self.timer1.start(500)  # 1/100thsecond
+        self.progress_bar.setValue(10)
+        self.wt = WorkerThread(self)
+        self.wt.setFunction(partial(create_db.create_tables,
+                                    self.dialog.host,
+                                    self.dialog.port,
+                                    self.dialog.db_user,
+                                    self.dialog.db_pass,
+                                    self.dialog.db_name))
+        self.wt.finished.connect(finished)
+        LOGGER.info("Starting thread")
+        self.wt.start()
+
+    @property
+    def is_completed(self):
+        return self._schema_installed
+
+    @property
+    def error_message(self):
+        return "%s %s %s<hr />%s<br />%s %s" % (
+                    _("Sql scripts to layout a schema for database"),
+                    self.dialog.db_name,
+                    _("Failed"),
+                    _("Please try again by overwriting this database."),
+                    _("If you continue to stick at this point"),
+                    _("you may need to fix this manually"))
+
+
+class PageEight(_InputPage):
 
-        def updatePB():
-            val = self.progress_bar.value()
-            if val < PB_LIMIT:
-                self.progress_bar.setValue(val + 5)
-                self.progress_bar.update()
+    def __init__(self, parent=None):
+        _InputPage.__init__(self, parent)
 
+        self._data_installed = False
+        message = "%s<br />%s" % (
+            _("Installing a minimum amount of data into the database."),
+            _("This may take some time"))
+        self.label.setText(message)
+        self.progress_bar = QtWidgets.QProgressBar()
         self.timer1 = QtCore.QTimer()
-        self.timer1.timeout.connect(updatePB)
+        self.timer1.timeout.connect(self.updatePB)
 
-        try:
-            from openmolar import create_db
-            if (create_db.exists_already(self.dialog.host,
-                                         self.dialog.port,
-                                         self.dialog.db_name,
-                                         self.dialog.privileged_user_pass,
-                                         self.dialog.privileged_user) and
-                    QtWidgets.QMessageBox.question(
-                        self, _("Confirm"),
-                        "%s '%s' %s<hr />%s" % (_("A database named"),
-                                                self.dialog.db_name,
-                                                _("exists already"),
-                                                _("Overwrite this database?")),
-                        QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
-                        QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No):
-                self.dialog.database_exists_already()
-                return
-            self.timer1.start(10)  # 1/100thsecond
-
-            self.progress_bar.setValue(10)
-            create_db.create_database(
-                self.dialog.host,
-                self.dialog.port,
-                self.dialog.db_user,
-                self.dialog.db_pass,
-                self.dialog.db_name,
-                self.dialog.privileged_user_pass,
-                self.dialog.privileged_user
-            )
+        layout = QtWidgets.QVBoxLayout(self.frame)
+        layout.addWidget(self.progress_bar)
+
+    @property
+    def header_text(self):
+        return "<b>%s</b>" % _("Step 8 - Install data into database")
 
-            self.progress_bar.setValue(50)
-            PB_LIMIT = 90
-            create_db.create_tables(self.dialog.host,
+    def showEvent(self, event):
+        self.progress_bar.setValue(0)
+        if not self._data_installed:
+            self.install_data()
+
+    def hideEvent(self, event):
+        self.timer1.stop()
+
+    def updatePB(self):
+        val = self.progress_bar.value()
+        if val < 90:
+            self.progress_bar.setValue(val + 3)
+            self.progress_bar.update()
+
+    def install_data(self):
+        def finished():
+            LOGGER.info("QThread has finished")
+            self.timer1.stop()
+            self.progress_bar.setValue(100)
+            self._data_installed = self.wt.result
+            self.enable_next()
+
+        minimal_only = QtWidgets.QMessageBox.question(
+            self, _("Choice"),
+            _("Would you like an example patient in the database?"),
+            QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
+            QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No
+
+        self.timer1.start(500)
+        self.progress_bar.setValue(10)
+        self.wt = WorkerThread(self)
+        self.wt.setFunction(partial(create_db.insert_data,
+                                    self.dialog.host,
                                     self.dialog.port,
                                     self.dialog.db_user,
                                     self.dialog.db_pass,
                                     self.dialog.db_name,
-                                    )
+                                    minimal_only))
+        self.wt.finished.connect(finished)
+        LOGGER.info("Starting thread")
+        self.wt.start()
 
-            self.progress_bar.setValue(100)
-            QtWidgets.QMessageBox.information(
-                self,
-                _("Success!"),
-                _("Database created successfully!")
-            )
-            self.db_created = True
-            next(self.dialog)
-        except Exception as exc:
-            LOGGER.exception("error creating database")
-            message = "%s<hr />%s" % (_("Error Creating Database"), exc)
-            QtWidgets.QMessageBox.warning(self, _("Error"), message)
-            self.db_created = False
+    @property
+    def is_completed(self):
+        return self._data_installed
 
+    @property
+    def error_message(self):
+        return "%s %s %s<hr />%s" % (
+                _("inserting data into"),
+                self.dialog.db_name,
+                _("Failed"),
+                _("you may need to fix this manually"))
 
-class PageSeven(_InputPage):
+
+class PageNine(_InputPage):
+    _connection_works = False
+    _users_present = False
+    single_user = None
 
     def __init__(self, parent=None):
         _InputPage.__init__(self, parent)
@@ -508,10 +740,13 @@ class PageSeven(_InputPage):
             "Final Step - Test Connection & Write Config File")
 
     def showEvent(self, event):
-        QtCore.QTimer.singleShot(100, self.test_connection)
+        QtCore.QTimer.singleShot(500, self.test_connection)
 
     def test_connection(self):
         self.dialog.wait()
+        self.single_user = None
+        self._connection_works = False
+        self._users_present = False
         try:
             LOGGER.info("attempting to connect to mysql server")
 
@@ -521,23 +756,61 @@ class PageSeven(_InputPage):
                                  passwd=self.dialog.db_pass,
                                  user=self.dialog.db_user)
             db.open
+            self._connection_works = True
+            cursor = db.cursor()
+            cursor.execute(USER_QUERY)
+            rows = cursor.fetchall()
+            n_users = len(rows)
+            self._users_present = n_users > 0
+            if n_users == 1:
+                self.single_user = rows[0][0]
             db.close()
-            self.dialog.wait(False)
-            self.label.setText(_("Your database is accepting connections!"))
-            return True
         except Exception:
-            self.dialog.wait(False)
-            LOGGER.exception("connection attempt failed")
+            LOGGER.exception("database interaction failed")
+        self.enable_next()
+        self.dialog.wait(False)
+        if self._connection_works:
+            self.label.setText(
+                "<h2>%s</h2>%s '%s' %s '%s:%s' %s<hr />(%s '%s:%s')" % (
+                    _("SUCCESS!"),
+                    _("Database"),
+                    self.dialog.db_name,
+                    _("on server"),
+                    self.dialog.host,
+                    self.dialog.port,
+                    _("is accepting connections!"),
+                    _("Authenticating as"),
+                    self.dialog.db_user,
+                    "*" * len(self.dialog.db_pass)
+                ))
+        else:
             self.label.setText("<b>%s</b> %s" % (
                 _("WARNING"),
                 _("Your database is NOT accepting connections!"))
             )
-            return False
-        finally:
-            self.dialog.wait(False)
+        self.show_warnings()
+
+    @property
+    def is_completed(self):
+        return True
+    def show_warnings(self):
+        if self._connection_works and self._users_present:
+            return
+        if not self._connection_works:
+            QtWidgets.QMessageBox.warning(
+                self, _("Warning"),
+                _("Openmolar is unable to connect to the database "
+                  "you have configured."))
+        elif not self._users_present:
+            QtWidgets.QMessageBox.warning(
+                self, _("Warning"),
+                "%s<hr /><b>%s</b>" % (
+                _("There are no users in the database you have configured."),
+                _("You will not be able to log in!")))
 
 
 class FirstRunDialog(BaseDialog):
+    EXISTING_DB_ORDER = [0,1,2,3,5,9]
 
     def __init__(self, parent=None):
         BaseDialog.__init__(self, parent)
@@ -554,8 +827,9 @@ class FirstRunDialog(BaseDialog):
         self.page4 = PageFour(self)
         self.page5 = PageFive(self)
         page6 = PageSix(self)
-        self.page7 = PageSeven(self)
-        # accept_page = AcceptPage(self)
+        page7 = PageSeven(self)
+        self.page8 = PageEight(self)
+        self.page9 = PageNine(self)
 
         self.wizard_widget.addWidget(page0)
         self.wizard_widget.addWidget(self.page1)
@@ -564,8 +838,9 @@ class FirstRunDialog(BaseDialog):
         self.wizard_widget.addWidget(self.page4)
         self.wizard_widget.addWidget(self.page5)
         self.wizard_widget.addWidget(page6)
-        self.wizard_widget.addWidget(self.page7)
-        # self.wizard_widget.addWidget(accept_page)
+        self.wizard_widget.addWidget(page7)
+        self.wizard_widget.addWidget(self.page8)
+        self.wizard_widget.addWidget(self.page9)
 
         self.insertWidget(self.top_label)
         self.insertWidget(self.wizard_widget)
@@ -592,13 +867,14 @@ class FirstRunDialog(BaseDialog):
             QtWidgets.QApplication.instance().restoreOverrideCursor()
 
     def set_labels(self):
+        self.next_but.setEnabled(False)
         self.top_label.setText(self.current_page.header_text)
         self.cancel_but.setVisible(self.current_index == 0)
         self.back_but.setVisible(self.current_index != 0)
 
-        if self.current_index == 5:
+        if self.current_index == 5 and self.creating_new_database:
             self.next_but.setText(_("Create Database Now!"))
-        elif self.current_index == 7:
+        elif self.current_index == 9:
             self.next_but.setText(_("Write Config File and Proceed"))
         else:
             self.next_but.setText(_("Next"))
@@ -612,21 +888,25 @@ class FirstRunDialog(BaseDialog):
         4 = database details (dbname, user and password)
         5 = enter privileged user
         6 = create database
-        7 = test connection, write config and exit.
+        7 = layout schema
+        8 = test connection, write config and exit.
         '''
         i = self.wizard_widget.currentIndex()
+        if self.current_page.unfinished_business():
+            return
         if not self.current_page.is_completed:
-            QtWidgets.QMessageBox.warning(self,
-                                          _("error"),
+            QtWidgets.QMessageBox.warning(self, _("error"),
                                           self.current_page.error_message)
             new_i = i
-        elif i == 4 and not self.page3.create_new:
-            new_i = i + 3
-        elif i == 7:
+        elif i == 9:
             self.finish()
             return
+        elif not self.creating_new_database:
+            new_i = self.EXISTING_DB_ORDER[self.EXISTING_DB_ORDER.index(i) + 1]
         else:
             new_i = i + 1
+        LOGGER.debug("next page is page %s", new_i)
+        self.page5.set_creating_new(self.creating_new_database)
         self.wizard_widget.setCurrentIndex(new_i)
         self.set_labels()
 
@@ -634,8 +914,10 @@ class FirstRunDialog(BaseDialog):
         i = self.wizard_widget.currentIndex()
         if i == 0:
             new_i = 0
-        elif i == 7:  # shouldn't happen?
+        elif i == 9:  # shouldn't happen?
             new_i = 0  # don't create a database by hitting "back"
+        elif not self.creating_new_database:
+            new_i = self.EXISTING_DB_ORDER[self.EXISTING_DB_ORDER.index(i) - 1]
         else:
             new_i = i - 1
         self.wizard_widget.setCurrentIndex(new_i)
@@ -645,6 +927,10 @@ class FirstRunDialog(BaseDialog):
         self.wizard_widget.setCurrentIndex(4)
         self.set_labels()
 
+    def table_creation_failed(self):
+        self.wizard_widget.setCurrentIndex(4)
+        self.set_labels()
+
     def finish(self):
         dom = minidom.parseString(XML_TEMPLATE)
         #  hash the password (twice) and save it
@@ -708,7 +994,7 @@ class FirstRunDialog(BaseDialog):
             localsettings.cflocation = localsettings.cflocation
 
         conf_text = "[login]\nPASSWORD=\nUSER1=\nUSER2="
-        if self.page3.create_new:
+        if self.page9.single_user:
             conf_text = conf_text.replace("USER1=", "USER1=USER")
         f = open(localsettings.LOGIN_CONF, "w")
         f.write(conf_text)
@@ -749,20 +1035,24 @@ class FirstRunDialog(BaseDialog):
 
     @property
     def db_name(self):
-        return str(self.page4.line_edit1.text())
+        return str(self.page5.line_edit1.text())
 
     @property
     def db_user(self):
-        return str(self.page4.line_edit2.text())
+        return str(self.page5.line_edit2.text())
 
     @property
     def db_pass(self):
-        return str(self.page4.line_edit3.text())
+        return str(self.page5.line_edit3.text())
 
     @property
     def privileged_user(self):
-        return str(self.page5.line_edit1.text())
+        return str(self.page4.line_edit1.text())
 
     @property
     def privileged_user_pass(self):
-        return str(self.page5.line_edit2.text())
+        return str(self.page4.line_edit2.text())
+
+    @property
+    def creating_new_database(self):
+        return self.page3.create_new
diff --git a/src/openmolar/qt4gui/dialogs/newCourse.py b/src/openmolar/qt4gui/dialogs/newCourse.py
index 531afee..61e4492 100644
--- a/src/openmolar/qt4gui/dialogs/newCourse.py
+++ b/src/openmolar/qt4gui/dialogs/newCourse.py
@@ -71,7 +71,7 @@ class NewCourseDialog(Ui_newCourse.Ui_Dialog, QtWidgets.QDialog):
                 retarg = (dnt1, dnt2, cset, self.dateEdit.date())
                 if "" in retarg:
                     QtWidgets.QMessageBox.information(
-                        self.dialog,
+                        self.parent(),
                         _("Error"), _("Some fields are missing, please check"))
                 else:
                     return (True, retarg)
diff --git a/src/openmolar/qt4gui/dialogs/patient_location_dialog.py b/src/openmolar/qt4gui/dialogs/patient_location_dialog.py
new file mode 100644
index 0000000..0be3db1
--- /dev/null
+++ b/src/openmolar/qt4gui/dialogs/patient_location_dialog.py
@@ -0,0 +1,143 @@
+#! /usr/bin/python
+
+# ########################################################################### #
+# #                                                                         # #
+# # Copyright (c) 2009-2016 Neil Wallace <neil at openmolar.com>               # #
+# #                                                                         # #
+# # This file is part of OpenMolar.                                         # #
+# #                                                                         # #
+# # OpenMolar is free software: you can redistribute it and/or modify       # #
+# # it under the terms of the GNU General Public License as published by    # #
+# # the Free Software Foundation, either version 3 of the License, or       # #
+# # (at your option) any later version.                                     # #
+# #                                                                         # #
+# # OpenMolar is distributed in the hope that it will be useful,            # #
+# # but WITHOUT ANY WARRANTY; without even the implied warranty of          # #
+# # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           # #
+# # GNU General Public License for more details.                            # #
+# #                                                                         # #
+# # You should have received a copy of the GNU General Public License       # #
+# # along with OpenMolar.  If not, see <http://www.gnu.org/licenses/>.      # #
+# #                                                                         # #
+# ########################################################################### #
+
+import logging
+import re
+
+from PyQt5 import QtCore
+from PyQt5 import QtWidgets
+
+from openmolar.settings import localsettings
+from openmolar.connect import connect
+
+from openmolar.qt4gui.customwidgets.warning_label import WarningLabel
+from openmolar.qt4gui.dialogs.base_dialogs import BaseDialog
+
+LOGGER = logging.getLogger("openmolar")
+
+UPDATE_LOC_QUERY = 'REPLACE into locations (serialno, location) values (%s, %s)'
+
+DELETE_QUERY = 'DELETE FROM locations WHERE serialno=%s'
+
+DELETE_ALL_QUERY = 'DELETE FROM locations'
+
+GET_NAME_QUERY = \
+    'SELECT CONCAT(fname, " ", sname) from new_patients where serialno=%s'
+
+## TODO - put these into the database or maybe local settings folder?
+localsettings.PATIENT_LOCATIONS = {"W": _("Waiting Room"),
+                                   "T": _("Toilet"),
+                                   "1": _("Surgery 1"),
+                                   "2": _("Surgery 2"),
+                                   "3": _("Surgery 3")}
+
+
+class ClearLocationsDialog(BaseDialog):
+    def __init__(self, parent=None):
+        BaseDialog.__init__(self, parent)
+        self.setWindowTitle(_("Confirm"))
+
+        label = WarningLabel(_("Clear ALL Patient Locations?"))
+        self.insertWidget(label)
+        self.enableApply()
+
+    def exec_(self):
+        result = BaseDialog.exec_(self)
+        if result:
+            db = connect()
+            cursor = db.cursor()
+            cursor.execute(DELETE_ALL_QUERY)
+            cursor.close()
+            db.commit()
+
+        return result
+
+
+class PatientLocationDialog(BaseDialog):
+    _name = None
+    message = ""
+
+    def __init__(self, sno, parent=None):
+        BaseDialog.__init__(self, parent)
+        self.setWindowTitle(_("Patient Location Dialog"))
+        self.serialno = sno
+
+        label = WarningLabel("%s %s" % (_("Update the location of"),
+                                             self.name))
+        self.insertWidget(label)
+
+        for location in sorted(localsettings.PATIENT_LOCATIONS.values()):
+            button = QtWidgets.QPushButton(location)
+            button.clicked.connect(self.button_clicked)
+            self.insertWidget(button)
+
+        button = QtWidgets.QPushButton(_("Clear Patient Location"))
+        button.clicked.connect(self.clear_patient)
+        button.setMinimumHeight(80)
+        self.insertWidget(button)
+        self.apply_but.hide()
+
+    def sizeHint(self):
+        return QtCore.QSize(400, 500)
+
+    @property
+    def name(self):
+        if self._name is None:
+            db = connect()
+            cursor = db.cursor()
+            cursor.execute(GET_NAME_QUERY, (self.serialno,))
+            self._name = cursor.fetchone()[0]
+            cursor.close()
+        return self._name
+
+    def button_clicked(self):
+        location = self.sender().text()
+        rev_dict = {v:k for k, v in localsettings.PATIENT_LOCATIONS.items()}
+        key = rev_dict[location]
+        self.message = "Patient %s is in %s" % (self.serialno, location)
+        LOGGER.debug(self.message)
+        db = connect()
+        cursor = db.cursor()
+        cursor.execute(UPDATE_LOC_QUERY, (self.serialno, key))
+        cursor.close()
+        db.commit()
+        self.accept()
+
+    def clear_patient(self):
+        self.message = "Patient %s has left" % self.serialno
+        LOGGER.debug(self.message)
+        db = connect()
+        cursor = db.cursor()
+        cursor.execute(DELETE_QUERY, (self.serialno,))
+        cursor.close()
+        db.commit()
+        self.accept()
+
+
+if __name__ == "__main__":
+
+    LOGGER.setLevel(logging.DEBUG)
+    app = QtWidgets.QApplication([])
+
+    dl = PatientLocationDialog(1)
+    dl.exec_()
diff --git a/src/openmolar/qt4gui/diary_widget.py b/src/openmolar/qt4gui/diary_widget.py
index 0d6189c..fae84f9 100644
--- a/src/openmolar/qt4gui/diary_widget.py
+++ b/src/openmolar/qt4gui/diary_widget.py
@@ -35,6 +35,7 @@ from PyQt5 import QtWidgets
 from openmolar.settings import localsettings
 
 from openmolar.dbtools import appointments
+from openmolar.dbtools import locations
 from openmolar.dbtools import search
 from openmolar.dbtools.brief_patient import BriefPatient
 from openmolar.ptModules import formatted_notes
@@ -88,6 +89,7 @@ class DiaryWidget(Advisor):
     pt_diary_changed = QtCore.pyqtSignal(object)
     bring_to_front = QtCore.pyqtSignal()
     print_mh_signal = QtCore.pyqtSignal(object)
+    location_signal = QtCore.pyqtSignal(object)
     mh_form_date_signal = QtCore.pyqtSignal(object)
 
     alterAday_clipboard = []  # clipboard used by the alterAday dialog
@@ -943,6 +945,7 @@ class DiaryWidget(Advisor):
 
         self.appointmentData.setDate(date_)
         self.appointmentData.getAppointments(dents)
+        patient_locations = locations.locations()
 
         if self.schedule_controller.mode == self.SCHEDULING_MODE:
             # self.schedule_controller.clear_slots()
@@ -977,6 +980,7 @@ class DiaryWidget(Advisor):
             book = self.apptBookWidgets[i]
 
             book.setDentist(dent)
+            book.set_locations(patient_locations)
 
             book.setDayStartTime(abs_start)
             book.setDayEndTime(abs_end)
@@ -1502,6 +1506,7 @@ class DiaryWidget(Advisor):
         book.appt_dropped_signal.connect(self.appt_dropped_onto_daywidget)
         book.slot_clicked_signal.connect(self.userHasChosen_slot)
         book.print_mh_signal.connect(self.print_mh_signal.emit)
+        book.location_signal.connect(self.location_signal.emit)
         book.mh_form_date_signal.connect(self.mh_form_date_signal.emit)
         book.appt_clicked_signal.connect(self.update_highlighted_appointment)
 
diff --git a/src/openmolar/qt4gui/forum_widget.py b/src/openmolar/qt4gui/forum_widget.py
index 5fdfa6e..0f2a642 100644
--- a/src/openmolar/qt4gui/forum_widget.py
+++ b/src/openmolar/qt4gui/forum_widget.py
@@ -41,16 +41,56 @@ from openmolar.qt4gui.customwidgets.warning_label import WarningLabel
 LOGGER = logging.getLogger("openmolar")
 
 
+class GetForumPosterDialog(BaseDialog):
+    '''
+    raise a dialog to determine who is posting to the forum
+    '''
+
+    _user = None
+
+    def __init__(self, user, parent=None):
+        BaseDialog.__init__(self, parent)
+
+        label = WarningLabel(
+            "%s %s<hr /> %s" % (user,
+                                _("is not allowed to post."),
+                                _("Who are you?")))
+        frame = QtWidgets.QFrame()
+        layout = QtWidgets.QVBoxLayout(frame)
+
+        scroll_area = QtWidgets.QScrollArea()
+        scroll_area.setWidgetResizable(True)
+        scroll_area.setWidget(frame)
+
+        for op in localsettings.allowed_logins:
+            if op not in localsettings.disallowed_forum_posters:
+                but = QtWidgets.QPushButton(op)
+                but.clicked.connect(self.but_clicked)
+                layout.addWidget(but)
+
+        self.insertWidget(label)
+        self.insertWidget(scroll_area)
+
+    @property
+    def chosen_user(self):
+        return self._user
+
+    def but_clicked(self):
+        but = self.sender()
+        self._user = but.text()
+        self.accept()
+
+
 class GetForumUserDialog(BaseDialog):
+    '''
+    raise a dialog to determine who is browsing the forum.
+    if check is False, dialog will not show if there is only one registered
+    user.
+    '''
 
     _user = None
 
     def __init__(self, check=False, parent=None):
-        '''
-        raise a dialog to determine who is browsing the forum.
-        if check is False, dialog will not show if there is only one registered
-        user.
-        '''
         BaseDialog.__init__(self, parent)
         self.check = check
         self.enableApply()
@@ -112,6 +152,7 @@ class ForumWidget(QtWidgets.QWidget):
     parenting_mode = (False, None)
     spliiter_resized = False
     _forum_user = None
+    _forum_poster = None
     DEFAULT_BRUSH = QtGui.QBrush()
     BLUE_BRUSH = QtGui.QBrush(QtGui.QColor("blue"))
     RED_BRUSH = QtGui.QBrush(QtGui.QColor("red"))
@@ -202,6 +243,7 @@ class ForumWidget(QtWidgets.QWidget):
 
     def change_user_but_clicked(self):
         self.apply_new_reads()
+        self._forum_poster = None
         self._forum_user = self.forum_user(check=True)
         self.loadForum()
 
@@ -211,6 +253,7 @@ class ForumWidget(QtWidgets.QWidget):
         self.loadForum()
 
     def showEvent(self, event=None):
+        LOGGER.info("ForumWidget showEvent")
         self.timer.stop()
         if not self.spliiter_resized:
             self.splitter.setSizes([self.width()*.7, self.width()*.3])
@@ -222,10 +265,21 @@ class ForumWidget(QtWidgets.QWidget):
         parenting_mode = (False, None)
         self.cancel_parenting_mode()
         self._forum_user = None
+        self._forum_poster = None
         self.departed_signal.emit()
         self.timer.start(60000)  # fire every minute
 
+    def forum_poster(self):
+        if self._forum_poster is None:
+            self._forum_poster = self.forum_user()
+        if self._forum_poster in localsettings.disallowed_forum_posters:
+            dl = GetForumPosterDialog(self._forum_poster, self)
+            dl.exec_()
+            self._forum_poster = dl.chosen_user
+        return self._forum_poster
+
     def forum_user(self, check=False):
+        LOGGER.info("forum_user called")
         if check or self._forum_user is None:
             self.read_ids = set([])
             dl = GetForumUserDialog(check, self)
@@ -414,13 +468,13 @@ class ForumWidget(QtWidgets.QWidget):
                 raise exc
             finally:
                 self.cancel_parenting_mode()
+                self.loadForum()
         else:
             QtCore.QTimer.singleShot(3000, partial(self.mark_as_read, post.ix))
 
     def cancel_parenting_mode(self):
         self.parenting_mode = (False, None)
         self.parent_button.setStyleSheet("")
-        self.loadForum()
 
     def mark_as_read(self, ix):
         item = self.tree_widget.currentItem()
@@ -459,6 +513,7 @@ class ForumWidget(QtWidgets.QWidget):
                     QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.Yes:
                 forum.deletePost(post.ix)
         self.loadForum()
+
     def toggle_importance(self):
         item = self.tree_widget.currentItem()
         if item is None:
@@ -505,7 +560,7 @@ class ForumWidget(QtWidgets.QWidget):
         post = forum.ForumPost()
         post.topic = dl.topic_lineEdit.text()
         post.comment = dl.comment_textEdit.toPlainText()
-        post.inits = self.forum_user()
+        post.inits = self.forum_poster()
         if dl.to_comboBox.currentIndex != 0:
             post.recipient = dl.to_comboBox.currentText()
         ix = forum.commitPost(post)
@@ -553,7 +608,7 @@ class ForumWidget(QtWidgets.QWidget):
             newpost.parent_ix = post.ix
             newpost.topic = dl.topic_lineEdit.text()
             newpost.comment = dl.comment_textEdit.toPlainText()
-            newpost.inits = self.forum_user()
+            newpost.inits = self.forum_poster()
             newpost.recipient = dl.to_comboBox.currentText()
             ix = forum.commitPost(newpost)
             self.read_ids.add(ix)
@@ -600,6 +655,7 @@ if __name__ == "__main__":
 
     localsettings.initiateUsers()
     localsettings.operator = "NW"
+    localsettings.disallowed_forum_posters = ["NW"]
     LOGGER.setLevel(logging.DEBUG)
     app = QtWidgets.QApplication([])
     mw = ForumMainWindow()
diff --git a/src/openmolar/qt4gui/maingui.py b/src/openmolar/qt4gui/maingui.py
index 1712f22..0a2d90e 100755
--- a/src/openmolar/qt4gui/maingui.py
+++ b/src/openmolar/qt4gui/maingui.py
@@ -67,7 +67,6 @@ from openmolar.qt4gui.compiled_uis import Ui_main
 from openmolar.qt4gui.compiled_uis import Ui_surgeryNumber
 from openmolar.qt4gui.compiled_uis import Ui_showMemo
 
-
 # -custom dialog modules
 from openmolar.qt4gui.dialogs import permissions
 
@@ -76,6 +75,7 @@ from openmolar.qt4gui.dialogs.dialog_collection import (
     AccountSeverityDialog,
     AddClinicianDialog,
     AddUserDialog,
+    AdvancedNamesDialog,
     AdvancedRecordManagementDialog,
     AdvancedTxPlanningDialog,
     AlterTodaysNotesDialog,
@@ -88,6 +88,7 @@ from openmolar.qt4gui.dialogs.dialog_collection import (
     ChildSmileDialog,
     ChooseToothDialog,
     ClinicianSelectDialog,
+    ClearLocationsDialog,
     CorrespondenceDialog,
     CourseConsistencyDialog,
     CourseEditDialog,
@@ -115,6 +116,7 @@ from openmolar.qt4gui.dialogs.dialog_collection import (
     MedicalHistoryDialog,
     MedFormCheckDialog,
     NHSFormsConfigDialog,
+    PatientLocationDialog,
     ResetSupervisorPasswordDialog,
     RecallDialog,
     SaveDiscardCancelDialog,
@@ -148,6 +150,7 @@ from openmolar.dbtools.distinct_statuses import DistinctStatuses
 from openmolar.dbtools import schema_version
 from openmolar.dbtools import referral
 from openmolar.dbtools import records_in_use
+from openmolar.dbtools import locations
 
 # -modules which act upon the pt class type (and subclasses)
 from openmolar.ptModules import patientDetails
@@ -192,6 +195,7 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
     summary_notes_loaded = False
     notes_loaded = False
     _db_connnection_progress_dialog = None
+    _reloading_record = False
 
     def __init__(self, parent=None):
         QtWidgets.QMainWindow.__init__(self, parent)
@@ -425,6 +429,14 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
         QtWidgets.QMainWindow.resizeEvent(self, event)
         self.setBriefMessageLocation()
 
+    def showEvent(self, event):
+        '''
+        this function is overwritten so that the advisor popup can be
+        put in the correct place
+        '''
+        QtWidgets.QMainWindow.showEvent(self, event)
+        QtCore.QTimer.singleShot(100, self.setBriefMessageLocation)
+
     def setBriefMessageLocation(self):
         '''
         make the Advisor sub class aware of the windows geometry.
@@ -712,9 +724,10 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
         if self.pt.serialno == 0:
             return True
 
-        course_module.prompt_close_course(self)
-        if not course_module.recall_check(self):
-            return False
+        if not self._reloading_record:
+            course_module.prompt_close_course(self)
+            if not course_module.recall_check(self):
+                return False
 
         # -apply changes to patient details
         self.pt.synopsis = str(self.ui.synopsis_lineEdit.text())
@@ -856,7 +869,6 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
         '''
         if self.pt.serialno != 0:
             LOGGER.debug("clearing record")
-            self.clear_record_in_use()
             self.forget_notes_loaded()
             self.ui.dobEdit.setDate(QtCore.QDate(1900, 1, 1))
             self.ui.detailsBrowser.setText("")
@@ -882,6 +894,9 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
 
             self.ui.medNotes_pushButton.setStyleSheet("")
             self.ui.medNotes_pushButton2.setStyleSheet("")
+            if not self._reloading_record:
+                self.prompt_clear_location()
+            self.clear_record_in_use()
 
             # -load a blank version of the patient class
             self.pt = patient_class.patient(0)
@@ -1306,7 +1321,7 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
         else:
             current_address = localsettings.LAST_ADDRESS
 
-        self.clear_record_in_use()
+        self.clearRecord()
         try:
             # update saved last address
             self.pt = patient_class.patient(serialno)
@@ -1353,11 +1368,13 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
         '''
         reload the current record
         '''
+        self._reloading_record = True
         if self.okToLeaveRecord():
             sno = self.pt.serialno
             self.advise("%s %s" % (_("Reloading record"), sno))
             self.clearRecord()
             self.getrecord(sno)
+        self._reloading_record = False
 
     def set_note_preferences(self):
         formatted_notes.show_printed = \
@@ -1676,12 +1693,16 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
 
     def set_surgery_mode(self, is_surgery=None):
         if is_surgery is None:
-            is_surgery = localsettings.station == "surgery"
+            is_surgery = self.surgery_mode
         localsettings.station = "surgery" if is_surgery else "reception"
         self.ui.actionSurgery_Mode.setChecked(is_surgery)
         self.set_operator_label()
         self.gotoDefaultTab()
 
+    @property
+    def surgery_mode(self):
+        return localsettings.station == "surgery"
+
     def set_operator_label(self):
         if localsettings.clinicianNo == 0:
             if localsettings.station == "surgery":
@@ -1992,6 +2013,7 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
             # - only make changes if user has visited this tab
             self.apply_editpage_changes()
         self.pt.monies_reset = patient_write_changes.reset_money(self.pt)
+        self.check_previous_surname()
         uc = self.unsavedChanges()
         if uc != []:
             LOGGER.info(
@@ -2082,6 +2104,7 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
                      self.ui.xray_pushButton,
                      self.ui.newBPE_pushButton,
                      self.ui.hygWizard_pushButton,
+                     self.ui.set_location_button,
                      self.ui.childsmile_button,
                      self.ui.completedChartWidget):
             widg.setEnabled(enable_tx_buts)
@@ -2836,6 +2859,7 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
         self.ui.actionSurgery_Mode.toggled.connect(self.set_surgery_mode)
         self.ui.actionDocuments_Dialog.triggered.connect(
             self.documents_pushButton_clicked)
+        self.ui.set_location_button.clicked.connect(self.set_patient_location)
 
     def signals_admin(self):
         # admin frame
@@ -2962,6 +2986,7 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
             self.configure_feescales)
         self.ui.actionEdit_Account_Letter_Settings.triggered.connect(
             self.edit_account_letter_settings)
+        self.ui.actionClear_Locations.triggered.connect(self.clear_locations)
 
     def signals_estimates(self):
         # Estimates and Course Management
@@ -3153,6 +3178,7 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
         self.ui.save_new_patient_pushButton.clicked.connect(
             self.checkNewPatient)
         self.ui.abort_new_patient_pushButton.clicked.connect(self.home)
+        self.ui.advanced_names_pushButton.clicked.connect(self.advanced_names)
 
     def signals_notesPage(self):
         # notes page
@@ -3184,6 +3210,7 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
         self.diary_widget.pt_diary_changed.connect(
             self.pt_diary_widget.refresh_ptDiary)
         self.diary_widget.print_mh_signal.connect(self.print_mh_forms)
+        self.diary_widget.location_signal.connect(self.patient_location)
         self.diary_widget.mh_form_date_signal.connect(self.diary_mh_form_date)
         self.pt_diary_widget.start_scheduling_signal.connect(self.start_scheduling)
         self.pt_diary_widget.find_appt.connect(self.diary_widget.find_appt)
@@ -3322,6 +3349,14 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
             email = self.ui.email1Edit.text()
         webbrowser.open("mailto:%s" % email)
 
+    def advanced_names(self):
+        self.apply_editpage_changes()
+        dl = AdvancedNamesDialog(self)
+        dl.set_patient(self.pt)
+        if dl.exec_():
+            self.ui.snameEdit.setText(dl.sname)
+            self.ui.fnameEdit.setText(dl.fname)
+
     def load_pt_statuses(self):
         ds = DistinctStatuses()
         self.ui.status_comboBox.addItems(ds.DISTINCT_STATUSES)
@@ -3611,6 +3646,7 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
         check to see who may be using the current record.
         called when the records_in_use_timer timeouts.
         '''
+        self.check_waiting()
         if not self.pt or self.pt.serialno == 0:
             return
         LOGGER.debug("checking records in use")
@@ -3661,6 +3697,50 @@ class OpenmolarGui(QtWidgets.QMainWindow, Advisor):
                                    localsettings.formatDate(dl.chosen_date)),
                         1)
 
+    def check_previous_surname(self):
+        if self.pt.sname != self.pt.dbstate.sname:
+            dl = AdvancedNamesDialog(self)
+            dl.set_patient(self.pt)
+            dl.check_save_previous_surname(self.pt.dbstate.sname)
+
+    def prompt_clear_location(self):
+        if (self.surgery_mode and self.pt and
+                self.pt.serialno in locations.all_snos()):
+            self.set_patient_location()
+
+    def set_patient_location(self):
+        self.patient_location(self.pt.serialno)
+
+    def patient_location(self, sno):
+        dl = PatientLocationDialog(sno, self)
+        if dl.exec_():
+            self.advise(dl.message)
+            self.diary_widget.layout_diary()
+            self.check_waiting()
+
+    def check_waiting(self):
+        serialnos = locations.no_of_patients_waiting()
+        n = len(serialnos)
+        if n == 0:
+            message =_("No patients are waiting")
+        elif n == 1:
+            message = _("1 PATIENT IS WAITING")
+        else:
+            message = "%d %s" % (n, _("PATIENTS ARE WAITING"))
+        if self.pt and self.pt.serialno in serialnos:
+            self.ui.set_location_button.setText(_("WAITING"))
+            self.ui.set_location_button.setStyleSheet("background:red")
+        else:
+            self.ui.set_location_button.setText(_("Location"))
+            self.ui.set_location_button.setStyleSheet("")
+        self.ui.statusbar.showMessage(message)
+
+    def clear_locations(self):
+        dl = ClearLocationsDialog(self)
+        if dl.exec_():
+            self.advise(_("All Patient Locations have been cleared"))
+            self.diary_widget.layout_diary()
+
     def excepthook(self, exc_type, exc_val, tracebackobj):
         '''
         PyQt5 prints unhandled exceptions to stdout and carries on regardless
diff --git a/src/openmolar/qt4gui/schema_updater.py b/src/openmolar/qt4gui/schema_updater.py
index 70540a7..eee2331 100644
--- a/src/openmolar/qt4gui/schema_updater.py
+++ b/src/openmolar/qt4gui/schema_updater.py
@@ -66,6 +66,8 @@ UPGRADES_AVAILABLE = (
     ("3.3", ".schema3_2to3_3"),
     ("3.4", ".schema3_3to3_4"),
     ("3.5", ".schema3_4to3_5"),
+    ("3.6", ".schema3_5to3_6"),
+    ("3.7", ".schema3_6to3_7"),
 )
 
 MESSAGE = '''<h3>%s</h3>
diff --git a/src/openmolar/resources/demo_data.sql b/src/openmolar/resources/demo_data.sql
new file mode 100644
index 0000000..db7d100
--- /dev/null
+++ b/src/openmolar/resources/demo_data.sql
@@ -0,0 +1,145 @@
+-- MySQL dump 10.15  Distrib 10.0.28-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: localhost    Database: localhost
+-- ------------------------------------------------------
+-- Server version	10.0.28-MariaDB-2
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Dumping data for table `clinical_memos`
+--
+
+LOCK TABLES `clinical_memos` WRITE;
+/*!40000 ALTER TABLE `clinical_memos` DISABLE KEYS */;
+INSERT INTO `clinical_memos` VALUES (1,1,'REC','2014-06-10 20:28:10',0,'This patient is for demonstration purposes only. Any similarity to any person, alive or dead, is entirely unintentional.');
+/*!40000 ALTER TABLE `clinical_memos` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `feescales`
+--
+
+LOCK TABLES `feescales` WRITE;
+/*!40000 ALTER TABLE `feescales` DISABLE KEYS */;
+INSERT INTO `feescales` VALUES (1,1,0,'example feescale','<?xml version=\"1.0\" ?><feescale>\n	<version>0.1</version>\n	<tablename>test_feescale</tablename>\n	<feescale_description>Example Fee Scale</feescale_description>\n	<category>P</category>\n	<header id=\"1\">Diagnosis</header>\n	<header id=\"2\">Preventive Care</header>\n	<header id=\"3\">Periodontal Treatment</header>\n	<header id=\"4\">Conservative Treatment</header>\n	<header id=\"5\">Endodontic Treatment</header>\n	<header id= [...]
+/*!40000 ALTER TABLE `feescales` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `formatted_notes`
+--
+
+LOCK TABLES `formatted_notes` WRITE;
+/*!40000 ALTER TABLE `formatted_notes` DISABLE KEYS */;
+INSERT INTO `formatted_notes` VALUES (1,1,'2014-06-10','REC',NULL,'opened','System date - 10/06/2014 20:26:37','2014-06-10 19:26:37'),(2,1,'2014-06-10','REC',NULL,'newNOTE','This example patient was added to the demo database today.\n','2014-06-10 19:26:37'),(3,1,'2014-06-10','REC',NULL,'closed','REC 10/06/2014 20:26:37','2014-06-10 19:26:37'),(4,1,'2016-09-14','USER',NULL,'opened','System date - 14/09/2016 13:18:01','2016-09-14 12:18:01'),(5,1,'2016-09-14','USER',NULL,'newNOTE','New not [...]
+/*!40000 ALTER TABLE `formatted_notes` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `forum`
+--
+
+LOCK TABLES `forum` WRITE;
+/*!40000 ALTER TABLE `forum` DISABLE KEYS */;
+INSERT INTO `forum` VALUES (1,'USER','2016-09-14 13:20:13','An Example Message','A forum is useful for inter surgery communication etc.',1,'EVERYBOD'),(2,'USER','2016-09-14 13:20:56','re. An Example Message','thanks.',1,'EVERYBOD'),(3,'USER','2016-09-14 13:22:05','Another Example message','This message has been marked as important by forum user \"USER\"',1,'USER');
+/*!40000 ALTER TABLE `forum` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `forum_important`
+--
+
+LOCK TABLES `forum_important` WRITE;
+/*!40000 ALTER TABLE `forum_important` DISABLE KEYS */;
+INSERT INTO `forum_important` VALUES (3,'USER');
+/*!40000 ALTER TABLE `forum_important` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `forum_parents`
+--
+
+LOCK TABLES `forum_parents` WRITE;
+/*!40000 ALTER TABLE `forum_parents` DISABLE KEYS */;
+INSERT INTO `forum_parents` VALUES (1,2);
+/*!40000 ALTER TABLE `forum_parents` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `forumread`
+--
+
+LOCK TABLES `forumread` WRITE;
+/*!40000 ALTER TABLE `forumread` DISABLE KEYS */;
+INSERT INTO `forumread` VALUES (1,1,'USER','2016-09-14 13:20:13'),(2,1,'USER','2016-09-14 13:20:44'),(3,2,'USER','2016-09-14 13:20:56'),(4,3,'USER','2016-09-14 13:22:05'),(5,3,'USER','2016-09-14 13:22:24');
+/*!40000 ALTER TABLE `forumread` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `new_patients`
+--
+
+LOCK TABLES `new_patients` WRITE;
+/*!40000 ALTER TABLE `new_patients` DISABLE KEYS */;
+INSERT INTO `new_patients` VALUES (1,'PATIENT','EXAMPLE','MR','M','1969-12-09','19 UNION STREET','','','INVERNESS','SCOTLAND, UK','IV1 1PP','','','','','','','','',NULL,'P',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'','');
+/*!40000 ALTER TABLE `new_patients` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `patient_dates`
+--
+
+LOCK TABLES `patient_dates` WRITE;
+/*!40000 ALTER TABLE `patient_dates` DISABLE KEYS */;
+INSERT INTO `patient_dates` VALUES (1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+/*!40000 ALTER TABLE `patient_dates` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `patient_money`
+--
+
+LOCK TABLES `patient_money` WRITE;
+/*!40000 ALTER TABLE `patient_money` DISABLE KEYS */;
+INSERT INTO `patient_money` VALUES (1,0,0,0,0,0,0,0,0,0,0,0,0);
+/*!40000 ALTER TABLE `patient_money` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `standard_letters`
+--
+
+LOCK TABLES `standard_letters` WRITE;
+/*!40000 ALTER TABLE `standard_letters` DISABLE KEYS */;
+INSERT INTO `standard_letters` VALUES (1,'XRay Request Letter','<br />\n<div align=\"center\"><b>XRAY REQUEST</b></div>\n<br />\n<p>You have requested copies of your xrays to take with you to another practice.<br />\nPlease be advise that we are happy to do this, and provide these as Jpeg files on CD-rom.\n</p>\n<p>\nThere is, however, a nominal charge of £15.00 for this service, which is in line with British Dental Association recommendations.\n</p>\n<p>\nShould you wish to procee [...]
+/*!40000 ALTER TABLE `standard_letters` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `static_chart`
+--
+
+LOCK TABLES `static_chart` WRITE;
+/*!40000 ALTER TABLE `static_chart` DISABLE KEYS */;
+INSERT INTO `static_chart` VALUES (1,NULL,16,NULL,NULL,'PV ','CR,LAVA ','MI ','B,GL ','MOD ','MO,CO ','','UE ','IM/TIT IM/ABUT  CR,V1 ','','','GI/MOD RT ','','','','UE ','','','','','OL,CO ','B ','FS ','UE ','','','','','','MOL,CO ','','UE ');
+/*!40000 ALTER TABLE `static_chart` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2016-12-13 13:51:43
diff --git a/src/openmolar/resources/hdp.png b/src/openmolar/resources/hdp.png
deleted file mode 100644
index a04239d..0000000
Binary files a/src/openmolar/resources/hdp.png and /dev/null differ
diff --git a/src/openmolar/resources/hdp_maintenance.png b/src/openmolar/resources/hdp_maintenance.png
new file mode 100644
index 0000000..7176c58
Binary files /dev/null and b/src/openmolar/resources/hdp_maintenance.png differ
diff --git a/src/openmolar/resources/schema.sql b/src/openmolar/resources/minimal_data.sql
similarity index 51%
copy from src/openmolar/resources/schema.sql
copy to src/openmolar/resources/minimal_data.sql
index 657cade..470627f 100644
--- a/src/openmolar/resources/schema.sql
+++ b/src/openmolar/resources/minimal_data.sql
@@ -1,8 +1,8 @@
--- MySQL dump 10.15  Distrib 10.0.26-MariaDB, for debian-linux-gnu (x86_64)
+-- MySQL dump 10.15  Distrib 10.0.28-MariaDB, for debian-linux-gnu (x86_64)
 --
--- Host: localhost    Database: openmolar_demo
+-- Host: localhost    Database: localhost
 -- ------------------------------------------------------
--- Server version	10.0.26-MariaDB-3
+-- Server version	10.0.28-MariaDB-2
 
 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
 /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
@@ -10,328 +10,21 @@
 /*!40101 SET NAMES utf8mb4 */;
 /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
 /*!40103 SET TIME_ZONE='+00:00' */;
-/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
 /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
 /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
 /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
 
 --
--- Table structure for table `aday`
---
-
-DROP TABLE IF EXISTS `aday`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `aday` (
-  `adate` date NOT NULL DEFAULT '0000-00-00',
-  `apptix` smallint(6) NOT NULL DEFAULT '0',
-  `start` smallint(6) DEFAULT NULL,
-  `end` smallint(6) DEFAULT NULL,
-  `flag` tinyint(4) DEFAULT NULL,
-  `memo` char(30) DEFAULT NULL,
-  PRIMARY KEY (`adate`,`apptix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `aday`
---
-
-LOCK TABLES `aday` WRITE;
-/*!40000 ALTER TABLE `aday` DISABLE KEYS */;
-/*!40000 ALTER TABLE `aday` ENABLE KEYS */;
-UNLOCK TABLES;
-/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
-/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
-/*!50003 SET @saved_col_connection = @@collation_connection */ ;
-/*!50003 SET character_set_client  = utf8 */ ;
-/*!50003 SET character_set_results = utf8 */ ;
-/*!50003 SET collation_connection  = utf8_general_ci */ ;
-/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
-/*!50003 SET sql_mode              = '' */ ;
-DELIMITER ;;
-/*!50003 CREATE*/ /*!50017 DEFINER=`openmolar`@`localhost`*/ /*!50003 TRIGGER aday_update_trigger 
-    BEFORE UPDATE ON aday 
-    FOR EACH ROW 
-        BEGIN 
-            DECLARE clash_count INT; 
-            IF NEW.flag = 0 THEN
-                SET clash_count=(SELECT count(*) FROM aslot WHERE apptix=NEW.apptix AND adate=NEW.adate AND serialno!=0); 
-                IF clash_count>0 THEN 
-                    SIGNAL SQLSTATE '45000' 
-                    SET message_text="existing appointments prevent you blocking this day"; 
-                END IF;
-            ELSE
-                SET clash_count=(SELECT count(*) FROM aslot 
-                WHERE apptix=NEW.apptix AND adate=NEW.adate AND (start<NEW.start OR end>NEW.end)); 
-            
-                IF clash_count>0 THEN 
-                    SIGNAL SQLSTATE '45000' 
-                    SET message_text="existing appointments prevent you changing this day"; 
-                END IF;
-            END IF;
-        END */;;
-DELIMITER ;
-/*!50003 SET sql_mode              = @saved_sql_mode */ ;
-/*!50003 SET character_set_client  = @saved_cs_client */ ;
-/*!50003 SET character_set_results = @saved_cs_results */ ;
-/*!50003 SET collation_connection  = @saved_col_connection */ ;
-
---
--- Table structure for table `appt_prefs`
---
-
-DROP TABLE IF EXISTS `appt_prefs`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `appt_prefs` (
-  `serialno` int(11) NOT NULL DEFAULT '0',
-  `recall_active` tinyint(1) NOT NULL DEFAULT '1',
-  `recdent_period` int(11) DEFAULT NULL,
-  `recdent` date DEFAULT NULL,
-  `rechyg_period` int(11) DEFAULT NULL,
-  `rechyg` date DEFAULT NULL,
-  `recall_method` enum('post','sms','email','tel') DEFAULT NULL,
-  `sms_reminders` tinyint(1) NOT NULL DEFAULT '0',
-  `no_combined_appts` tinyint(1) NOT NULL DEFAULT '0',
-  `note` varchar(120) DEFAULT NULL,
-  PRIMARY KEY (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `appt_prefs`
---
-
-LOCK TABLES `appt_prefs` WRITE;
-/*!40000 ALTER TABLE `appt_prefs` DISABLE KEYS */;
-/*!40000 ALTER TABLE `appt_prefs` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `apr`
---
-
-DROP TABLE IF EXISTS `apr`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `apr` (
-  `serialno` int(11) NOT NULL DEFAULT '0',
-  `aprix` tinyint(4) NOT NULL DEFAULT '0',
-  `practix` smallint(6) DEFAULT NULL,
-  `code0` char(8) DEFAULT NULL,
-  `code1` char(8) DEFAULT NULL,
-  `code2` char(8) DEFAULT NULL,
-  `note` char(20) DEFAULT NULL,
-  `adate` date DEFAULT NULL,
-  `atime` smallint(6) DEFAULT NULL,
-  `length` smallint(6) DEFAULT NULL,
-  `flag0` tinyint(4) DEFAULT NULL,
-  `flag1` tinyint(4) DEFAULT NULL,
-  `flag2` tinyint(4) DEFAULT NULL,
-  `flag3` tinyint(4) DEFAULT NULL,
-  `flag4` tinyint(4) DEFAULT NULL,
-  `datespec` char(10) DEFAULT NULL,
-  PRIMARY KEY (`serialno`,`aprix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `apr`
---
-
-LOCK TABLES `apr` WRITE;
-/*!40000 ALTER TABLE `apr` DISABLE KEYS */;
-/*!40000 ALTER TABLE `apr` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `aslot`
---
-
-DROP TABLE IF EXISTS `aslot`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `aslot` (
-  `adate` date DEFAULT NULL,
-  `apptix` smallint(6) DEFAULT NULL,
-  `start` smallint(6) DEFAULT NULL,
-  `end` smallint(6) DEFAULT NULL,
-  `name` char(30) DEFAULT NULL,
-  `serialno` int(11) DEFAULT NULL,
-  `code0` char(8) DEFAULT NULL,
-  `code1` char(8) DEFAULT NULL,
-  `code2` char(8) DEFAULT NULL,
-  `note` char(20) DEFAULT NULL,
-  `flag0` tinyint(4) DEFAULT NULL,
-  `flag1` tinyint(4) DEFAULT NULL,
-  `flag2` tinyint(4) DEFAULT NULL,
-  `flag3` tinyint(4) DEFAULT NULL,
-  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-  KEY `adate` (`adate`,`apptix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `aslot`
---
-
-LOCK TABLES `aslot` WRITE;
-/*!40000 ALTER TABLE `aslot` DISABLE KEYS */;
-/*!40000 ALTER TABLE `aslot` ENABLE KEYS */;
-UNLOCK TABLES;
-/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
-/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
-/*!50003 SET @saved_col_connection = @@collation_connection */ ;
-/*!50003 SET character_set_client  = utf8 */ ;
-/*!50003 SET character_set_results = utf8 */ ;
-/*!50003 SET collation_connection  = utf8_general_ci */ ;
-/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
-/*!50003 SET sql_mode              = '' */ ;
-DELIMITER ;;
-/*!50003 CREATE*/ /*!50017 DEFINER=`openmolar`@`localhost`*/ /*!50003 TRIGGER aslot_trigger 
-    BEFORE INSERT ON aslot
-    FOR EACH ROW
-    BEGIN 
-        DECLARE appt_count INT;
-        if NEW.start = NEW.end then
-            SET appt_count = 0;
-        else
-            SET appt_count = (
-                SELECT count(*) from aslot 
-                where adate=NEW.adate and start>=NEW.start and start<NEW.end and apptix=NEW.apptix
-                );
-        end if;
-        
-        if appt_count>0 then
-            signal sqlstate '45000' 
-            set message_text = "this appointment clashes with one (or more) already in the database";
-        end if; 
-            
-    END */;;
-DELIMITER ;
-/*!50003 SET sql_mode              = @saved_sql_mode */ ;
-/*!50003 SET character_set_client  = @saved_cs_client */ ;
-/*!50003 SET character_set_results = @saved_cs_results */ ;
-/*!50003 SET collation_connection  = @saved_col_connection */ ;
-
---
--- Table structure for table `bpe`
---
-
-DROP TABLE IF EXISTS `bpe`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `bpe` (
-  `serialno` int(11) NOT NULL DEFAULT '0',
-  `bpedate` date NOT NULL DEFAULT '0000-00-00',
-  `bpe` char(6) DEFAULT NULL,
-  PRIMARY KEY (`serialno`,`bpedate`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `bpe`
---
-
-LOCK TABLES `bpe` WRITE;
-/*!40000 ALTER TABLE `bpe` DISABLE KEYS */;
-/*!40000 ALTER TABLE `bpe` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `calendar`
---
-
-DROP TABLE IF EXISTS `calendar`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `calendar` (
-  `adate` date NOT NULL,
-  `memo` char(30) DEFAULT NULL,
-  PRIMARY KEY (`adate`),
-  KEY `adate` (`adate`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `calendar`
---
-
-LOCK TABLES `calendar` WRITE;
-/*!40000 ALTER TABLE `calendar` DISABLE KEYS */;
-/*!40000 ALTER TABLE `calendar` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `calldurr`
---
-
-DROP TABLE IF EXISTS `calldurr`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `calldurr` (
-  `stn` tinyint(4) NOT NULL DEFAULT '0',
-  `serialno` int(11) DEFAULT NULL,
-  PRIMARY KEY (`stn`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `calldurr`
---
-
-LOCK TABLES `calldurr` WRITE;
-/*!40000 ALTER TABLE `calldurr` DISABLE KEYS */;
-/*!40000 ALTER TABLE `calldurr` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `cashbook`
---
-
-DROP TABLE IF EXISTS `cashbook`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `cashbook` (
-  `id` int(11) NOT NULL AUTO_INCREMENT,
-  `cbdate` date DEFAULT NULL,
-  `ref` char(10) DEFAULT NULL,
-  `linkid` int(11) DEFAULT NULL,
-  `descr` varchar(32) DEFAULT NULL,
-  `code` tinyint(3) unsigned DEFAULT NULL,
-  `dntid` smallint(6) DEFAULT NULL,
-  `amt` int(11) DEFAULT NULL,
-  PRIMARY KEY (`id`),
-  KEY `date` (`cbdate`),
-  KEY `ref` (`ref`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `cashbook`
+-- Dumping data for table `opid`
 --
 
-LOCK TABLES `cashbook` WRITE;
-/*!40000 ALTER TABLE `cashbook` DISABLE KEYS */;
-/*!40000 ALTER TABLE `cashbook` ENABLE KEYS */;
+LOCK TABLES `opid` WRITE;
+/*!40000 ALTER TABLE `opid` DISABLE KEYS */;
+INSERT INTO `opid` VALUES ('USER',NULL,1);
+/*!40000 ALTER TABLE `opid` ENABLE KEYS */;
 UNLOCK TABLES;
 
 --
--- Table structure for table `cbcodes`
---
-
-DROP TABLE IF EXISTS `cbcodes`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `cbcodes` (
-  `code` tinyint(3) unsigned DEFAULT NULL,
-  `flag` tinyint(4) DEFAULT NULL,
-  `descr` char(20) DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
 -- Dumping data for table `cbcodes`
 --
 
@@ -342,824 +35,16 @@ INSERT INTO `cbcodes` VALUES (1,2,'NHS CASH'),(2,2,'PRIVATE CASH'),(3,2,'NHS CHE
 UNLOCK TABLES;
 
 --
--- Table structure for table `claims`
---
-
-DROP TABLE IF EXISTS `claims`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `claims` (
-  `courseno` int(11) NOT NULL DEFAULT '0',
-  `serialno` int(11) NOT NULL DEFAULT '0',
-  `dntix` smallint(6) DEFAULT '0',
-  `proddate` date DEFAULT NULL,
-  `startdate` date DEFAULT NULL,
-  `cmpldate` date DEFAULT NULL,
-  `regdate` date DEFAULT NULL,
-  `authdate` date DEFAULT NULL,
-  `dob` date DEFAULT NULL,
-  `sname` varchar(30) DEFAULT NULL,
-  `fname` varchar(30) DEFAULT NULL,
-  `addr1` varchar(30) DEFAULT NULL,
-  `addr2` varchar(30) DEFAULT NULL,
-  `addr3` varchar(30) DEFAULT NULL,
-  `pcde` varchar(30) DEFAULT NULL,
-  `nhsno` varchar(30) DEFAULT NULL,
-  `prevsname` varchar(30) DEFAULT NULL,
-  `exempttext` varchar(50) DEFAULT NULL,
-  `i0` int(11) DEFAULT '0',
-  `i1` int(11) DEFAULT '0',
-  `i2` int(11) DEFAULT '0',
-  `i3` int(11) DEFAULT '0',
-  `i4` int(11) DEFAULT '0',
-  `f0` tinyint(3) unsigned DEFAULT '0',
-  `f1` tinyint(3) unsigned DEFAULT '0',
-  `f2` tinyint(3) unsigned DEFAULT '0',
-  `f3` tinyint(3) unsigned DEFAULT '0',
-  `f4` tinyint(3) unsigned DEFAULT '0',
-  `f5` tinyint(3) unsigned DEFAULT '0',
-  `f6` tinyint(3) unsigned DEFAULT '0',
-  `f7` tinyint(3) unsigned DEFAULT '0',
-  `f8` tinyint(3) unsigned DEFAULT '0',
-  `f9` tinyint(3) unsigned DEFAULT '0',
-  `submstatus` tinyint(4) DEFAULT '0',
-  `submcount` tinyint(4) DEFAULT '0',
-  `submno` int(11) DEFAULT '0',
-  `claimdata` blob,
-  `trtdata` blob,
-  `archdate` date DEFAULT NULL,
-  `town` varchar(30) DEFAULT NULL,
-  `county` varchar(30) DEFAULT NULL,
-  `regtype` tinyint(3) unsigned DEFAULT '0',
-  PRIMARY KEY (`serialno`,`courseno`),
-  KEY `dentist` (`dntix`),
-  KEY `patient` (`sname`,`fname`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `claims`
---
-
-LOCK TABLES `claims` WRITE;
-/*!40000 ALTER TABLE `claims` DISABLE KEYS */;
-/*!40000 ALTER TABLE `claims` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `clinical_memos`
---
-
-DROP TABLE IF EXISTS `clinical_memos`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `clinical_memos` (
-  `ix` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `serialno` int(11) unsigned NOT NULL,
-  `author` char(8) DEFAULT NULL,
-  `datestamp` datetime NOT NULL,
-  `hidden` tinyint(1) NOT NULL DEFAULT '0',
-  `synopsis` text,
-  PRIMARY KEY (`ix`),
-  KEY `serialno` (`serialno`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `clinical_memos`
---
-
-LOCK TABLES `clinical_memos` WRITE;
-/*!40000 ALTER TABLE `clinical_memos` DISABLE KEYS */;
-INSERT INTO `clinical_memos` VALUES (1,1,'REC','2014-06-10 20:28:10',0,'This patient is for demonstration purposes only. Any similarity to any person, alive or dead, is entirely unintentional.');
-/*!40000 ALTER TABLE `clinical_memos` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `clinician_dates`
---
-
-DROP TABLE IF EXISTS `clinician_dates`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `clinician_dates` (
-  `clinician_ix` smallint(5) unsigned NOT NULL,
-  `start_date` date NOT NULL,
-  `end_date` date DEFAULT NULL,
-  `date_comments` varchar(255) DEFAULT NULL,
-  KEY `clinician_ix` (`clinician_ix`),
-  CONSTRAINT `clinician_dates_ibfk_1` FOREIGN KEY (`clinician_ix`) REFERENCES `clinicians` (`ix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `clinician_dates`
---
-
-LOCK TABLES `clinician_dates` WRITE;
-/*!40000 ALTER TABLE `clinician_dates` DISABLE KEYS */;
-/*!40000 ALTER TABLE `clinician_dates` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `clinicians`
---
-
-DROP TABLE IF EXISTS `clinicians`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `clinicians` (
-  `ix` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
-  `initials` char(5) NOT NULL,
-  `name` varchar(64) NOT NULL,
-  `formal_name` varchar(128) DEFAULT NULL,
-  `qualifications` varchar(64) DEFAULT NULL,
-  `type` smallint(5) NOT NULL DEFAULT '1',
-  `speciality` varchar(64) DEFAULT NULL,
-  `data` varchar(255) DEFAULT NULL,
-  `comments` varchar(255) DEFAULT NULL,
-  PRIMARY KEY (`ix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `clinicians`
---
-
-LOCK TABLES `clinicians` WRITE;
-/*!40000 ALTER TABLE `clinicians` DISABLE KEYS */;
-/*!40000 ALTER TABLE `clinicians` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `currtrtmt2`
---
-
-DROP TABLE IF EXISTS `currtrtmt2`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `currtrtmt2` (
-  `courseno` int(11) unsigned NOT NULL AUTO_INCREMENT,
-  `serialno` int(11) DEFAULT NULL,
-  `examt` varchar(10) NOT NULL DEFAULT '',
-  `examd` date DEFAULT NULL,
-  `accd` date DEFAULT NULL,
-  `cmpd` date DEFAULT NULL,
-  `xraypl` varchar(56) NOT NULL DEFAULT '',
-  `periopl` varchar(56) NOT NULL DEFAULT '',
-  `anaespl` varchar(56) NOT NULL DEFAULT '',
-  `otherpl` varchar(56) NOT NULL DEFAULT '',
-  `ndupl` varchar(56) NOT NULL DEFAULT '',
-  `ndlpl` varchar(56) NOT NULL DEFAULT '',
-  `odupl` varchar(56) NOT NULL DEFAULT '',
-  `odlpl` varchar(56) NOT NULL DEFAULT '',
-  `custompl` varchar(56) NOT NULL DEFAULT '',
-  `ur8pl` varchar(34) NOT NULL DEFAULT '',
-  `ur7pl` varchar(34) NOT NULL DEFAULT '',
-  `ur6pl` varchar(34) NOT NULL DEFAULT '',
-  `ur5pl` varchar(34) NOT NULL DEFAULT '',
-  `ur4pl` varchar(34) NOT NULL DEFAULT '',
-  `ur3pl` varchar(34) NOT NULL DEFAULT '',
-  `ur2pl` varchar(34) NOT NULL DEFAULT '',
-  `ur1pl` varchar(34) NOT NULL DEFAULT '',
-  `ul1pl` varchar(34) NOT NULL DEFAULT '',
-  `ul2pl` varchar(34) NOT NULL DEFAULT '',
-  `ul3pl` varchar(34) NOT NULL DEFAULT '',
-  `ul4pl` varchar(34) NOT NULL DEFAULT '',
-  `ul5pl` varchar(34) NOT NULL DEFAULT '',
-  `ul6pl` varchar(34) NOT NULL DEFAULT '',
-  `ul7pl` varchar(34) NOT NULL DEFAULT '',
-  `ul8pl` varchar(34) NOT NULL DEFAULT '',
-  `ll8pl` varchar(34) NOT NULL DEFAULT '',
-  `ll7pl` varchar(34) NOT NULL DEFAULT '',
-  `ll6pl` varchar(34) NOT NULL DEFAULT '',
-  `ll5pl` varchar(34) NOT NULL DEFAULT '',
-  `ll4pl` varchar(34) NOT NULL DEFAULT '',
-  `ll3pl` varchar(34) NOT NULL DEFAULT '',
-  `ll2pl` varchar(34) NOT NULL DEFAULT '',
-  `ll1pl` varchar(34) NOT NULL DEFAULT '',
-  `lr1pl` varchar(34) NOT NULL DEFAULT '',
-  `lr2pl` varchar(34) NOT NULL DEFAULT '',
-  `lr3pl` varchar(34) NOT NULL DEFAULT '',
-  `lr4pl` varchar(34) NOT NULL DEFAULT '',
-  `lr5pl` varchar(34) NOT NULL DEFAULT '',
-  `lr6pl` varchar(34) NOT NULL DEFAULT '',
-  `lr7pl` varchar(34) NOT NULL DEFAULT '',
-  `lr8pl` varchar(34) NOT NULL DEFAULT '',
-  `ur8cmp` varchar(34) NOT NULL DEFAULT '',
-  `ur7cmp` varchar(34) NOT NULL DEFAULT '',
-  `ur6cmp` varchar(34) NOT NULL DEFAULT '',
-  `ur5cmp` varchar(34) NOT NULL DEFAULT '',
-  `ur4cmp` varchar(34) NOT NULL DEFAULT '',
-  `ur3cmp` varchar(34) NOT NULL DEFAULT '',
-  `ur2cmp` varchar(34) NOT NULL DEFAULT '',
-  `ur1cmp` varchar(34) NOT NULL DEFAULT '',
-  `ul1cmp` varchar(34) NOT NULL DEFAULT '',
-  `ul2cmp` varchar(34) NOT NULL DEFAULT '',
-  `ul3cmp` varchar(34) NOT NULL DEFAULT '',
-  `ul4cmp` varchar(34) NOT NULL DEFAULT '',
-  `ul5cmp` varchar(34) NOT NULL DEFAULT '',
-  `ul6cmp` varchar(34) NOT NULL DEFAULT '',
-  `ul7cmp` varchar(34) NOT NULL DEFAULT '',
-  `ul8cmp` varchar(34) NOT NULL DEFAULT '',
-  `ll8cmp` varchar(34) NOT NULL DEFAULT '',
-  `ll7cmp` varchar(34) NOT NULL DEFAULT '',
-  `ll6cmp` varchar(34) NOT NULL DEFAULT '',
-  `ll5cmp` varchar(34) NOT NULL DEFAULT '',
-  `ll4cmp` varchar(34) NOT NULL DEFAULT '',
-  `ll3cmp` varchar(34) NOT NULL DEFAULT '',
-  `ll2cmp` varchar(34) NOT NULL DEFAULT '',
-  `ll1cmp` varchar(34) NOT NULL DEFAULT '',
-  `lr1cmp` varchar(34) NOT NULL DEFAULT '',
-  `lr2cmp` varchar(34) NOT NULL DEFAULT '',
-  `lr3cmp` varchar(34) NOT NULL DEFAULT '',
-  `lr4cmp` varchar(34) NOT NULL DEFAULT '',
-  `lr5cmp` varchar(34) NOT NULL DEFAULT '',
-  `lr6cmp` varchar(34) NOT NULL DEFAULT '',
-  `lr7cmp` varchar(34) NOT NULL DEFAULT '',
-  `lr8cmp` varchar(34) NOT NULL DEFAULT '',
-  `xraycmp` varchar(56) NOT NULL DEFAULT '',
-  `periocmp` varchar(56) NOT NULL DEFAULT '',
-  `anaescmp` varchar(56) NOT NULL DEFAULT '',
-  `othercmp` varchar(56) NOT NULL DEFAULT '',
-  `nducmp` varchar(56) NOT NULL DEFAULT '',
-  `ndlcmp` varchar(56) NOT NULL DEFAULT '',
-  `oducmp` varchar(56) NOT NULL DEFAULT '',
-  `odlcmp` varchar(56) NOT NULL DEFAULT '',
-  `customcmp` varchar(56) NOT NULL DEFAULT '',
-  `ftr` tinyint(1) DEFAULT '0',
-  PRIMARY KEY (`courseno`),
-  KEY `serialno` (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `currtrtmt2`
---
-
-LOCK TABLES `currtrtmt2` WRITE;
-/*!40000 ALTER TABLE `currtrtmt2` DISABLE KEYS */;
-/*!40000 ALTER TABLE `currtrtmt2` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `daybook`
---
-
-DROP TABLE IF EXISTS `daybook`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `daybook` (
-  `date` date DEFAULT NULL,
-  `serialno` int(11) DEFAULT NULL,
-  `coursetype` char(1) DEFAULT NULL,
-  `dntid` smallint(6) DEFAULT NULL,
-  `trtid` smallint(6) DEFAULT NULL,
-  `diagn` varchar(56) DEFAULT NULL,
-  `perio` varchar(56) DEFAULT NULL,
-  `anaes` varchar(56) DEFAULT NULL,
-  `misc` varchar(56) DEFAULT NULL,
-  `ndu` varchar(56) DEFAULT NULL,
-  `ndl` varchar(56) DEFAULT NULL,
-  `odu` varchar(56) DEFAULT NULL,
-  `odl` varchar(56) DEFAULT NULL,
-  `other` varchar(56) DEFAULT NULL,
-  `chart` blob,
-  `feesa` int(11) DEFAULT NULL,
-  `feesb` int(11) DEFAULT NULL,
-  `feesc` int(11) DEFAULT NULL,
-  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  PRIMARY KEY (`id`),
-  KEY `date` (`date`),
-  KEY `serialno` (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `daybook`
---
-
-LOCK TABLES `daybook` WRITE;
-/*!40000 ALTER TABLE `daybook` DISABLE KEYS */;
-/*!40000 ALTER TABLE `daybook` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `daybook_link`
---
-
-DROP TABLE IF EXISTS `daybook_link`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `daybook_link` (
-  `ix` int(11) unsigned NOT NULL AUTO_INCREMENT,
-  `daybook_id` int(11) DEFAULT NULL,
-  `tx_hash` char(40) NOT NULL,
-  PRIMARY KEY (`ix`),
-  KEY `daybook_id` (`daybook_id`),
-  KEY `daybook_id_index` (`tx_hash`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `daybook_link`
---
-
-LOCK TABLES `daybook_link` WRITE;
-/*!40000 ALTER TABLE `daybook_link` DISABLE KEYS */;
-/*!40000 ALTER TABLE `daybook_link` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `diary_link`
---
-
-DROP TABLE IF EXISTS `diary_link`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `diary_link` (
-  `clinician_ix` smallint(5) unsigned NOT NULL,
-  `apptix` smallint(5) unsigned NOT NULL,
-  KEY `clinician_ix` (`clinician_ix`),
-  CONSTRAINT `diary_link_ibfk_1` FOREIGN KEY (`clinician_ix`) REFERENCES `clinicians` (`ix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `diary_link`
---
-
-LOCK TABLES `diary_link` WRITE;
-/*!40000 ALTER TABLE `diary_link` DISABLE KEYS */;
-/*!40000 ALTER TABLE `diary_link` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `docsimported`
---
-
-DROP TABLE IF EXISTS `docsimported`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `docsimported` (
-  `ix` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
-  `serialno` int(11) unsigned NOT NULL DEFAULT '0',
-  `datatype` varchar(60) NOT NULL DEFAULT 'application/octet-stream',
-  `name` varchar(120) NOT NULL DEFAULT '',
-  `size` bigint(20) unsigned NOT NULL DEFAULT '1024',
-  `filedate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
-  `importime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-  PRIMARY KEY (`ix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `docsimported`
---
-
-LOCK TABLES `docsimported` WRITE;
-/*!40000 ALTER TABLE `docsimported` DISABLE KEYS */;
-/*!40000 ALTER TABLE `docsimported` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `docsimporteddata`
---
-
-DROP TABLE IF EXISTS `docsimporteddata`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `docsimporteddata` (
-  `ix` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
-  `masterid` mediumint(8) unsigned NOT NULL DEFAULT '0',
-  `filedata` blob NOT NULL,
-  PRIMARY KEY (`ix`),
-  KEY `master_idx` (`masterid`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `docsimporteddata`
---
-
-LOCK TABLES `docsimporteddata` WRITE;
-/*!40000 ALTER TABLE `docsimporteddata` DISABLE KEYS */;
-/*!40000 ALTER TABLE `docsimporteddata` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `est_link2`
---
-
-DROP TABLE IF EXISTS `est_link2`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `est_link2` (
-  `ix` int(11) unsigned NOT NULL AUTO_INCREMENT,
-  `est_id` int(11) DEFAULT NULL,
-  `tx_hash` char(40) NOT NULL,
-  `completed` tinyint(1) NOT NULL DEFAULT '0',
-  PRIMARY KEY (`ix`),
-  KEY `est_id` (`est_id`),
-  KEY `est_link2_hash_index` (`tx_hash`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `est_link2`
---
-
-LOCK TABLES `est_link2` WRITE;
-/*!40000 ALTER TABLE `est_link2` DISABLE KEYS */;
-/*!40000 ALTER TABLE `est_link2` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `est_logger`
---
-
-DROP TABLE IF EXISTS `est_logger`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `est_logger` (
-  `ix` int(11) unsigned NOT NULL AUTO_INCREMENT,
-  `courseno` int(11) unsigned NOT NULL,
-  `est_data` mediumtext NOT NULL,
-  `operator` varchar(16) NOT NULL,
-  `time_stamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-  PRIMARY KEY (`ix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `est_logger`
---
-
-LOCK TABLES `est_logger` WRITE;
-/*!40000 ALTER TABLE `est_logger` DISABLE KEYS */;
-/*!40000 ALTER TABLE `est_logger` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `exemptions`
---
-
-DROP TABLE IF EXISTS `exemptions`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `exemptions` (
-  `ix` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `serialno` int(11) unsigned NOT NULL,
-  `exemption` varchar(10) DEFAULT NULL,
-  `exempttext` varchar(50) DEFAULT NULL,
-  `datestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
-  PRIMARY KEY (`ix`),
-  KEY `serialno` (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `exemptions`
---
-
-LOCK TABLES `exemptions` WRITE;
-/*!40000 ALTER TABLE `exemptions` DISABLE KEYS */;
-/*!40000 ALTER TABLE `exemptions` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `families`
---
-
-DROP TABLE IF EXISTS `families`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `families` (
-  `familyno` int(11) NOT NULL,
-  `head` int(11) DEFAULT NULL,
-  PRIMARY KEY (`familyno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `families`
---
-
-LOCK TABLES `families` WRITE;
-/*!40000 ALTER TABLE `families` DISABLE KEYS */;
-/*!40000 ALTER TABLE `families` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `feescales`
---
-
-DROP TABLE IF EXISTS `feescales`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `feescales` (
-  `ix` int(11) unsigned NOT NULL AUTO_INCREMENT,
-  `in_use` tinyint(1) NOT NULL DEFAULT '0',
-  `priority` int(8) DEFAULT NULL,
-  `comment` varchar(255) NOT NULL DEFAULT 'unnamed feescale',
-  `xml_data` mediumtext NOT NULL,
-  PRIMARY KEY (`ix`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `feescales`
---
-
-LOCK TABLES `feescales` WRITE;
-/*!40000 ALTER TABLE `feescales` DISABLE KEYS */;
-INSERT INTO `feescales` VALUES (1,1,0,'example feescale','<?xml version=\"1.0\" ?><feescale>\n	<version>0.1</version>\n	<tablename>test_feescale</tablename>\n	<feescale_description>Example Fee Scale</feescale_description>\n	<category>P</category>\n	<header id=\"1\">Diagnosis</header>\n	<header id=\"2\">Preventive Care</header>\n	<header id=\"3\">Periodontal Treatment</header>\n	<header id=\"4\">Conservative Treatment</header>\n	<header id=\"5\">Endodontic Treatment</header>\n	<header id= [...]
-/*!40000 ALTER TABLE `feescales` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `feetable_key`
---
-
-DROP TABLE IF EXISTS `feetable_key`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `feetable_key` (
-  `ix` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `tablename` char(30) DEFAULT NULL,
-  `categories` char(30) DEFAULT NULL,
-  `description` char(60) DEFAULT NULL,
-  `startdate` date DEFAULT NULL,
-  `enddate` date DEFAULT NULL,
-  `feecoltypes` tinytext,
-  `in_use` tinyint(1) NOT NULL DEFAULT '1',
-  `display_order` smallint(6) DEFAULT NULL,
-  `data` mediumtext,
-  PRIMARY KEY (`ix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `feetable_key`
---
-
-LOCK TABLES `feetable_key` WRITE;
-/*!40000 ALTER TABLE `feetable_key` DISABLE KEYS */;
-/*!40000 ALTER TABLE `feetable_key` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `formatted_notes`
---
-
-DROP TABLE IF EXISTS `formatted_notes`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `formatted_notes` (
-  `ix` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
-  `serialno` int(11) DEFAULT NULL,
-  `ndate` date DEFAULT NULL,
-  `op1` varchar(8) DEFAULT NULL,
-  `op2` varchar(8) DEFAULT NULL,
-  `ntype` varchar(32) DEFAULT NULL,
-  `note` varchar(80) DEFAULT NULL,
-  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-  UNIQUE KEY `ix` (`ix`),
-  KEY `formatted_notes_serialno_index` (`serialno`)
-) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `formatted_notes`
---
-
-LOCK TABLES `formatted_notes` WRITE;
-/*!40000 ALTER TABLE `formatted_notes` DISABLE KEYS */;
-INSERT INTO `formatted_notes` VALUES (1,1,'2014-06-10','REC',NULL,'opened','System date - 10/06/2014 20:26:37','2014-06-10 19:26:37'),(2,1,'2014-06-10','REC',NULL,'newNOTE','This example patient was added to the demo database today.\n','2014-06-10 19:26:37'),(3,1,'2014-06-10','REC',NULL,'closed','REC 10/06/2014 20:26:37','2014-06-10 19:26:37'),(4,1,'2016-09-14','USER',NULL,'opened','System date - 14/09/2016 13:18:01','2016-09-14 12:18:01'),(5,1,'2016-09-14','USER',NULL,'newNOTE','New not [...]
-/*!40000 ALTER TABLE `formatted_notes` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `forum`
---
-
-DROP TABLE IF EXISTS `forum`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `forum` (
-  `ix` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `inits` char(5) DEFAULT NULL,
-  `fdate` datetime DEFAULT NULL,
-  `topic` char(30) DEFAULT NULL,
-  `comment` text NOT NULL,
-  `open` tinyint(1) NOT NULL DEFAULT '1',
-  `recipient` char(8) DEFAULT NULL,
-  PRIMARY KEY (`ix`)
-) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `forum`
---
-
-LOCK TABLES `forum` WRITE;
-/*!40000 ALTER TABLE `forum` DISABLE KEYS */;
-INSERT INTO `forum` VALUES (1,'USER','2016-09-14 13:20:13','An Example Message','A forum is useful for inter surgery communication etc.',1,'EVERYBOD'),(2,'USER','2016-09-14 13:20:56','re. An Example Message','thanks.',1,'EVERYBOD'),(3,'USER','2016-09-14 13:22:05','Another Example message','This message has been marked as important by forum user \"USER\"',1,'USER');
-/*!40000 ALTER TABLE `forum` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `forum_important`
---
-
-DROP TABLE IF EXISTS `forum_important`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `forum_important` (
-  `important_id` int(10) unsigned NOT NULL,
-  `op` char(8) DEFAULT NULL,
-  KEY `important_id` (`important_id`),
-  KEY `forum_important_index` (`op`),
-  CONSTRAINT `forum_important_ibfk_1` FOREIGN KEY (`important_id`) REFERENCES `forum` (`ix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `forum_important`
---
-
-LOCK TABLES `forum_important` WRITE;
-/*!40000 ALTER TABLE `forum_important` DISABLE KEYS */;
-INSERT INTO `forum_important` VALUES (3,'USER');
-/*!40000 ALTER TABLE `forum_important` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `forum_parents`
---
-
-DROP TABLE IF EXISTS `forum_parents`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `forum_parents` (
-  `parent_id` int(10) unsigned NOT NULL,
-  `child_id` int(10) unsigned NOT NULL,
-  UNIQUE KEY `child_id` (`child_id`,`parent_id`),
-  KEY `parent_id` (`parent_id`),
-  CONSTRAINT `forum_parents_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `forum` (`ix`),
-  CONSTRAINT `forum_parents_ibfk_2` FOREIGN KEY (`child_id`) REFERENCES `forum` (`ix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `forum_parents`
---
-
-LOCK TABLES `forum_parents` WRITE;
-/*!40000 ALTER TABLE `forum_parents` DISABLE KEYS */;
-INSERT INTO `forum_parents` VALUES (1,2);
-/*!40000 ALTER TABLE `forum_parents` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `forumread`
---
-
-DROP TABLE IF EXISTS `forumread`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `forumread` (
-  `ix` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `id` int(10) unsigned NOT NULL,
-  `op` char(8) DEFAULT NULL,
-  `readdate` datetime NOT NULL,
-  PRIMARY KEY (`ix`),
-  KEY `id` (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `forumread`
---
-
-LOCK TABLES `forumread` WRITE;
-/*!40000 ALTER TABLE `forumread` DISABLE KEYS */;
-INSERT INTO `forumread` VALUES (1,1,'USER','2016-09-14 13:20:13'),(2,1,'USER','2016-09-14 13:20:44'),(3,2,'USER','2016-09-14 13:20:56'),(4,3,'USER','2016-09-14 13:22:05'),(5,3,'USER','2016-09-14 13:22:24');
-/*!40000 ALTER TABLE `forumread` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `medforms`
---
-
-DROP TABLE IF EXISTS `medforms`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `medforms` (
-  `pt_sno` int(11) unsigned NOT NULL,
-  `chk_date` date NOT NULL,
-  PRIMARY KEY (`pt_sno`,`chk_date`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `medforms`
---
-
-LOCK TABLES `medforms` WRITE;
-/*!40000 ALTER TABLE `medforms` DISABLE KEYS */;
-/*!40000 ALTER TABLE `medforms` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `medhist`
---
-
-DROP TABLE IF EXISTS `medhist`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `medhist` (
-  `ix` int(11) unsigned NOT NULL AUTO_INCREMENT,
-  `pt_sno` int(11) NOT NULL,
-  `medication_comments` varchar(200) NOT NULL DEFAULT '',
-  `warning_card` varchar(60) NOT NULL DEFAULT '',
-  `allergies` varchar(60) NOT NULL DEFAULT '',
-  `respiratory` varchar(60) NOT NULL DEFAULT '',
-  `heart` varchar(60) NOT NULL DEFAULT '',
-  `diabetes` varchar(60) NOT NULL DEFAULT '',
-  `arthritis` varchar(60) NOT NULL DEFAULT '',
-  `bleeding` varchar(60) NOT NULL DEFAULT '',
-  `infectious_disease` varchar(60) NOT NULL DEFAULT '',
-  `endocarditis` varchar(60) NOT NULL DEFAULT '',
-  `liver` varchar(60) NOT NULL DEFAULT '',
-  `anaesthetic` varchar(60) NOT NULL DEFAULT '',
-  `joint_replacement` varchar(60) NOT NULL DEFAULT '',
-  `heart_surgery` varchar(60) NOT NULL DEFAULT '',
-  `brain_surgery` varchar(60) NOT NULL DEFAULT '',
-  `hospital` varchar(60) NOT NULL DEFAULT '',
-  `cjd` varchar(60) NOT NULL DEFAULT '',
-  `other` varchar(60) NOT NULL DEFAULT '',
-  `alert` tinyint(1) NOT NULL DEFAULT '0',
-  `chkdate` date DEFAULT NULL,
-  `modified_by` varchar(20) NOT NULL DEFAULT 'unknown',
-  `time_stamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-  PRIMARY KEY (`ix`),
-  KEY `pt_sno` (`pt_sno`),
-  CONSTRAINT `medhist_ibfk_1` FOREIGN KEY (`pt_sno`) REFERENCES `new_patients` (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `medhist`
---
-
-LOCK TABLES `medhist` WRITE;
-/*!40000 ALTER TABLE `medhist` DISABLE KEYS */;
-/*!40000 ALTER TABLE `medhist` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `medication_link`
---
-
-DROP TABLE IF EXISTS `medication_link`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `medication_link` (
-  `med_ix` int(11) unsigned NOT NULL,
-  `med` varchar(120) DEFAULT NULL,
-  `details` varchar(60) DEFAULT NULL,
-  KEY `med_ix` (`med_ix`),
-  KEY `med` (`med`),
-  CONSTRAINT `medication_link_ibfk_1` FOREIGN KEY (`med_ix`) REFERENCES `medhist` (`ix`),
-  CONSTRAINT `medication_link_ibfk_2` FOREIGN KEY (`med`) REFERENCES `medications` (`medication`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `medication_link`
+-- Dumping data for table `settings`
 --
 
-LOCK TABLES `medication_link` WRITE;
-/*!40000 ALTER TABLE `medication_link` DISABLE KEYS */;
-/*!40000 ALTER TABLE `medication_link` ENABLE KEYS */;
+LOCK TABLES `settings` WRITE;
+/*!40000 ALTER TABLE `settings` DISABLE KEYS */;
+INSERT INTO `settings` VALUES (1,'wikiurl','http://openmolar.com/wiki',NULL,NULL,NULL,'neil at openmolar.com','2014-06-10 17:52:59'),(2,'Schema_Version','2.9',NULL,NULL,NULL,'neil at openmolar.com','2014-07-01 12:51:30'),(3,'Schema_Version','3.0',NULL,NULL,NULL,'2_9 to 3_0 script','2016-09-14 12:15:42'),(5,'Schema_Version','3.1',NULL,NULL,NULL,'3_0 to 3_1 script','2016-09-14 12:15:45'),(7,'Schema_Version','3.2',NULL,NULL,NULL,'3.1 to 3.2 script','2016-09-14 12:15:48'),(9,'Schema_Version','3.3' [...]
+/*!40000 ALTER TABLE `settings` ENABLE KEYS */;
 UNLOCK TABLES;
 
 --
--- Table structure for table `medications`
---
-
-DROP TABLE IF EXISTS `medications`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `medications` (
-  `medication` varchar(120) NOT NULL,
-  `warning` tinyint(1) NOT NULL DEFAULT '0',
-  PRIMARY KEY (`medication`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
 -- Dumping data for table `medications`
 --
 
@@ -1168,633 +53,13 @@ LOCK TABLES `medications` WRITE;
 INSERT INTO `medications` VALUES ('50:50 Ointment',0),('Abacavir Sulphate',0),('Abatacept',0),('Abciximab',0),('Abelcet',0),('Abidec Multivitamin Drops',0),('Abilify',0),('Acamprosate Calcium',0),('Acarbose',0),('Accolate',0),('Accupro',0),('Accuretic',0),('Acea',0),('Acebutolol',0),('Acebutolol Hydrochloride',0),('Aceclofenac',0),('Acemetacin',0),('Acenocoumarol',0),('Acepril',0),('Acetazolamide',0),('Acetic Acid Cough Linctus',0),('Acetylcholine Chloride',0),('Acetylcysteine',0),('Acez [...]
 /*!40000 ALTER TABLE `medications` ENABLE KEYS */;
 UNLOCK TABLES;
-
---
--- Table structure for table `new_patients`
---
-
-DROP TABLE IF EXISTS `new_patients`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `new_patients` (
-  `serialno` int(11) NOT NULL,
-  `sname` varchar(30) DEFAULT NULL,
-  `fname` varchar(30) DEFAULT NULL,
-  `title` varchar(30) DEFAULT NULL,
-  `sex` char(1) DEFAULT NULL,
-  `dob` date DEFAULT NULL,
-  `addr1` varchar(30) NOT NULL DEFAULT '',
-  `addr2` varchar(30) NOT NULL DEFAULT '',
-  `addr3` varchar(30) NOT NULL DEFAULT '',
-  `town` varchar(30) NOT NULL DEFAULT '',
-  `county` varchar(30) NOT NULL DEFAULT '',
-  `pcde` varchar(30) NOT NULL DEFAULT '',
-  `tel1` varchar(30) NOT NULL DEFAULT '',
-  `tel2` varchar(30) NOT NULL DEFAULT '',
-  `mobile` varchar(30) NOT NULL DEFAULT '',
-  `fax` varchar(30) NOT NULL DEFAULT '',
-  `email1` varchar(50) NOT NULL DEFAULT '',
-  `email2` varchar(50) NOT NULL DEFAULT '',
-  `occup` varchar(30) NOT NULL DEFAULT '',
-  `nhsno` varchar(30) NOT NULL DEFAULT '',
-  `cnfd` date DEFAULT NULL,
-  `cset` varchar(10) DEFAULT NULL,
-  `dnt1` smallint(6) DEFAULT NULL,
-  `dnt2` smallint(6) DEFAULT NULL,
-  `courseno0` int(11) DEFAULT NULL,
-  `billdate` date DEFAULT NULL,
-  `billct` tinyint(3) unsigned DEFAULT NULL,
-  `billtype` char(1) DEFAULT NULL,
-  `familyno` int(11) DEFAULT NULL,
-  `memo` varchar(255) NOT NULL DEFAULT '',
-  `status` varchar(30) NOT NULL DEFAULT '',
-  PRIMARY KEY (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `new_patients`
---
-
-LOCK TABLES `new_patients` WRITE;
-/*!40000 ALTER TABLE `new_patients` DISABLE KEYS */;
-INSERT INTO `new_patients` VALUES (1,'PATIENT','EXAMPLE','MR','M','1969-12-09','19 UNION STREET','','','INVERNESS','SCOTLAND, UK','IV1 1PP','','','','','','','','',NULL,'P',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'','');
-/*!40000 ALTER TABLE `new_patients` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `newdocsprinted`
---
-
-DROP TABLE IF EXISTS `newdocsprinted`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `newdocsprinted` (
-  `ix` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `serialno` int(11) DEFAULT NULL,
-  `printdate` date DEFAULT NULL,
-  `docname` varchar(64) DEFAULT NULL,
-  `docversion` smallint(6) DEFAULT NULL,
-  `data` blob,
-  PRIMARY KEY (`ix`),
-  KEY `newdocsprinted_serialno_index` (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `newdocsprinted`
---
-
-LOCK TABLES `newdocsprinted` WRITE;
-/*!40000 ALTER TABLE `newdocsprinted` DISABLE KEYS */;
-/*!40000 ALTER TABLE `newdocsprinted` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `newestimates`
---
-
-DROP TABLE IF EXISTS `newestimates`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `newestimates` (
-  `ix` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `serialno` int(11) NOT NULL,
-  `courseno` int(10) unsigned DEFAULT NULL,
-  `category` char(12) DEFAULT NULL,
-  `type` char(20) DEFAULT NULL,
-  `number` tinyint(4) DEFAULT NULL,
-  `itemcode` char(5) DEFAULT NULL,
-  `description` char(50) DEFAULT NULL,
-  `fee` int(11) DEFAULT NULL,
-  `ptfee` int(11) DEFAULT NULL,
-  `csetype` char(5) DEFAULT NULL,
-  `feescale` char(1) DEFAULT NULL,
-  `dent` tinyint(1) DEFAULT NULL,
-  `completed` tinyint(1) DEFAULT NULL,
-  `carriedover` tinyint(1) DEFAULT NULL,
-  `linked` tinyint(1) DEFAULT NULL,
-  `modified_by` varchar(20) NOT NULL,
-  `time_stamp` datetime NOT NULL,
-  PRIMARY KEY (`ix`),
-  KEY `serialno` (`serialno`),
-  KEY `courseno` (`courseno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `newestimates`
---
-
-LOCK TABLES `newestimates` WRITE;
-/*!40000 ALTER TABLE `newestimates` DISABLE KEYS */;
-/*!40000 ALTER TABLE `newestimates` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `newfeetable`
---
-
-DROP TABLE IF EXISTS `newfeetable`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `newfeetable` (
-  `ix` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
-  `section` smallint(6) DEFAULT NULL,
-  `USERCODE` char(14) DEFAULT NULL,
-  `code` char(8) DEFAULT NULL,
-  `oldcode` char(12) DEFAULT NULL,
-  `regulation` char(50) DEFAULT NULL,
-  `max_per_course` char(25) DEFAULT NULL,
-  `description` char(60) DEFAULT NULL,
-  `description1` char(60) DEFAULT NULL,
-  `NF08` int(11) DEFAULT NULL,
-  `NF08_pt` int(11) DEFAULT NULL,
-  `PFA` int(11) DEFAULT NULL,
-  `NF09` int(11) DEFAULT NULL,
-  `NF09_pt` int(11) DEFAULT NULL,
-  PRIMARY KEY (`ix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `newfeetable`
---
-
-LOCK TABLES `newfeetable` WRITE;
-/*!40000 ALTER TABLE `newfeetable` DISABLE KEYS */;
-/*!40000 ALTER TABLE `newfeetable` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `opid`
---
-
-DROP TABLE IF EXISTS `opid`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `opid` (
-  `id` char(5) NOT NULL,
-  `serialno` int(11) DEFAULT NULL,
-  `active` tinyint(1) NOT NULL DEFAULT '1',
-  PRIMARY KEY (`id`),
-  KEY `fk_opid_serialno` (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `opid`
---
-
-LOCK TABLES `opid` WRITE;
-/*!40000 ALTER TABLE `opid` DISABLE KEYS */;
-INSERT INTO `opid` VALUES ('REC',NULL,1),('USER',NULL,1);
-/*!40000 ALTER TABLE `opid` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `patient_dates`
---
-
-DROP TABLE IF EXISTS `patient_dates`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `patient_dates` (
-  `pt_sno` int(11) NOT NULL,
-  `pd0` date DEFAULT NULL,
-  `pd1` date DEFAULT NULL,
-  `pd2` date DEFAULT NULL,
-  `pd3` date DEFAULT NULL,
-  `pd4` date DEFAULT NULL,
-  `pd5` date DEFAULT NULL,
-  `pd6` date DEFAULT NULL,
-  `pd7` date DEFAULT NULL,
-  `pd8` date DEFAULT NULL,
-  `pd9` date DEFAULT NULL,
-  `pd10` date DEFAULT NULL,
-  `pd11` date DEFAULT NULL,
-  `pd12` date DEFAULT NULL,
-  `pd13` date DEFAULT NULL,
-  `pd14` date DEFAULT NULL,
-  UNIQUE KEY `pt_sno` (`pt_sno`),
-  CONSTRAINT `patient_dates_ibfk_1` FOREIGN KEY (`pt_sno`) REFERENCES `new_patients` (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `patient_dates`
---
-
-LOCK TABLES `patient_dates` WRITE;
-/*!40000 ALTER TABLE `patient_dates` DISABLE KEYS */;
-INSERT INTO `patient_dates` VALUES (1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
-/*!40000 ALTER TABLE `patient_dates` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `patient_money`
---
-
-DROP TABLE IF EXISTS `patient_money`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `patient_money` (
-  `pt_sno` int(11) NOT NULL,
-  `money0` int(11) NOT NULL DEFAULT '0',
-  `money1` int(11) NOT NULL DEFAULT '0',
-  `money2` int(11) NOT NULL DEFAULT '0',
-  `money3` int(11) NOT NULL DEFAULT '0',
-  `money4` int(11) NOT NULL DEFAULT '0',
-  `money5` int(11) NOT NULL DEFAULT '0',
-  `money6` int(11) NOT NULL DEFAULT '0',
-  `money7` int(11) NOT NULL DEFAULT '0',
-  `money8` int(11) NOT NULL DEFAULT '0',
-  `money9` int(11) NOT NULL DEFAULT '0',
-  `money10` int(11) NOT NULL DEFAULT '0',
-  `money11` int(11) NOT NULL DEFAULT '0',
-  UNIQUE KEY `pt_sno` (`pt_sno`),
-  CONSTRAINT `patient_money_ibfk_1` FOREIGN KEY (`pt_sno`) REFERENCES `new_patients` (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `patient_money`
---
-
-LOCK TABLES `patient_money` WRITE;
-/*!40000 ALTER TABLE `patient_money` DISABLE KEYS */;
-INSERT INTO `patient_money` VALUES (1,0,0,0,0,0,0,0,0,0,0,0,0);
-/*!40000 ALTER TABLE `patient_money` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `patient_nhs`
---
-
-DROP TABLE IF EXISTS `patient_nhs`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `patient_nhs` (
-  `pt_sno` int(11) NOT NULL,
-  `initaccept` date DEFAULT NULL,
-  `lastreaccept` date DEFAULT NULL,
-  `lastclaim` date DEFAULT NULL,
-  `expiry` date DEFAULT NULL,
-  `cstatus` tinyint(3) unsigned DEFAULT NULL,
-  `transfer` date DEFAULT NULL,
-  `pstatus` tinyint(3) unsigned DEFAULT NULL,
-  UNIQUE KEY `pt_sno` (`pt_sno`),
-  CONSTRAINT `patient_nhs_ibfk_1` FOREIGN KEY (`pt_sno`) REFERENCES `new_patients` (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `patient_nhs`
---
-
-LOCK TABLES `patient_nhs` WRITE;
-/*!40000 ALTER TABLE `patient_nhs` DISABLE KEYS */;
-/*!40000 ALTER TABLE `patient_nhs` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `perio`
---
-
-DROP TABLE IF EXISTS `perio`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `perio` (
-  `serialno` int(11) NOT NULL DEFAULT '0',
-  `chartdate` date NOT NULL DEFAULT '0000-00-00',
-  `bpe` char(6) DEFAULT NULL,
-  `chartdata` blob,
-  `flag` tinyint(3) unsigned DEFAULT NULL,
-  PRIMARY KEY (`serialno`,`chartdate`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `perio`
---
-
-LOCK TABLES `perio` WRITE;
-/*!40000 ALTER TABLE `perio` DISABLE KEYS */;
-/*!40000 ALTER TABLE `perio` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `phrasebook`
---
-
-DROP TABLE IF EXISTS `phrasebook`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `phrasebook` (
-  `clinician_id` int(10) unsigned NOT NULL,
-  `phrases` text,
-  PRIMARY KEY (`clinician_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `phrasebook`
---
-
-LOCK TABLES `phrasebook` WRITE;
-/*!40000 ALTER TABLE `phrasebook` DISABLE KEYS */;
-/*!40000 ALTER TABLE `phrasebook` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `plandata`
---
-
-DROP TABLE IF EXISTS `plandata`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `plandata` (
-  `serialno` int(11) NOT NULL,
-  `plantype` char(4) DEFAULT NULL,
-  `band` char(1) DEFAULT NULL,
-  `grosschg` int(11) DEFAULT NULL,
-  `discount` int(11) DEFAULT NULL,
-  `netchg` int(11) DEFAULT NULL,
-  `catcode` char(1) DEFAULT NULL,
-  `planjoin` date DEFAULT NULL,
-  `regno` int(11) DEFAULT NULL,
-  PRIMARY KEY (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `plandata`
---
-
-LOCK TABLES `plandata` WRITE;
-/*!40000 ALTER TABLE `plandata` DISABLE KEYS */;
-/*!40000 ALTER TABLE `plandata` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `previous_snames`
---
-
-DROP TABLE IF EXISTS `previous_snames`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `previous_snames` (
-  `ix` int(11) unsigned NOT NULL AUTO_INCREMENT,
-  `serialno` int(11) DEFAULT NULL,
-  `psn` char(40) NOT NULL,
-  PRIMARY KEY (`ix`),
-  KEY `serialno` (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `previous_snames`
---
-
-LOCK TABLES `previous_snames` WRITE;
-/*!40000 ALTER TABLE `previous_snames` DISABLE KEYS */;
-/*!40000 ALTER TABLE `previous_snames` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `ptmemos`
---
-
-DROP TABLE IF EXISTS `ptmemos`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `ptmemos` (
-  `ix` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `serialno` int(11) DEFAULT NULL,
-  `enabled` tinyint(1) DEFAULT NULL,
-  `author` char(5) DEFAULT NULL,
-  `type` char(5) DEFAULT NULL,
-  `mdate` datetime DEFAULT NULL,
-  `expiredate` date DEFAULT NULL,
-  `message` char(200) DEFAULT NULL,
-  `open` tinyint(1) NOT NULL DEFAULT '1',
-  PRIMARY KEY (`ix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `ptmemos`
---
-
-LOCK TABLES `ptmemos` WRITE;
-/*!40000 ALTER TABLE `ptmemos` DISABLE KEYS */;
-/*!40000 ALTER TABLE `ptmemos` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `records_in_use`
---
-
-DROP TABLE IF EXISTS `records_in_use`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `records_in_use` (
-  `pt_sno` int(11) unsigned NOT NULL,
-  `surgery_number` smallint(6) DEFAULT NULL,
-  `op` varchar(24) DEFAULT NULL,
-  `locked` tinyint(1) NOT NULL DEFAULT '0',
-  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `records_in_use`
---
-
-LOCK TABLES `records_in_use` WRITE;
-/*!40000 ALTER TABLE `records_in_use` DISABLE KEYS */;
-/*!40000 ALTER TABLE `records_in_use` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `referral_centres`
---
-
-DROP TABLE IF EXISTS `referral_centres`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `referral_centres` (
-  `ix` int(11) unsigned NOT NULL AUTO_INCREMENT,
-  `description` char(64) NOT NULL DEFAULT 'referral',
-  `greeting` char(64) NOT NULL DEFAULT 'Dear Sir/Madam',
-  `addr1` char(64) NOT NULL DEFAULT '',
-  `addr2` char(64) NOT NULL DEFAULT '',
-  `addr3` char(64) NOT NULL DEFAULT '',
-  `addr4` char(64) NOT NULL DEFAULT '',
-  `addr5` char(64) NOT NULL DEFAULT '',
-  `addr6` char(64) NOT NULL DEFAULT '',
-  `addr7` char(64) NOT NULL DEFAULT '',
-  PRIMARY KEY (`ix`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `referral_centres`
---
-
-LOCK TABLES `referral_centres` WRITE;
-/*!40000 ALTER TABLE `referral_centres` DISABLE KEYS */;
-/*!40000 ALTER TABLE `referral_centres` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `settings`
---
-
-DROP TABLE IF EXISTS `settings`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `settings` (
-  `ix` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `value` varchar(128) DEFAULT NULL,
-  `data` text,
-  `hostname` varchar(128) DEFAULT NULL,
-  `station` char(20) DEFAULT NULL,
-  `user` char(20) DEFAULT NULL,
-  `modified_by` varchar(20) NOT NULL,
-  `time_stamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-  PRIMARY KEY (`ix`),
-  KEY `value` (`value`)
-) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `settings`
---
-
-LOCK TABLES `settings` WRITE;
-/*!40000 ALTER TABLE `settings` DISABLE KEYS */;
-INSERT INTO `settings` VALUES (1,'wikiurl','http://openmolar.com/wiki',NULL,NULL,NULL,'neil at openmolar.com','2014-06-10 17:52:59'),(2,'Schema_Version','2.9',NULL,NULL,NULL,'neil at openmolar.com','2014-07-01 12:51:30'),(3,'Schema_Version','3.0',NULL,NULL,NULL,'2_9 to 3_0 script','2016-09-14 12:15:42'),(5,'Schema_Version','3.1',NULL,NULL,NULL,'3_0 to 3_1 script','2016-09-14 12:15:45'),(7,'Schema_Version','3.2',NULL,NULL,NULL,'3.1 to 3.2 script','2016-09-14 12:15:48'),(9,'Schema_Version','3.3' [...]
-/*!40000 ALTER TABLE `settings` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `standard_letters`
---
-
-DROP TABLE IF EXISTS `standard_letters`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `standard_letters` (
-  `ix` int(11) unsigned NOT NULL AUTO_INCREMENT,
-  `description` char(64) NOT NULL,
-  `body_text` text NOT NULL,
-  `footer` text,
-  PRIMARY KEY (`ix`),
-  UNIQUE KEY `description` (`description`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `standard_letters`
---
-
-LOCK TABLES `standard_letters` WRITE;
-/*!40000 ALTER TABLE `standard_letters` DISABLE KEYS */;
-INSERT INTO `standard_letters` VALUES (1,'XRay Request Letter','<br />\n<div align=\"center\"><b>XRAY REQUEST</b></div>\n<br />\n<p>You have requested copies of your xrays to take with you to another practice.<br />\nPlease be advise that we are happy to do this, and provide these as Jpeg files on CD-rom.\n</p>\n<p>\nThere is, however, a nominal charge of £15.00 for this service, which is in line with British Dental Association recommendations.\n</p>\n<p>\nShould you wish to procee [...]
-/*!40000 ALTER TABLE `standard_letters` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `static_chart`
---
-
-DROP TABLE IF EXISTS `static_chart`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `static_chart` (
-  `pt_sno` int(11) NOT NULL,
-  `dent0` tinyint(4) DEFAULT NULL,
-  `dent1` tinyint(4) DEFAULT NULL,
-  `dent2` tinyint(4) DEFAULT NULL,
-  `dent3` tinyint(4) DEFAULT NULL,
-  `ur1` varchar(34) NOT NULL DEFAULT '',
-  `ur2` varchar(34) NOT NULL DEFAULT '',
-  `ur3` varchar(34) NOT NULL DEFAULT '',
-  `ur4` varchar(34) NOT NULL DEFAULT '',
-  `ur5` varchar(34) NOT NULL DEFAULT '',
-  `ur6` varchar(34) NOT NULL DEFAULT '',
-  `ur7` varchar(34) NOT NULL DEFAULT '',
-  `ur8` varchar(34) NOT NULL DEFAULT '',
-  `ul1` varchar(34) NOT NULL DEFAULT '',
-  `ul2` varchar(34) NOT NULL DEFAULT '',
-  `ul3` varchar(34) NOT NULL DEFAULT '',
-  `ul4` varchar(34) NOT NULL DEFAULT '',
-  `ul5` varchar(34) NOT NULL DEFAULT '',
-  `ul6` varchar(34) NOT NULL DEFAULT '',
-  `ul7` varchar(34) NOT NULL DEFAULT '',
-  `ul8` varchar(34) NOT NULL DEFAULT '',
-  `lr1` varchar(34) NOT NULL DEFAULT '',
-  `lr2` varchar(34) NOT NULL DEFAULT '',
-  `lr3` varchar(34) NOT NULL DEFAULT '',
-  `lr4` varchar(34) NOT NULL DEFAULT '',
-  `lr5` varchar(34) NOT NULL DEFAULT '',
-  `lr6` varchar(34) NOT NULL DEFAULT '',
-  `lr7` varchar(34) NOT NULL DEFAULT '',
-  `lr8` varchar(34) NOT NULL DEFAULT '',
-  `ll1` varchar(34) NOT NULL DEFAULT '',
-  `ll2` varchar(34) NOT NULL DEFAULT '',
-  `ll3` varchar(34) NOT NULL DEFAULT '',
-  `ll4` varchar(34) NOT NULL DEFAULT '',
-  `ll5` varchar(34) NOT NULL DEFAULT '',
-  `ll6` varchar(34) NOT NULL DEFAULT '',
-  `ll7` varchar(34) NOT NULL DEFAULT '',
-  `ll8` varchar(34) NOT NULL DEFAULT '',
-  UNIQUE KEY `pt_sno` (`pt_sno`),
-  CONSTRAINT `static_chart_ibfk_1` FOREIGN KEY (`pt_sno`) REFERENCES `new_patients` (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `static_chart`
---
-
-LOCK TABLES `static_chart` WRITE;
-/*!40000 ALTER TABLE `static_chart` DISABLE KEYS */;
-INSERT INTO `static_chart` VALUES (1,NULL,16,NULL,NULL,'PV ','CR,LAVA ','MI ','B,GL ','MOD ','MO,CO ','','UE ','IM/TIT IM/ABUT  CR,V1 ','','','GI/MOD RT ','','','','UE ','','','','','OL,CO ','B ','FS ','UE ','','','','','','MOL,CO ','','UE ');
-/*!40000 ALTER TABLE `static_chart` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
--- Table structure for table `userdata`
---
-
-DROP TABLE IF EXISTS `userdata`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `userdata` (
-  `serialno` int(11) NOT NULL,
-  `data` blob,
-  PRIMARY KEY (`serialno`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `userdata`
---
-
-LOCK TABLES `userdata` WRITE;
-/*!40000 ALTER TABLE `userdata` DISABLE KEYS */;
-/*!40000 ALTER TABLE `userdata` ENABLE KEYS */;
-UNLOCK TABLES;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
 /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
-/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
 /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
 /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
 /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
 
--- Dump completed on 2016-09-14 17:04:01
+-- Dump completed on 2016-12-13 13:51:43
diff --git a/src/openmolar/resources/resources.qrc b/src/openmolar/resources/resources.qrc
index bac9fd0..cc76126 100644
--- a/src/openmolar/resources/resources.qrc
+++ b/src/openmolar/resources/resources.qrc
@@ -18,7 +18,6 @@
     <file>icons/chain-broken.png</file>
     <file>icons/chain.png</file>
     <file>private.png</file>
-    <file>hdp.png</file>
     <file>nhs_scot.png</file>
     <file alias="first.png">icons/number1.png</file>
     <file alias="speaker.svg">icons/Speaker_Icon.svg</file>
diff --git a/src/openmolar/resources/schema.sql b/src/openmolar/resources/schema.sql
index 657cade..1760ea1 100644
--- a/src/openmolar/resources/schema.sql
+++ b/src/openmolar/resources/schema.sql
@@ -1,8 +1,8 @@
--- MySQL dump 10.15  Distrib 10.0.26-MariaDB, for debian-linux-gnu (x86_64)
+-- MySQL dump 10.15  Distrib 10.0.28-MariaDB, for debian-linux-gnu (x86_64)
 --
--- Host: localhost    Database: openmolar_demo
+-- Host: localhost    Database: localhost
 -- ------------------------------------------------------
--- Server version	10.0.26-MariaDB-3
+-- Server version	10.0.28-MariaDB-2
 
 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
 /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
@@ -34,50 +34,6 @@ CREATE TABLE `aday` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `aday`
---
-
-LOCK TABLES `aday` WRITE;
-/*!40000 ALTER TABLE `aday` DISABLE KEYS */;
-/*!40000 ALTER TABLE `aday` ENABLE KEYS */;
-UNLOCK TABLES;
-/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
-/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
-/*!50003 SET @saved_col_connection = @@collation_connection */ ;
-/*!50003 SET character_set_client  = utf8 */ ;
-/*!50003 SET character_set_results = utf8 */ ;
-/*!50003 SET collation_connection  = utf8_general_ci */ ;
-/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
-/*!50003 SET sql_mode              = '' */ ;
-DELIMITER ;;
-/*!50003 CREATE*/ /*!50017 DEFINER=`openmolar`@`localhost`*/ /*!50003 TRIGGER aday_update_trigger 
-    BEFORE UPDATE ON aday 
-    FOR EACH ROW 
-        BEGIN 
-            DECLARE clash_count INT; 
-            IF NEW.flag = 0 THEN
-                SET clash_count=(SELECT count(*) FROM aslot WHERE apptix=NEW.apptix AND adate=NEW.adate AND serialno!=0); 
-                IF clash_count>0 THEN 
-                    SIGNAL SQLSTATE '45000' 
-                    SET message_text="existing appointments prevent you blocking this day"; 
-                END IF;
-            ELSE
-                SET clash_count=(SELECT count(*) FROM aslot 
-                WHERE apptix=NEW.apptix AND adate=NEW.adate AND (start<NEW.start OR end>NEW.end)); 
-            
-                IF clash_count>0 THEN 
-                    SIGNAL SQLSTATE '45000' 
-                    SET message_text="existing appointments prevent you changing this day"; 
-                END IF;
-            END IF;
-        END */;;
-DELIMITER ;
-/*!50003 SET sql_mode              = @saved_sql_mode */ ;
-/*!50003 SET character_set_client  = @saved_cs_client */ ;
-/*!50003 SET character_set_results = @saved_cs_results */ ;
-/*!50003 SET collation_connection  = @saved_col_connection */ ;
-
---
 -- Table structure for table `appt_prefs`
 --
 
@@ -100,15 +56,6 @@ CREATE TABLE `appt_prefs` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `appt_prefs`
---
-
-LOCK TABLES `appt_prefs` WRITE;
-/*!40000 ALTER TABLE `appt_prefs` DISABLE KEYS */;
-/*!40000 ALTER TABLE `appt_prefs` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `apr`
 --
 
@@ -137,15 +84,6 @@ CREATE TABLE `apr` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `apr`
---
-
-LOCK TABLES `apr` WRITE;
-/*!40000 ALTER TABLE `apr` DISABLE KEYS */;
-/*!40000 ALTER TABLE `apr` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `aslot`
 --
 
@@ -173,49 +111,6 @@ CREATE TABLE `aslot` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `aslot`
---
-
-LOCK TABLES `aslot` WRITE;
-/*!40000 ALTER TABLE `aslot` DISABLE KEYS */;
-/*!40000 ALTER TABLE `aslot` ENABLE KEYS */;
-UNLOCK TABLES;
-/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
-/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
-/*!50003 SET @saved_col_connection = @@collation_connection */ ;
-/*!50003 SET character_set_client  = utf8 */ ;
-/*!50003 SET character_set_results = utf8 */ ;
-/*!50003 SET collation_connection  = utf8_general_ci */ ;
-/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
-/*!50003 SET sql_mode              = '' */ ;
-DELIMITER ;;
-/*!50003 CREATE*/ /*!50017 DEFINER=`openmolar`@`localhost`*/ /*!50003 TRIGGER aslot_trigger 
-    BEFORE INSERT ON aslot
-    FOR EACH ROW
-    BEGIN 
-        DECLARE appt_count INT;
-        if NEW.start = NEW.end then
-            SET appt_count = 0;
-        else
-            SET appt_count = (
-                SELECT count(*) from aslot 
-                where adate=NEW.adate and start>=NEW.start and start<NEW.end and apptix=NEW.apptix
-                );
-        end if;
-        
-        if appt_count>0 then
-            signal sqlstate '45000' 
-            set message_text = "this appointment clashes with one (or more) already in the database";
-        end if; 
-            
-    END */;;
-DELIMITER ;
-/*!50003 SET sql_mode              = @saved_sql_mode */ ;
-/*!50003 SET character_set_client  = @saved_cs_client */ ;
-/*!50003 SET character_set_results = @saved_cs_results */ ;
-/*!50003 SET collation_connection  = @saved_col_connection */ ;
-
---
 -- Table structure for table `bpe`
 --
 
@@ -231,15 +126,6 @@ CREATE TABLE `bpe` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `bpe`
---
-
-LOCK TABLES `bpe` WRITE;
-/*!40000 ALTER TABLE `bpe` DISABLE KEYS */;
-/*!40000 ALTER TABLE `bpe` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `calendar`
 --
 
@@ -255,15 +141,6 @@ CREATE TABLE `calendar` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `calendar`
---
-
-LOCK TABLES `calendar` WRITE;
-/*!40000 ALTER TABLE `calendar` DISABLE KEYS */;
-/*!40000 ALTER TABLE `calendar` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `calldurr`
 --
 
@@ -278,15 +155,6 @@ CREATE TABLE `calldurr` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `calldurr`
---
-
-LOCK TABLES `calldurr` WRITE;
-/*!40000 ALTER TABLE `calldurr` DISABLE KEYS */;
-/*!40000 ALTER TABLE `calldurr` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `cashbook`
 --
 
@@ -309,15 +177,6 @@ CREATE TABLE `cashbook` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `cashbook`
---
-
-LOCK TABLES `cashbook` WRITE;
-/*!40000 ALTER TABLE `cashbook` DISABLE KEYS */;
-/*!40000 ALTER TABLE `cashbook` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `cbcodes`
 --
 
@@ -332,16 +191,6 @@ CREATE TABLE `cbcodes` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `cbcodes`
---
-
-LOCK TABLES `cbcodes` WRITE;
-/*!40000 ALTER TABLE `cbcodes` DISABLE KEYS */;
-INSERT INTO `cbcodes` VALUES (1,2,'NHS CASH'),(2,2,'PRIVATE CASH'),(3,2,'NHS CHEQUE'),(4,2,'PRIVATE CHEQUE'),(5,2,'NHS CARD'),(6,2,'PRIVATE CARD'),(9,2,'BANK TRANSFER'),(14,2,'SUNDRY CASH'),(15,2,'SUNDRY CHEQUE'),(17,2,'SUNDRY CARD'),(21,2,'ANNUAL HDP'),(24,2,'OTHER'),(125,2,'REFUND');
-/*!40000 ALTER TABLE `cbcodes` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `claims`
 --
 
@@ -398,15 +247,6 @@ CREATE TABLE `claims` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `claims`
---
-
-LOCK TABLES `claims` WRITE;
-/*!40000 ALTER TABLE `claims` DISABLE KEYS */;
-/*!40000 ALTER TABLE `claims` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `clinical_memos`
 --
 
@@ -426,16 +266,6 @@ CREATE TABLE `clinical_memos` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `clinical_memos`
---
-
-LOCK TABLES `clinical_memos` WRITE;
-/*!40000 ALTER TABLE `clinical_memos` DISABLE KEYS */;
-INSERT INTO `clinical_memos` VALUES (1,1,'REC','2014-06-10 20:28:10',0,'This patient is for demonstration purposes only. Any similarity to any person, alive or dead, is entirely unintentional.');
-/*!40000 ALTER TABLE `clinical_memos` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `clinician_dates`
 --
 
@@ -453,15 +283,6 @@ CREATE TABLE `clinician_dates` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `clinician_dates`
---
-
-LOCK TABLES `clinician_dates` WRITE;
-/*!40000 ALTER TABLE `clinician_dates` DISABLE KEYS */;
-/*!40000 ALTER TABLE `clinician_dates` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `clinicians`
 --
 
@@ -483,15 +304,6 @@ CREATE TABLE `clinicians` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `clinicians`
---
-
-LOCK TABLES `clinicians` WRITE;
-/*!40000 ALTER TABLE `clinicians` DISABLE KEYS */;
-/*!40000 ALTER TABLE `clinicians` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `currtrtmt2`
 --
 
@@ -594,15 +406,6 @@ CREATE TABLE `currtrtmt2` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `currtrtmt2`
---
-
-LOCK TABLES `currtrtmt2` WRITE;
-/*!40000 ALTER TABLE `currtrtmt2` DISABLE KEYS */;
-/*!40000 ALTER TABLE `currtrtmt2` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `daybook`
 --
 
@@ -636,15 +439,6 @@ CREATE TABLE `daybook` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `daybook`
---
-
-LOCK TABLES `daybook` WRITE;
-/*!40000 ALTER TABLE `daybook` DISABLE KEYS */;
-/*!40000 ALTER TABLE `daybook` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `daybook_link`
 --
 
@@ -662,15 +456,6 @@ CREATE TABLE `daybook_link` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `daybook_link`
---
-
-LOCK TABLES `daybook_link` WRITE;
-/*!40000 ALTER TABLE `daybook_link` DISABLE KEYS */;
-/*!40000 ALTER TABLE `daybook_link` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `diary_link`
 --
 
@@ -686,15 +471,6 @@ CREATE TABLE `diary_link` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `diary_link`
---
-
-LOCK TABLES `diary_link` WRITE;
-/*!40000 ALTER TABLE `diary_link` DISABLE KEYS */;
-/*!40000 ALTER TABLE `diary_link` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `docsimported`
 --
 
@@ -714,15 +490,6 @@ CREATE TABLE `docsimported` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `docsimported`
---
-
-LOCK TABLES `docsimported` WRITE;
-/*!40000 ALTER TABLE `docsimported` DISABLE KEYS */;
-/*!40000 ALTER TABLE `docsimported` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `docsimporteddata`
 --
 
@@ -739,15 +506,6 @@ CREATE TABLE `docsimporteddata` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `docsimporteddata`
---
-
-LOCK TABLES `docsimporteddata` WRITE;
-/*!40000 ALTER TABLE `docsimporteddata` DISABLE KEYS */;
-/*!40000 ALTER TABLE `docsimporteddata` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `est_link2`
 --
 
@@ -766,15 +524,6 @@ CREATE TABLE `est_link2` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `est_link2`
---
-
-LOCK TABLES `est_link2` WRITE;
-/*!40000 ALTER TABLE `est_link2` DISABLE KEYS */;
-/*!40000 ALTER TABLE `est_link2` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `est_logger`
 --
 
@@ -792,15 +541,6 @@ CREATE TABLE `est_logger` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `est_logger`
---
-
-LOCK TABLES `est_logger` WRITE;
-/*!40000 ALTER TABLE `est_logger` DISABLE KEYS */;
-/*!40000 ALTER TABLE `est_logger` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `exemptions`
 --
 
@@ -819,15 +559,6 @@ CREATE TABLE `exemptions` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `exemptions`
---
-
-LOCK TABLES `exemptions` WRITE;
-/*!40000 ALTER TABLE `exemptions` DISABLE KEYS */;
-/*!40000 ALTER TABLE `exemptions` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `families`
 --
 
@@ -842,15 +573,6 @@ CREATE TABLE `families` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `families`
---
-
-LOCK TABLES `families` WRITE;
-/*!40000 ALTER TABLE `families` DISABLE KEYS */;
-/*!40000 ALTER TABLE `families` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `feescales`
 --
 
@@ -868,16 +590,6 @@ CREATE TABLE `feescales` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `feescales`
---
-
-LOCK TABLES `feescales` WRITE;
-/*!40000 ALTER TABLE `feescales` DISABLE KEYS */;
-INSERT INTO `feescales` VALUES (1,1,0,'example feescale','<?xml version=\"1.0\" ?><feescale>\n	<version>0.1</version>\n	<tablename>test_feescale</tablename>\n	<feescale_description>Example Fee Scale</feescale_description>\n	<category>P</category>\n	<header id=\"1\">Diagnosis</header>\n	<header id=\"2\">Preventive Care</header>\n	<header id=\"3\">Periodontal Treatment</header>\n	<header id=\"4\">Conservative Treatment</header>\n	<header id=\"5\">Endodontic Treatment</header>\n	<header id= [...]
-/*!40000 ALTER TABLE `feescales` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `feetable_key`
 --
 
@@ -900,15 +612,6 @@ CREATE TABLE `feetable_key` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `feetable_key`
---
-
-LOCK TABLES `feetable_key` WRITE;
-/*!40000 ALTER TABLE `feetable_key` DISABLE KEYS */;
-/*!40000 ALTER TABLE `feetable_key` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `formatted_notes`
 --
 
@@ -930,16 +633,6 @@ CREATE TABLE `formatted_notes` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `formatted_notes`
---
-
-LOCK TABLES `formatted_notes` WRITE;
-/*!40000 ALTER TABLE `formatted_notes` DISABLE KEYS */;
-INSERT INTO `formatted_notes` VALUES (1,1,'2014-06-10','REC',NULL,'opened','System date - 10/06/2014 20:26:37','2014-06-10 19:26:37'),(2,1,'2014-06-10','REC',NULL,'newNOTE','This example patient was added to the demo database today.\n','2014-06-10 19:26:37'),(3,1,'2014-06-10','REC',NULL,'closed','REC 10/06/2014 20:26:37','2014-06-10 19:26:37'),(4,1,'2016-09-14','USER',NULL,'opened','System date - 14/09/2016 13:18:01','2016-09-14 12:18:01'),(5,1,'2016-09-14','USER',NULL,'newNOTE','New not [...]
-/*!40000 ALTER TABLE `formatted_notes` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `forum`
 --
 
@@ -959,16 +652,6 @@ CREATE TABLE `forum` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `forum`
---
-
-LOCK TABLES `forum` WRITE;
-/*!40000 ALTER TABLE `forum` DISABLE KEYS */;
-INSERT INTO `forum` VALUES (1,'USER','2016-09-14 13:20:13','An Example Message','A forum is useful for inter surgery communication etc.',1,'EVERYBOD'),(2,'USER','2016-09-14 13:20:56','re. An Example Message','thanks.',1,'EVERYBOD'),(3,'USER','2016-09-14 13:22:05','Another Example message','This message has been marked as important by forum user \"USER\"',1,'USER');
-/*!40000 ALTER TABLE `forum` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `forum_important`
 --
 
@@ -985,16 +668,6 @@ CREATE TABLE `forum_important` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `forum_important`
---
-
-LOCK TABLES `forum_important` WRITE;
-/*!40000 ALTER TABLE `forum_important` DISABLE KEYS */;
-INSERT INTO `forum_important` VALUES (3,'USER');
-/*!40000 ALTER TABLE `forum_important` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `forum_parents`
 --
 
@@ -1012,16 +685,6 @@ CREATE TABLE `forum_parents` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `forum_parents`
---
-
-LOCK TABLES `forum_parents` WRITE;
-/*!40000 ALTER TABLE `forum_parents` DISABLE KEYS */;
-INSERT INTO `forum_parents` VALUES (1,2);
-/*!40000 ALTER TABLE `forum_parents` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `forumread`
 --
 
@@ -1039,14 +702,19 @@ CREATE TABLE `forumread` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `forumread`
+-- Table structure for table `locations`
 --
 
-LOCK TABLES `forumread` WRITE;
-/*!40000 ALTER TABLE `forumread` DISABLE KEYS */;
-INSERT INTO `forumread` VALUES (1,1,'USER','2016-09-14 13:20:13'),(2,1,'USER','2016-09-14 13:20:44'),(3,2,'USER','2016-09-14 13:20:56'),(4,3,'USER','2016-09-14 13:22:05'),(5,3,'USER','2016-09-14 13:22:24');
-/*!40000 ALTER TABLE `forumread` ENABLE KEYS */;
-UNLOCK TABLES;
+DROP TABLE IF EXISTS `locations`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `locations` (
+  `serialno` int(11) NOT NULL,
+  `location` char(1) DEFAULT NULL,
+  PRIMARY KEY (`serialno`),
+  CONSTRAINT `locations_ibfk_1` FOREIGN KEY (`serialno`) REFERENCES `new_patients` (`serialno`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
 
 --
 -- Table structure for table `medforms`
@@ -1063,15 +731,6 @@ CREATE TABLE `medforms` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `medforms`
---
-
-LOCK TABLES `medforms` WRITE;
-/*!40000 ALTER TABLE `medforms` DISABLE KEYS */;
-/*!40000 ALTER TABLE `medforms` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `medhist`
 --
 
@@ -1110,15 +769,6 @@ CREATE TABLE `medhist` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `medhist`
---
-
-LOCK TABLES `medhist` WRITE;
-/*!40000 ALTER TABLE `medhist` DISABLE KEYS */;
-/*!40000 ALTER TABLE `medhist` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `medication_link`
 --
 
@@ -1137,15 +787,6 @@ CREATE TABLE `medication_link` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `medication_link`
---
-
-LOCK TABLES `medication_link` WRITE;
-/*!40000 ALTER TABLE `medication_link` DISABLE KEYS */;
-/*!40000 ALTER TABLE `medication_link` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `medications`
 --
 
@@ -1160,16 +801,6 @@ CREATE TABLE `medications` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `medications`
---
-
-LOCK TABLES `medications` WRITE;
-/*!40000 ALTER TABLE `medications` DISABLE KEYS */;
-INSERT INTO `medications` VALUES ('50:50 Ointment',0),('Abacavir Sulphate',0),('Abatacept',0),('Abciximab',0),('Abelcet',0),('Abidec Multivitamin Drops',0),('Abilify',0),('Acamprosate Calcium',0),('Acarbose',0),('Accolate',0),('Accupro',0),('Accuretic',0),('Acea',0),('Acebutolol',0),('Acebutolol Hydrochloride',0),('Aceclofenac',0),('Acemetacin',0),('Acenocoumarol',0),('Acepril',0),('Acetazolamide',0),('Acetic Acid Cough Linctus',0),('Acetylcholine Chloride',0),('Acetylcysteine',0),('Acez [...]
-/*!40000 ALTER TABLE `medications` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `new_patients`
 --
 
@@ -1213,16 +844,6 @@ CREATE TABLE `new_patients` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `new_patients`
---
-
-LOCK TABLES `new_patients` WRITE;
-/*!40000 ALTER TABLE `new_patients` DISABLE KEYS */;
-INSERT INTO `new_patients` VALUES (1,'PATIENT','EXAMPLE','MR','M','1969-12-09','19 UNION STREET','','','INVERNESS','SCOTLAND, UK','IV1 1PP','','','','','','','','',NULL,'P',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'','');
-/*!40000 ALTER TABLE `new_patients` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `newdocsprinted`
 --
 
@@ -1242,15 +863,6 @@ CREATE TABLE `newdocsprinted` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `newdocsprinted`
---
-
-LOCK TABLES `newdocsprinted` WRITE;
-/*!40000 ALTER TABLE `newdocsprinted` DISABLE KEYS */;
-/*!40000 ALTER TABLE `newdocsprinted` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `newestimates`
 --
 
@@ -1283,15 +895,6 @@ CREATE TABLE `newestimates` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `newestimates`
---
-
-LOCK TABLES `newestimates` WRITE;
-/*!40000 ALTER TABLE `newestimates` DISABLE KEYS */;
-/*!40000 ALTER TABLE `newestimates` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `newfeetable`
 --
 
@@ -1318,15 +921,6 @@ CREATE TABLE `newfeetable` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `newfeetable`
---
-
-LOCK TABLES `newfeetable` WRITE;
-/*!40000 ALTER TABLE `newfeetable` DISABLE KEYS */;
-/*!40000 ALTER TABLE `newfeetable` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `opid`
 --
 
@@ -1343,16 +937,6 @@ CREATE TABLE `opid` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `opid`
---
-
-LOCK TABLES `opid` WRITE;
-/*!40000 ALTER TABLE `opid` DISABLE KEYS */;
-INSERT INTO `opid` VALUES ('REC',NULL,1),('USER',NULL,1);
-/*!40000 ALTER TABLE `opid` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `patient_dates`
 --
 
@@ -1382,16 +966,6 @@ CREATE TABLE `patient_dates` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `patient_dates`
---
-
-LOCK TABLES `patient_dates` WRITE;
-/*!40000 ALTER TABLE `patient_dates` DISABLE KEYS */;
-INSERT INTO `patient_dates` VALUES (1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
-/*!40000 ALTER TABLE `patient_dates` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `patient_money`
 --
 
@@ -1418,16 +992,6 @@ CREATE TABLE `patient_money` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `patient_money`
---
-
-LOCK TABLES `patient_money` WRITE;
-/*!40000 ALTER TABLE `patient_money` DISABLE KEYS */;
-INSERT INTO `patient_money` VALUES (1,0,0,0,0,0,0,0,0,0,0,0,0);
-/*!40000 ALTER TABLE `patient_money` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `patient_nhs`
 --
 
@@ -1449,15 +1013,6 @@ CREATE TABLE `patient_nhs` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `patient_nhs`
---
-
-LOCK TABLES `patient_nhs` WRITE;
-/*!40000 ALTER TABLE `patient_nhs` DISABLE KEYS */;
-/*!40000 ALTER TABLE `patient_nhs` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `perio`
 --
 
@@ -1475,15 +1030,6 @@ CREATE TABLE `perio` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `perio`
---
-
-LOCK TABLES `perio` WRITE;
-/*!40000 ALTER TABLE `perio` DISABLE KEYS */;
-/*!40000 ALTER TABLE `perio` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `phrasebook`
 --
 
@@ -1498,15 +1044,6 @@ CREATE TABLE `phrasebook` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `phrasebook`
---
-
-LOCK TABLES `phrasebook` WRITE;
-/*!40000 ALTER TABLE `phrasebook` DISABLE KEYS */;
-/*!40000 ALTER TABLE `phrasebook` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `plandata`
 --
 
@@ -1528,15 +1065,6 @@ CREATE TABLE `plandata` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `plandata`
---
-
-LOCK TABLES `plandata` WRITE;
-/*!40000 ALTER TABLE `plandata` DISABLE KEYS */;
-/*!40000 ALTER TABLE `plandata` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `previous_snames`
 --
 
@@ -1553,13 +1081,24 @@ CREATE TABLE `previous_snames` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `previous_snames`
+-- Table structure for table `pseudonyms`
 --
 
-LOCK TABLES `previous_snames` WRITE;
-/*!40000 ALTER TABLE `previous_snames` DISABLE KEYS */;
-/*!40000 ALTER TABLE `previous_snames` ENABLE KEYS */;
-UNLOCK TABLES;
+DROP TABLE IF EXISTS `pseudonyms`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `pseudonyms` (
+  `ix` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `serialno` int(11) NOT NULL,
+  `alt_sname` varchar(30) DEFAULT NULL,
+  `alt_fname` varchar(30) DEFAULT NULL,
+  `comment` varchar(60) DEFAULT NULL,
+  `search_include` tinyint(1) NOT NULL DEFAULT '1',
+  PRIMARY KEY (`ix`),
+  UNIQUE KEY `serialno` (`serialno`,`alt_sname`,`alt_fname`),
+  CONSTRAINT `pseudonyms_ibfk_1` FOREIGN KEY (`serialno`) REFERENCES `new_patients` (`serialno`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
 
 --
 -- Table structure for table `ptmemos`
@@ -1583,15 +1122,6 @@ CREATE TABLE `ptmemos` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `ptmemos`
---
-
-LOCK TABLES `ptmemos` WRITE;
-/*!40000 ALTER TABLE `ptmemos` DISABLE KEYS */;
-/*!40000 ALTER TABLE `ptmemos` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `records_in_use`
 --
 
@@ -1608,15 +1138,6 @@ CREATE TABLE `records_in_use` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `records_in_use`
---
-
-LOCK TABLES `records_in_use` WRITE;
-/*!40000 ALTER TABLE `records_in_use` DISABLE KEYS */;
-/*!40000 ALTER TABLE `records_in_use` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `referral_centres`
 --
 
@@ -1639,15 +1160,6 @@ CREATE TABLE `referral_centres` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `referral_centres`
---
-
-LOCK TABLES `referral_centres` WRITE;
-/*!40000 ALTER TABLE `referral_centres` DISABLE KEYS */;
-/*!40000 ALTER TABLE `referral_centres` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `settings`
 --
 
@@ -1665,20 +1177,10 @@ CREATE TABLE `settings` (
   `time_stamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (`ix`),
   KEY `value` (`value`)
-) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `settings`
---
-
-LOCK TABLES `settings` WRITE;
-/*!40000 ALTER TABLE `settings` DISABLE KEYS */;
-INSERT INTO `settings` VALUES (1,'wikiurl','http://openmolar.com/wiki',NULL,NULL,NULL,'neil at openmolar.com','2014-06-10 17:52:59'),(2,'Schema_Version','2.9',NULL,NULL,NULL,'neil at openmolar.com','2014-07-01 12:51:30'),(3,'Schema_Version','3.0',NULL,NULL,NULL,'2_9 to 3_0 script','2016-09-14 12:15:42'),(5,'Schema_Version','3.1',NULL,NULL,NULL,'3_0 to 3_1 script','2016-09-14 12:15:45'),(7,'Schema_Version','3.2',NULL,NULL,NULL,'3.1 to 3.2 script','2016-09-14 12:15:48'),(9,'Schema_Version','3.3' [...]
-/*!40000 ALTER TABLE `settings` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `standard_letters`
 --
 
@@ -1696,16 +1198,6 @@ CREATE TABLE `standard_letters` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `standard_letters`
---
-
-LOCK TABLES `standard_letters` WRITE;
-/*!40000 ALTER TABLE `standard_letters` DISABLE KEYS */;
-INSERT INTO `standard_letters` VALUES (1,'XRay Request Letter','<br />\n<div align=\"center\"><b>XRAY REQUEST</b></div>\n<br />\n<p>You have requested copies of your xrays to take with you to another practice.<br />\nPlease be advise that we are happy to do this, and provide these as Jpeg files on CD-rom.\n</p>\n<p>\nThere is, however, a nominal charge of £15.00 for this service, which is in line with British Dental Association recommendations.\n</p>\n<p>\nShould you wish to procee [...]
-/*!40000 ALTER TABLE `standard_letters` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `static_chart`
 --
 
@@ -1756,16 +1248,6 @@ CREATE TABLE `static_chart` (
 /*!40101 SET character_set_client = @saved_cs_client */;
 
 --
--- Dumping data for table `static_chart`
---
-
-LOCK TABLES `static_chart` WRITE;
-/*!40000 ALTER TABLE `static_chart` DISABLE KEYS */;
-INSERT INTO `static_chart` VALUES (1,NULL,16,NULL,NULL,'PV ','CR,LAVA ','MI ','B,GL ','MOD ','MO,CO ','','UE ','IM/TIT IM/ABUT  CR,V1 ','','','GI/MOD RT ','','','','UE ','','','','','OL,CO ','B ','FS ','UE ','','','','','','MOL,CO ','','UE ');
-/*!40000 ALTER TABLE `static_chart` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
 -- Table structure for table `userdata`
 --
 
@@ -1778,15 +1260,6 @@ CREATE TABLE `userdata` (
   PRIMARY KEY (`serialno`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 /*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `userdata`
---
-
-LOCK TABLES `userdata` WRITE;
-/*!40000 ALTER TABLE `userdata` DISABLE KEYS */;
-/*!40000 ALTER TABLE `userdata` ENABLE KEYS */;
-UNLOCK TABLES;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -1797,4 +1270,4 @@ UNLOCK TABLES;
 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
 /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
 
--- Dump completed on 2016-09-14 17:04:01
+-- Dump completed on 2016-12-13 13:51:43
diff --git a/src/openmolar/resources/triggers.sql b/src/openmolar/resources/triggers.sql
new file mode 100644
index 0000000..07cc560
--- /dev/null
+++ b/src/openmolar/resources/triggers.sql
@@ -0,0 +1,94 @@
+-- MySQL dump 10.15  Distrib 10.0.28-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: localhost    Database: localhost
+-- ------------------------------------------------------
+-- Server version	10.0.28-MariaDB-2
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
+/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
+/*!50003 SET @saved_col_connection = @@collation_connection */ ;
+/*!50003 SET character_set_client  = utf8 */ ;
+/*!50003 SET character_set_results = utf8 */ ;
+/*!50003 SET collation_connection  = utf8_general_ci */ ;
+/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
+/*!50003 SET sql_mode              = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
+DELIMITER ;;
+/*!50003 CREATE*/ /*!50017 DEFINER=`academy`@`localhost`*/ /*!50003 TRIGGER aday_update_trigger 
+    BEFORE UPDATE ON aday 
+    FOR EACH ROW 
+        BEGIN 
+            DECLARE clash_count INT; 
+            IF NEW.flag = 0 THEN
+                SET clash_count=(SELECT count(*) FROM aslot WHERE apptix=NEW.apptix AND adate=NEW.adate AND serialno!=0); 
+                IF clash_count>0 THEN 
+                    SIGNAL SQLSTATE '45000' 
+                    SET message_text="existing appointments prevent you blocking this day"; 
+                END IF;
+            ELSE
+                SET clash_count=(SELECT count(*) FROM aslot 
+                WHERE apptix=NEW.apptix AND adate=NEW.adate AND (start<NEW.start OR end>NEW.end)); 
+            
+                IF clash_count>0 THEN 
+                    SIGNAL SQLSTATE '45000' 
+                    SET message_text="existing appointments prevent you changing this day"; 
+                END IF;
+            END IF;
+        END */;;
+DELIMITER ;
+/*!50003 SET sql_mode              = @saved_sql_mode */ ;
+/*!50003 SET character_set_client  = @saved_cs_client */ ;
+/*!50003 SET character_set_results = @saved_cs_results */ ;
+/*!50003 SET collation_connection  = @saved_col_connection */ ;
+/*!50003 SET @saved_cs_client      = @@character_set_client */ ;
+/*!50003 SET @saved_cs_results     = @@character_set_results */ ;
+/*!50003 SET @saved_col_connection = @@collation_connection */ ;
+/*!50003 SET character_set_client  = utf8 */ ;
+/*!50003 SET character_set_results = utf8 */ ;
+/*!50003 SET collation_connection  = utf8_general_ci */ ;
+/*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
+/*!50003 SET sql_mode              = '' */ ;
+DELIMITER ;;
+/*!50003 CREATE*/ /*!50017 DEFINER=`academy`@`localhost`*/ /*!50003 TRIGGER aslot_trigger 
+    BEFORE INSERT ON aslot
+    FOR EACH ROW
+    BEGIN 
+        DECLARE appt_count INT;
+        if NEW.start = NEW.end then
+            SET appt_count = 0;
+        else
+            SET appt_count = (
+                SELECT count(*) from aslot 
+                where adate=NEW.adate and start>=NEW.start and start<NEW.end and apptix=NEW.apptix
+                );
+        end if;
+        
+        if appt_count>0 then
+            signal sqlstate '45000' 
+            set message_text = "this appointment clashes with one (or more) already in the database";
+        end if; 
+            
+    END */;;
+DELIMITER ;
+/*!50003 SET sql_mode              = @saved_sql_mode */ ;
+/*!50003 SET character_set_client  = @saved_cs_client */ ;
+/*!50003 SET character_set_results = @saved_cs_results */ ;
+/*!50003 SET collation_connection  = @saved_col_connection */ ;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2016-12-13 13:51:43
diff --git a/src/openmolar/schema_upgrades/schema3_5to3_6.py b/src/openmolar/schema_upgrades/schema3_5to3_6.py
new file mode 100644
index 0000000..d88010c
--- /dev/null
+++ b/src/openmolar/schema_upgrades/schema3_5to3_6.py
@@ -0,0 +1,110 @@
+#! /usr/bin/python
+
+# ########################################################################### #
+# #                                                                         # #
+# # Copyright (c) 2009-2016 Neil Wallace <neil at openmolar.com>               # #
+# #                                                                         # #
+# # This file is part of OpenMolar.                                         # #
+# #                                                                         # #
+# # OpenMolar is free software: you can redistribute it and/or modify       # #
+# # it under the terms of the GNU General Public License as published by    # #
+# # the Free Software Foundation, either version 3 of the License, or       # #
+# # (at your option) any later version.                                     # #
+# #                                                                         # #
+# # OpenMolar is distributed in the hope that it will be useful,            # #
+# # but WITHOUT ANY WARRANTY; without even the implied warranty of          # #
+# # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           # #
+# # GNU General Public License for more details.                            # #
+# #                                                                         # #
+# # You should have received a copy of the GNU General Public License       # #
+# # along with OpenMolar.  If not, see <http://www.gnu.org/licenses/>.      # #
+# #                                                                         # #
+# ########################################################################### #
+
+'''
+This module provides a function 'run' which will move data
+to schema 3.6
+'''
+
+
+import logging
+
+from openmolar.schema_upgrades.database_updater_thread \
+    import DatabaseUpdaterThread
+
+LOGGER = logging.getLogger("openmolar")
+
+SQLSTRINGS = [
+    '''
+CREATE TABLE IF NOT EXISTS pseudonyms (
+ix int(10) unsigned NOT NULL auto_increment ,
+serialno int(11) NOT NULL,
+alt_sname varchar(30) DEFAULT NULL,
+alt_fname varchar(30) DEFAULT NULL,
+comment varchar(60) DEFAULT NULL,
+search_include BOOL NOT NULL default True,
+PRIMARY KEY (ix),
+FOREIGN KEY (serialno) REFERENCES new_patients(serialno),
+UNIQUE KEY (serialno, alt_sname, alt_fname)
+)''',
+]
+
+DATA_QUERY = \
+    'SELECT serialno, psn FROM previous_snames'
+
+TRANSFER_STRING = '''INSERT INTO  pseudonyms (serialno, alt_sname, comment)
+VALUES (%%s, %%s, '%s')''' % _('previous surname')
+
+CLEANUPSTRINGS = []
+
+
+class DatabaseUpdater(DatabaseUpdaterThread):
+
+    '''
+    a class to update the database
+    '''
+
+    def transfer_data(self):
+        '''
+        function specific to this update.
+        '''
+
+        self.cursor.execute(DATA_QUERY)
+        for serialno, psn in self.cursor.fetchall():
+            values = (serialno, psn)  #code not concise but has good clarity
+            self.cursor.execute(TRANSFER_STRING, values)
+
+    def run(self):
+        LOGGER.info("running script to convert from schema 3.5 to 3.6")
+        try:
+            self.connect()
+            # - execute the SQL commands
+            self.progressSig(10, _("creating new tables"))
+            self.execute_statements(SQLSTRINGS)
+            self.progressSig(30, _("transferring data"))
+            self.transfer_data()
+
+            self.progressSig(75, _("executing cleanup statements"))
+            self.execute_statements(CLEANUPSTRINGS)
+
+            self.progressSig(97, _('updating settings'))
+            LOGGER.info("updating stored database version in settings table")
+
+            self.update_schema_version(("3.6",), "3.5 to 3.6 script")
+
+            self.progressSig(100, _("updating stored schema version"))
+            self.commit()
+            self.completeSig(_("Successfully moved db to") + " 3.6")
+            return True
+        except Exception as exc:
+            LOGGER.exception("error upgrading schema")
+            self.rollback()
+            raise self.UpdateError(exc)
+
+
+if __name__ == "__main__":
+    dbu = DatabaseUpdater()
+    if dbu.run():
+        LOGGER.info("ALL DONE, conversion successful")
+    else:
+        LOGGER.warning("conversion failed")
diff --git a/src/openmolar/dbtools/writeNewPatient.py b/src/openmolar/schema_upgrades/schema3_6to3_7.py
similarity index 52%
copy from src/openmolar/dbtools/writeNewPatient.py
copy to src/openmolar/schema_upgrades/schema3_6to3_7.py
index 0eb880d..5948418 100644
--- a/src/openmolar/dbtools/writeNewPatient.py
+++ b/src/openmolar/schema_upgrades/schema3_6to3_7.py
@@ -21,60 +21,64 @@
 # #                                                                         # #
 # ########################################################################### #
 
-import MySQLdb
-from openmolar import connect
-from openmolar.dbtools import patient_class
-from openmolar.settings import localsettings
-
-
-def commit(pt):
-    sqlcond = ""
-    values = []
-    for attr in patient_class.patientTableAtts:
-        value = pt.__dict__[attr]
-        if value:
-            sqlcond += '%s = %%s,' % attr
-            values.append(value)
-
-    sqlcommand = "insert into new_patients SET %s serialno=%%s" % sqlcond
-
-    query = "select max(serialno) from new_patients"
-
-    Attempts = 0
-    while True:
-        db = connect.connect()
-        cursor = db.cursor()
-        cursor.execute(query)
-        currentMax = cursor.fetchone()[0]
-
-        if currentMax:
-            newSerialno = currentMax + 1
-        else:
-            newSerialno = 1
+'''
+This module provides a function 'run' which will move data
+to schema 3.7
+'''
+
+
+import logging
+
+from openmolar.schema_upgrades.database_updater_thread \
+    import DatabaseUpdaterThread
+
+LOGGER = logging.getLogger("openmolar")
+
+SQLSTRINGS = [
+    '''
+CREATE TABLE IF NOT EXISTS locations (
+serialno INT(11) NOT NULL,
+location CHAR(1),
+PRIMARY KEY (serialno),
+FOREIGN KEY (serialno) REFERENCES new_patients(serialno)
+)
+    ''',
+]
+
+CLEANUPSTRINGS = []
+
+
+class DatabaseUpdater(DatabaseUpdaterThread):
+
+    '''
+    a class to update the database
+    '''
+
+    def run(self):
+        LOGGER.info("running script to convert from schema 3.6 to 3.7")
         try:
-            cursor.execute(sqlcommand, tuple(values + [newSerialno]))
-            cursor.close()
-            db.commit()
-            break
+            self.connect()
+            # - execute the SQL commands
+            self.progressSig(10, _("creating new tables"))
+            self.execute_statements(SQLSTRINGS)
+            self.progressSig(97, _('updating settings'))
+            LOGGER.info("updating stored database version in settings table")
 
-        except connect.IntegrityError as exc:
-            print("error saving new patient, will retry with new serialno")
-            print(exc)
-            newSerialno = -1
+            self.update_schema_version(("3.7",), "3.6 to 3.7 script")
 
-        Attempts += 1
-        if Attempts > 20:
-            break
-    # db.close()
-    return newSerialno
+            self.progressSig(100, _("updating stored schema version"))
+            self.commit()
+            self.completeSig(_("Successfully moved db to") + " 3.7")
+            return True
+        except Exception as exc:
+            LOGGER.exception("error upgrading schema")
+            self.rollback()
+            raise self.UpdateError(exc)
 
 
 if __name__ == "__main__":
-    global pt
-    from openmolar.dbtools import patient_class
-    import copy
-    pt = patient_class.patient(0)
-    pt.fname = "Norman"
-    pt.sname = "Wisdom"
-    # ok - so a trivial change has been made - now write to the database
-    print(commit(pt))
+    dbu = DatabaseUpdater()
+    if dbu.run():
+        LOGGER.info("ALL DONE, conversion successful")
+    else:
+        LOGGER.warning("conversion failed")
diff --git a/src/openmolar/settings/fee_tables.py b/src/openmolar/settings/fee_tables.py
index bffe6a4..f997f5f 100644
--- a/src/openmolar/settings/fee_tables.py
+++ b/src/openmolar/settings/fee_tables.py
@@ -124,6 +124,7 @@ class FeeTables(object):
             for cset in table.categories:
                 if cset not in csetypes:
                     csetypes.append(cset)
+        LOGGER.debug("Coursetypes found are %s", csetypes)
         return csetypes
 
     @property
@@ -907,7 +908,9 @@ class Modifier(object):
         self.item_ids = []
         self.item_id_regexes = []
         self._gross_fee = None
-        self._charge_fee = None
+        self._charge_fee = None  # allow for a charge which can vary in any way
+                                 # from the fee (eg. free exams on over 80s)
+        self._charge_percent = None  # allow for a discount or supplement
 
         for node in modifier_node.getElementsByTagName("condition"):
             self.conditions.append(_stripped(node.firstChild.data))
@@ -923,8 +926,12 @@ class Modifier(object):
         except IndexError:
             pass  # no gross fee modification
         try:
-            self._charge_fee = int(modifier_node.getElementsByTagName(
-                                   "charge")[0].firstChild.data)
+            charge_data = modifier_node.getElementsByTagName(
+                "charge")[0].firstChild.data
+            if "%" in charge_data:
+                self._charge_percent = int(charge_data.replace("%", ""))/100
+            else:
+                self._charge_fee = int(charge_data)
         except IndexError:
             pass  # no charge fee modication
 
@@ -972,6 +979,8 @@ class Modifier(object):
         modify the original fee supplied by the feescale
         this function could do more.. eg %age increases etc?
         '''
+        if self._charge_percent is not None:
+            return int(fee * self._charge_percent)
         if self._charge_fee is not None:
             return self._charge_fee
         return fee
diff --git a/src/openmolar/settings/localsettings.py b/src/openmolar/settings/localsettings.py
index ed14cc7..aeae534 100644
--- a/src/openmolar/settings/localsettings.py
+++ b/src/openmolar/settings/localsettings.py
@@ -44,8 +44,8 @@ SUPERVISOR = "c1219df26de403348e211a314ff2fce58aa6e28d"
 
 DBNAME = "default"
 
-# updated 06th September 2016
-CLIENT_SCHEMA_VERSION = "3.5"
+# updated 23th November 2016
+CLIENT_SCHEMA_VERSION = "3.7"
 
 DB_SCHEMA_VERSION = "unknown"
 
@@ -377,11 +377,14 @@ LAST_ADDRESS = BLANK_ADDRESS
 # - 1 less dialog box for these lucky people
 defaultPrinterforGP17 = False
 
-# - my own class of excpetion, for when a serialno is called
-# -from the database and no match is found
-
+# - users who shouldn't post to the forum
+disallowed_forum_posters = []
 
 class PatientNotFoundError(Exception):
+    '''
+    my own class of exception, for when a serialno is called
+    from the database and no match is found
+    '''
     pass
 
 
@@ -510,6 +513,7 @@ def GP17formatDate(d):
     except AttributeError:
         return " " * 8
 
+
 try:
     DAYNAMES = (locale.nl_langinfo(locale.DAY_2),
                 locale.nl_langinfo(locale.DAY_3),
@@ -608,6 +612,7 @@ def readableDate(d):
         return _("Yesterday")
     return longDate(d)
 
+
 def readableDateTime(d):
     date_ = d.date()
     today = currentDay()
@@ -623,6 +628,7 @@ def readableDateTime(d):
 
     return "%s %s" % (date_str, d.time().strftime("%H:%M"))
 
+
 def notesDate(d):
     '''
     takes a python date type, returns either the date,
@@ -875,7 +881,7 @@ def initiate(changed_server=False):
     LOGGER.debug("initiating settings from database")
     global message, dentDict, ops, SUPERVISOR, \
         ops_reverse, activedents, activehygs, activedent_ixs, activehyg_ixs, \
-        dent_ixs, hyg_ixs, \
+        dent_ixs, hyg_ixs, disallowed_forum_posters, \
         apptix, apptix_reverse, BOOKEND, clinicianNo, clinicianInits, \
         WIKIURL, cashbookCodesDict, PT_COUNT, PRACTICE_ADDRESS, PRACTICE_NAME
 
@@ -906,6 +912,7 @@ def initiate(changed_server=False):
     activehygs, activehyg_ixs = settings_fetcher.active_hygs
     dent_ixs = settings_fetcher.archived_dents + activedent_ixs
     hyg_ixs = settings_fetcher.archived_hygs + activehyg_ixs
+    disallowed_forum_posters = settings_fetcher.disallowed_forum_posters
 
     PRACTICE_NAME = settings_fetcher.practice_name
     PRACTICE_ADDRESS = settings_fetcher.practice_address
diff --git a/src/openmolar/settings/version.py b/src/openmolar/settings/version.py
index 8422a4a..c955788 100644
--- a/src/openmolar/settings/version.py
+++ b/src/openmolar/settings/version.py
@@ -27,7 +27,7 @@ Do not edit this file manually, as it should be updated by make version
 when git tag is updated.
 '''
 
-VERSION = "1.0"
+VERSION = "1.0.15-gd81f9e5"
 
 
 if __name__ == '__main__':

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/openmolar.git



More information about the debian-med-commit mailing list