# -*- coding: utf-8 -*- from trac.core import * from trac.perm import PermissionSystem from trac.db import Table, Column, Index from datetime import datetime from trac.util.datefmt import utc, to_timestamp from trac.util.text import to_unicode from trac.env import IEnvironmentSetupParticipant from tracbooking.utils import validate_id, make_hash __all__ = [ 'Attendee', 'BookingOption', 'AvailableOption', 'BookingModelsupplier', 'Event', 'EventAccount', 'Option2Event', 'Supplier', 'BookingReminder', "AvailableOptionVariation", "BookingOptionVariation"] class BookingOption(object): def __init__(self, env, bo_id, a_id, ao_id, count, fetch_variations=False): self.env = env self.bo_id = int(bo_id) self.a_id = int(a_id) self.ao_id = int(ao_id) self.count = int(count) self.variations = [] if fetch_variations: self.variations = BookingOptionVariation.fetch_by_attendee(env, a_id) @staticmethod def fetch_one(env, a_id, ao_id, fetch_variations=False): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT bo_id, a_id, ao_id, count " \ "FROM booking_option " \ "WHERE a_id=%s and ao_id=%s", (a_id, ao_id)) row = cursor.fetchone() if not row: return [] return BookingOption(env, fetch_variations=fetch_variations, *row) @staticmethod def fetch_by_attendee(env, a_id, fetch_variations=False): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT bo_id, a_id, ao_id, count FROM booking_option " \ "WHERE a_id=%s", (a_id,)) rows = cursor.fetchall() if not rows: return [] return [BookingOption(env, fetch_variations=fetch_variations, *row) for row in rows] @staticmethod def exists(env, a_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT COUNT(*) FROM booking_option " \ "WHERE o_id=%s;", (a_id,)) row = cursor.fetchone() return row[0] > 0 def commit(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO booking_option " \ "(a_id, ao_id, count) " \ "VALUES(%s, %s, %s);", ( self.a_id, self.ao_id, self.count)) db.commit() self.bo_id = db.get_last_id(cursor, 'booking_option') @staticmethod def delete(env, a_id, ao_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("DELETE FROM booking_option " \ "WHERE a_id =%s and ao_id=%s;", (a_id, ao_id)) db.commit() @staticmethod def delete_by_attendee(env, a_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("DELETE FROM booking_option " \ "WHERE a_id =%s;", (a_id,)) db.commit() def update(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("UPDATE booking_option " \ "SET count=%s " \ "WHERE a_id=%s and ao_id=%s;", ( self.count, self.a_id, self.ao_id)) db.commit() class BookingOptionVariation(object): def __init__(self, env, attendee_id, variation_id, ovi_id): self.env = env self.attendee_id = attendee_id self.variation_id = variation_id self.ovi_id = ovi_id @staticmethod def fetch_one(env, attendee_id, variation_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT attendee_id,variation_id,ovi_id " \ "FROM booking_option_variations " \ "WHERE attendee_id=%s AND variation_id=%s;", (attendee_id,variation_id)) row = cursor.fetchone() return row and BookingOptionVariation(env, *row) or None @staticmethod def fetch_by_attendee(env, attendee_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT attendee_id,variation_id,ovi_id " \ "FROM booking_option_variations " \ "WHERE attendee_id=%s;", (attendee_id,)) return [BookingOptionVariation(env, *row) for row in cursor.fetchall()] def commit(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO booking_option_variations " \ "(attendee_id,variation_id,ovi_id) " \ "VALUES(%s, %s, %s);", ( self.attendee_id, self.variation_id, self.ovi_id)) db.commit() @staticmethod def delete(self, env, bov_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("DELETE FROM booking_option_variations " \ "WHERE attendee_id=%s and variation_id=%s;", (attendee_id,variation_id)) db.commit() @staticmethod def update(env, attendee_id, variation_id, ovi_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("UPDATE booking_option_variations " \ "SET ovi_id=%s WHERE attendee_id=%s and variation_id=%s;", (ovi_id, attendee_id, variation_id)) db.commit() class AvailableOption(object): def __init__(self, env, ao_id, name, description, price, active, min_count, max_count, supplier_id, ext_id, stock_count, fetch_variations=True, attendee_id=None): self.env = env self.ao_id = ao_id self.name = name self.description = description self.price = price self.active = active self.min_count = min_count self.max_count = max_count self.supplier_id = supplier_id self.ext_id = ext_id self.stock_count = stock_count self.variations = fetch_variations and AvailableOptionVariation.fetch_all(env, ao_id, attendee_id=attendee_id) or [] @staticmethod def fetch_one(env, ao_id=None, name=None, fetch_variations=True, attendee_id=None): db = env.get_db_cnx() cursor = db.cursor() if not name: cursor.execute("""SELECT ao_id,name,description,price,active,min_count,max_count,supplier_id,ext_id,stock_count FROM booking_available_option WHERE ao_id=%s""", (ao_id,)) else: cursor.execute("""SELECT ao_id,name,description,price,active,min_count,max_count,supplier_id,ext_id,stock_count FROM booking_available_option WHERE name=%s""", (name,)) row = cursor.fetchone() if not row: return None return AvailableOption(env, fetch_variations=fetch_variations, attendee_id=attendee_id, *row) @staticmethod def fetch_all(env, only_active=False, fetch_variations=True): db = env.get_db_cnx() cursor = db.cursor() if not only_active: cursor.execute("""SELECT ao_id,name,description,price,active,min_count,max_count,supplier_id,ext_id,stock_count FROM booking_available_option;""") else: cursor.execute("""SELECT ao_id,name,description,price,active,min_count,max_count,supplier_id,ext_id,stock_count FROM booking_available_option where active=1;""") return [AvailableOption(env, fetch_variations=fetch_variations, *row) for row in cursor.fetchall()] @staticmethod def fetch_by_event(env, e_id): maps = Option2Event.fetch_by_event(env, e_id) db = env.get_db_cnx() cursor = db.cursor() maps = [m.ao_id for m in maps] s = """SELECT ao_id,name,description,price,active,min_count,max_count,supplier_id,ext_id,stock_count FROM booking_available_option where ao_id in %s;""" % str(tuple(maps)) cursor.execute(s) rows = cursor.fetchall() if not rows: return [] return [AvailableOption(env, *row) for row in cursor.fetchall()] def commit(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("""INSERT INTO booking_available_option (name, description, price, active, min_count, max_count,supplier_id,ext_id,stock_count) VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)""", ( self.name, self.description, self.price, self.active, self.min_count, self.max_count, self.supplier_id, self.ext_id, self.stock_count)) db.commit() self.ao_id = db.get_last_id(cursor, 'booking_available_option') @staticmethod def delete(env, ao_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("""DELETE FROM booking_available_option WHERE ao_id =%s;""", (ao_id,)) db.commit() def update(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("""UPDATE booking_available_option SET name=%s, description=%s, price=%s, active=%s, min_count=%s, max_count=%s, supplier_id=%s, ext_id=%s, stock_count=%s WHERE ao_id = %s;""", ( self.name, self.description, self.price, self.active, self.min_count, self.max_count, self.supplier_id, self.ext_id, self.stock_count, self.ao_id)) db.commit() class AvailableOptionVariation(object): def __init__(self, env, variation_id, option_id, name, attendee_id=None): self.env = env self.variation_id = variation_id self.option_id = option_id self.name = name self.variations = AvailableOptionVariationItem.fetch_all(env, variation_id) self.selected_data = None if attendee_id: selected = attendee_id and BookingOptionVariation.fetch_one(env, attendee_id, variation_id) or None if selected: self.selected_data = AvailableOptionVariationItem.fetch_one(env, selected.ovi_id) @staticmethod def fetch_one(env, variation_id=None, attendee_id=None): db = env.get_db_cnx() cursor = db.cursor() if not name: cursor.execute("SELECT variation_id,option_id,name " \ "FROM booking_available_option_variations " \ "WHERE variation_id=%s", (variation_id,)) row = cursor.fetchone() if not row: return None return AvailableOptionVariation(env, attendee_id=attendee_id, *row) @staticmethod def fetch_all(env, option_id, attendee_id=None): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT variation_id,option_id,name " \ "FROM booking_available_option_variations " \ "WHERE option_id=%s", (option_id,)) rows = cursor.fetchall() if not rows: return None return [AvailableOptionVariation(env, attendee_id=attendee_id, *row) for row in rows] def commit(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO booking_available_option_variations " \ "(option_id, name) " \ "VALUES(%s, %s, %s)", ( self.option_id, self.name)) db.commit() self.variation_id = db.get_last_id(cursor, 'booking_available_option_variations') @staticmethod def delete(env, ovi_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("DELETE FROM booking_available_option_variations " \ "WHERE variation_id =%s;", (variation_id,)) db.commit() def update(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("PDATE booking_available_option_variations " \ "SET option_id=%s, " \ "name=%s " \ "WHERE variation_id = %s;", ( self.option_id, self.name, self.variation_id)) db.commit() class AvailableOptionVariationItem(object): def __init__(self, env, ovi_id, variation_id, name, value, description=""): self.env = env self.ovi_id = ovi_id self.variation_id = variation_id self.name = name self.value = value self.description = description @staticmethod def fetch_one(env, ovi_id=None): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT ovi_id,variation_id,name,value,description " \ "FROM booking_available_option_variation_items " \ "WHERE ovi_id=%s", (ovi_id,)) row = cursor.fetchone() if not row: return None return AvailableOptionVariationItem(env, *row) @staticmethod def fetch_all(env, variation_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT ovi_id,variation_id,name,value,description " \ "FROM booking_available_option_variation_items " \ "WHERE variation_id=%s", (variation_id,)) rows = cursor.fetchall() if not rows: return None return [AvailableOptionVariationItem(env, *row) for row in rows] def commit(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO booking_available_option_variation_items " \ "(variation_id, name, value) " \ "VALUES(%s, %s, %s, %s)", ( self.variation_id, self.name, self.value, self.description)) db.commit() self.ovi_id = db.get_last_id(cursor, 'booking_available_option_variation_items') @staticmethod def delete(env, ovi_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("DELETE FROM booking_available_option_variation_items " \ "WHERE ovi_id =%s;", (ovi_id,)) db.commit() def update(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("UPDATE booking_available_option_variation_items " \ "SET variation_id=%s, " \ "name=%s, " \ "value=%s, " \ "description=%s " \ "WHERE ovi_id = %s;", ( self.variation_id, self.name, self.value, self.description, self.ovi_id)) db.commit() class Supplier(object): """I hate this coding shit. sqlalchemy rulez!""" def __init__(self, env, supplier_id, name, address, phone, email, fax): self.env = env self.supplier_id = int(supplier_id) self.name = name self.address = address self.phone = phone self.email = email self.fax = fax @staticmethod def fetch_one(env, supplier_id=0, name=None): db = env.get_db_cnx() cursor = db.cursor() if not name: cursor.execute("SELECT name, address, phone, email, fax " \ "FROM supplier " \ "WHERE supplier_id=%s", (supplier_id,)) else: cursor.execute("SELECT name, address, phone, email, fax " \ "FROM supplier " \ "WHERE name=%s", (name,)) row = cursor.fetchone() if not row: return None return Supplier(env, *row) @staticmethod def fetch_all(env): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT supplier_id, name, address, phone, email, fax FROM supplier;") rows = cursor.fetchall() if not rows: return [] return [Supplier(env, *row) for row in rows] def commit(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO supplier " \ "(name, address, phone, email, fax) " \ "VALUES(%s, %s, %s, %s, %s)", ( self.supplier_id, self.name, self.address, self.phone, self.email, self.fax)) db.commit() self.supplier_id = db.get_last_id(cursor, 'supplier') @staticmethod def delete(env, a_id, e_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("DELETE FROM supplier WHERE supplier_id = %s;", (supplier_id,)) db.commit() def update(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("UPDATE supplier " \ "SET name=%s, " \ "address=%s, " \ "phone=%s, " \ "email=%s, " \ "fax=%s " \ "WHERE supplier_id=%s;", ( self.name, self.address, self.phone, self.email, self.fax, self.supplier_id)) db.commit() class Attendee(object): def __init__(self, env, a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount, fetch_options=False, fetch_variations=False): self.env = env self.a_id = int(a_id) self.e_id = int(e_id) self.ext_id = to_unicode(ext_id) self.nick = to_unicode(nick) self.email = to_unicode(email) self.finished = int(bool(finished)) self.has_paid = int(bool(has_paid)) self.time = time self.actual_amount = actual_amount self.options = None if fetch_options: self.options = BookingOption.fetch_by_attendee(env, self.a_id, fetch_variations=fetch_variations) @staticmethod def fetch_one(env, a_id=0, nick=None, e_id=0, fetch_options=False, fetch_variations=False): db = env.get_db_cnx() cursor = db.cursor() if not nick: cursor.execute("""SELECT a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount FROM attendee WHERE a_id=%s""", (a_id,)) else: cursor.execute("""SELECT a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount FROM attendee WHERE nick=%s and e_id=%s""", (nick, e_id)) row = cursor.fetchone() if not row: return None a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount = row return Attendee(env, a_id, e_id, ext_id, nick, email, finished, has_paid, datetime.utcfromtimestamp(time), actual_amount, fetch_options=fetch_options, fetch_variations=fetch_variations) @staticmethod def fetch_all(env, e_id=0, fetch_options=False, fetch_variations=False): db = env.get_db_cnx() cursor = db.cursor() s = "SELECT a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount FROM attendee %s;" if e_id > 0: s = s % "WHERE attendee.e_id=%s" cursor.execute(s, (e_id,)) else: cursor.execute(s % "") rows = cursor.fetchall() if not rows: return [] res = [] for row in rows: a_id, e_id, ext_id, nick, email, finished, has_paid, time, actual_amount = row res.append(Attendee(env, a_id, e_id, ext_id, nick, email, finished, has_paid, datetime.utcfromtimestamp(time), actual_amount, fetch_options=fetch_options, fetch_variations=fetch_variations)) return res @staticmethod def fetch_all_sorted(env, e_id=0, fetch_options=False): db = env.get_db_cnx() cursor = db.cursor() s = "SELECT attendee.a_id, attendee.e_id, attendee.ext_id, attendee.nick, attendee.email, attendee.finished, attendee.has_paid, attendee.time, attendee.actual_amount, booking_event.name FROM attendee, booking_event WHERE attendee.e_id=booking_event.e_id %s ORDER BY booking_event.name;" if e_id > 0: s = s % "AND attendee.e_id=%s" cursor.execute(s, (e_id,)) else: cursor.execute(s % "") rows = cursor.fetchall() if not rows: return [] oldname = rows[0][-1] curname = rows[0][-1] res = [] tmp = [] for row in rows: curname = row[-1] if curname != oldname: res.append(tmp) tmp = [] a_id, e_id, ext_id, nick, email, finished, has_paid, time, name, actual_amount = row a = Attendee(env, a_id, e_id, ext_id, nick, email, finished, has_paid, datetime.utcfromtimestamp(time), actual_amount, fetch_options) a.name = name tmp.append(a) oldname = curname res.append(tmp) return res @staticmethod def exists(env, nick): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("""SELECT COUNT(*) FROM attendee WHERE nick=%s;""", (nick,)) row = cursor.fetchone() return row[0] > 0 def commit(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("""INSERT INTO attendee (e_id, ext_id, nick, email, finished, has_paid, time, actual_amount) VALUES(%s, %s, %s, %s, %s, %s, %s, %s)""", ( self.e_id, self.ext_id, self.nick, self.email, self.finished, self.has_paid, to_timestamp(self.time), self.actual_amount)) db.commit() self.a_id = db.get_last_id(cursor, 'attendee') @staticmethod def delete(env, a_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("""DELETE FROM attendee WHERE a_id =%s;""", (a_id,)) db.commit() def update(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("""UPDATE attendee SET nick=%s, email=%s, finished=%s, has_paid=%s, actual_amount=%s WHERE a_id=%s;""", ( self.nick, self.email, self.finished, self.has_paid, self.actual_amount, self.a_id)) db.commit() def calculate_fee(self): cache = {} res = 0.0 for i in self.options: opt = AvailableOption.fetch_one(self.env, i.ao_id) res += opt.price * i.count return "%.2f" % res class EventAccount(object): def __init__(self, env, ea_id, e_id, account_owner, account_no, bank_name, bank_no, first_reason, second_reason): self.env = env self.ea_id = ea_id self.e_id = e_id self.account_owner = account_owner self.account_no = account_no self.bank_name = bank_name self.bank_no = bank_no self.first_reason = first_reason self.second_reason = second_reason @staticmethod def fetch_by_event(env, e_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("""SELECT * FROM event_account WHERE e_id=%s""", (e_id,)) row = cursor.fetchone() if not row: return None return EventAccount(env, *row) @staticmethod def copy_by_event(env, old_id, new_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT account_owner, account_no, bank_name, bank_no, first_reason, second_reason FROM event_account where e_id=%s;", (old_id,)) row = cursor.fetchone() account_owner, account_no, bank_name, bank_no, first_reason, second_reason = row cursor.execute("INSERT INTO event_account " \ "(e_id, account_owner, account_no, bank_name, bank_no, first_reason, second_reason) " \ "VALUES(%s,%s,%s,%s,%s,%s,%s);", ( new_id, account_owner, account_no, bank_name, bank_no, first_reason, second_reason)) def commit(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO event_account " \ "(e_id, account_owner, account_no, bank_name, bank_no, first_reason, second_reason) " \ "VALUES(%s, %s, %s, %s, %s, %s, %s)", ( self.e_id, self.account_owner, self.account_no, self.bank_name, self.bank_no, self.first_reason, self.second_reason)) db.commit() self.a_id = db.get_last_id(cursor, 'event_account') def update(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("UPDATE event_account SET " \ "e_id=%s, " \ "account_owner=%s, " \ "account_no=%s, " \ "bank_name=%s, " \ "bank_no=%s, " \ "first_reason=%s, " \ "second_reason=%s;", ( self.e_id, self.account_owner, self.account_no, self.bank_name, self.bank_no, self.first_reason, self.second_reason)) db.commit() self.ea_id = db.get_last_id(cursor, 'event_account') def __zero__(self): return self.ea_id != 0 class Event(object): def __init__(self, env, e_id, name, description, time_begin, time_end, register_deadline=utc.localize(datetime.utcnow()), edit_deadline=utc.localize(datetime.utcnow()), payment_deadline=utc.localize(datetime.utcnow()), fetch_options=False, only_active=False, attendee_id=None): self.env = env self.e_id = e_id self.name = name self.description = description self.time_begin = time_begin self.time_end = time_end self.register_deadline = register_deadline self.edit_deadline = edit_deadline self.payment_deadline = payment_deadline self.options = [] if fetch_options: relations = Option2Event.fetch_by_event(self.env, self.e_id) for relation in relations: option = AvailableOption.fetch_one(self.env, relation.ao_id, attendee_id=attendee_id) if option: if only_active and not option.active: continue self.options.append(option) @staticmethod def fetch_one(env, e_id=0, name=None, fetch_options=False, only_active=False, attendee_id=None): db = env.get_db_cnx() cursor = db.cursor() if not name: cursor.execute("SELECT e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline " \ "FROM booking_event " \ "WHERE e_id=%s", (e_id,)) else: cursor.execute("SELECT e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline " "FROM booking_event " \ "WHERE name=%s", (name,)) row = cursor.fetchone() if not row: return None e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline = row return Event(env, e_id, name, description, utc.localize(datetime.utcfromtimestamp(time_begin)), utc.localize(datetime.utcfromtimestamp(time_end)), utc.localize(datetime.utcfromtimestamp(register_deadline)), utc.localize(datetime.utcfromtimestamp(edit_deadline)), utc.localize(datetime.utcfromtimestamp(payment_deadline)), fetch_options=fetch_options, only_active=only_active, attendee_id=attendee_id) @staticmethod def fetch_all(env, fetch_options=False, only_active=False, attendee_id=None): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("""SELECT e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline FROM booking_event;""") rows = cursor.fetchall() if not rows: return [] res = [] for row in rows: e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline = row res.append(Event(env, e_id, name, description, utc.localize(datetime.utcfromtimestamp(time_begin)), utc.localize(datetime.utcfromtimestamp(time_end)), utc.localize(datetime.utcfromtimestamp(register_deadline)), utc.localize(datetime.utcfromtimestamp(edit_deadline)), utc.localize(datetime.utcfromtimestamp(payment_deadline)), fetch_options=fetch_options, only_active=only_active, attendee_id=attendee_id)) return res @staticmethod def copy(env, e_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline " \ "FROM booking_event " \ "WHERE e_id=%s", (e_id,)) row = cursor.fetchone() if not row: return None e_id, name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline = row event = Event(env, e_id, "Kopie von " + name, description, utc.localize(datetime.utcfromtimestamp(time_begin)), utc.localize(datetime.utcfromtimestamp(time_end)), utc.localize(datetime.utcfromtimestamp(register_deadline)), utc.localize(datetime.utcfromtimestamp(edit_deadline)), utc.localize(datetime.utcfromtimestamp(payment_deadline))) event.commit() event_account = EventAccount.copy_by_event(env, e_id, event.e_id) relations = Option2Event.fetch_by_event(env, e_id) for relation in relations: print "relation", relation.ao_id, event.e_id Option2Event.copy_by_event(env, relation.ao_id, event.e_id) def add_options(self, attendee_id): self.options = list() relations = Option2Event.fetch_by_event(self.env, self.e_id) for relation in relations: option = AvailableOption.fetch_one(self.env, relation.ao_id, attendee_id=attendee_id) if option: self.options.append(option) @staticmethod def exists(env, name): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT COUNT(e_id) FROM booking_event WHERE name=%s;", (name,)) row = cursor.fetchone() return row[0] > 0 def commit(self): db = self.env.get_db_cnx() cursor = db.cursor() a,b,c,d,e = to_timestamp(self.time_begin), to_timestamp(self.time_end), to_timestamp(self.register_deadline), to_timestamp(self.edit_deadline), to_timestamp(self.payment_deadline) cursor.execute("INSERT INTO booking_event " \ "(name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline) " \ "VALUES(%s, %s, %s, %s, %s, %s, %s)", ( self.name, self.description, a,b,c,d,e, )) db.commit() self.e_id = db.get_last_id(cursor, 'booking_event') @staticmethod def delete(env, e_id): db = env.get_db_cnx() cursor = db.cursor() try: cursor.execute("DELETE FROM booking_event WHERE e_id=%s;", (e_id,)) db.commit() except Exception, e: env.log.debug("Event delete failed\n%s" + str(e)) pass def update(self): db = self.env.get_db_cnx() cursor = db.cursor() a,b,c,d,e = to_timestamp(self.time_begin), to_timestamp(self.time_end), to_timestamp(self.register_deadline), to_timestamp(self.edit_deadline), to_timestamp(self.payment_deadline) cursor.execute("""UPDATE booking_event SET name=%s, description=%s, time_begin=%s, time_end=%s, register_deadline=%s, edit_deadline=%s, payment_deadline=%s WHERE e_id=%s;""", ( self.name, self.description, a,b,c,d,e, self.e_id)) db.commit() def __zero__(self): return self.e_id != 0 class BookingReminder(object): def __init__(self, env, reminder_id, e_id, text, notify_on, was_send_on=None): self.env = env self.reminder_id = reminder_id self.e_id = e_id self.text = text self.notify_on = notify_on self.was_send_on = was_send_on @staticmethod def fetch_one(env, reminder_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT * FROM booking_reminder WHERE reminder_id=%s;", (reminder_id,)) row = cursor.fetchone() if not row: return None return BookingReminder(env, *row) @staticmethod def fetch_all(env): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT * FROM booking_reminder;") rows = cursor.fetchall() if not rows: return [] return [BookingReminder(env, *row) for row in rows] @staticmethod def fetch_by_event(env, e_id): db = env.get_db_cnx() cursor = db.cursor() if e_id: cursor.execute("""SELECT * FROM booking_reminder WHERE e_id=%s""", (e_id,)) rows = cursor.fetchall() if not rows: return [] return [BookingReminder(env, *row) for row in rows] def commit(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO booking_reminder " \ "(reminder_id, e_id, text, notify_on, was_send_on) " \ "VALUES(%s, %s,%s, %s,%s)", ( self.reminder_id, self.e_id, self.text, self.notify_on, self.was_send_on)) db.commit() self.reminder_id = db.get_last_id(cursor, 'booking_reminder') @staticmethod def update(env, ao_id, e_id): db = env.get_db_cnx() cursor = db.cursor() try: cursor.execute("UPDATE booking_reminder SET " \ "text=%s " \ "notify_on=%s " \ "was_send_on=%s " \ "WHERE reminder_id=%s and e_id=%s;", (self.text, self.notify_on, self.was_send_on, self.reminder_id, self.e_id)) db.commit() except Exception: pass @staticmethod def delete(env, ao_id, e_id): db = env.get_db_cnx() cursor = db.cursor() try: cursor.execute("DELETE FROM booking_reminder WHERE ao_id=%s AND e_id=%s;", (ao_id, e_id,)) db.commit() except Exception: pass class Option2Event(object): def __init__(self, env, ao_id, e_id): self.env = env self.ao_id = ao_id self.e_id = e_id @staticmethod def fetch_one(env, ao_id, e_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT ao_id, e_id FROM option_to_event WHERE ao_id=%s AND e_id=%s;", (ao_id, e_id)) row = cursor.fetchone() if not row: return None return Option2Event(env, int(ao_id), int(e_id)) @staticmethod def fetch_by_option(env, ao_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT ao_id, e_id " \ "FROM option_to_event " \ "WHERE ao_id=%s", (ao_id,)) rows = cursor.fetchall() if not rows: return [] res = [] for row in rows: res.append(Option2Event(env, *row)) return res @staticmethod def fetch_by_event(env, e_id): db = env.get_db_cnx() cursor = db.cursor() if e_id: cursor.execute("""SELECT ao_id, e_id FROM option_to_event WHERE e_id=%s""", (e_id,)) rows = cursor.fetchall() if not rows: return [] res = [] for row in rows: res.append(Option2Event(env, *row)) return res @staticmethod def fetch_all(env, fetch=False): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT ao_id, e_id FROM option_to_event") rows = cursor.fetchall() if not rows: return [] res = [] for ao_id, e_id in rows: res.append(Option2Event(env, int(ao_id), int(e_id), fetch=fetch)) return res @staticmethod def copy_by_event(env, ao_id, e_id): db = env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO option_to_event (ao_id, e_id) VALUES(%s, %s);", (ao_id, e_id)) db.commit() def commit(self): db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO option_to_event " \ "(ao_id, e_id) " \ "VALUES(%s, %s)", ( self.ao_id, self.e_id)) db.commit() self.a_id = db.get_last_id(cursor, 'booking_event') @staticmethod def delete(env, ao_id, e_id): db = env.get_db_cnx() cursor = db.cursor() try: cursor.execute("DELETE FROM option_to_event WHERE ao_id=%s AND e_id=%s;", (ao_id, e_id,)) db.commit() except Exception: pass class BookingModelsupplier(Component): implements(IEnvironmentSetupParticipant) SCHEMA = [ Table('booking_event', key='e_id')[ Column('e_id', auto_increment=True), Column('name'), Column('description'), Column('time_begin', type='int'), Column('time_end', type='int'), Column('register_deadline', type='int'), Column('edit_deadline', type='int'), Column('payment_deadline', type='int'), Index(['name',])], Table('event_account', key='ea_id')[ Column('ea_id', auto_increment=True), Column('e_id', type='int'), Column('account_owner'), Column('account_no', type='int'), Column('bank_name'), Column('bank_no', type='int'), Column('first_reason'), Column('second_reason')], Table('attendee', key='a_id')[ Column('a_id', auto_increment=True), Column('e_id', type='int'), Column('ext_id'), Column('nick'), Column('email'), Column('finished', type='int'), Column('has_paid', type='int'), Column('time', type='int'), Column('actual_amount', type='float'), Index(['nick',]), Index(['e_id',]), Index(['ext_id',])], # custom relation specification for event specific attendee attributes Table('attendee_attributes', key='am_id')[ Column('am_id', auto_increment=True), Column('e_id'), Column('name'), Column('type')], # the actual values of attributes for event 'e_id' and attendee 'a_id' Table('attendee_attribute_values', key='aam_id')[ Column('aam_id', auto_increment=True), Column('eam_id', type='int'), Column('a_id', type='int'), Column('value')], Table('supplier', key='supplier_id')[ Column('supplier_id', auto_increment=True), Column('name'), Column('address'), Column('phone'), Column('email'), Column('fax'), Index(['name',])], Table('booking_available_option', key='ao_id')[ Column('ao_id', auto_increment=True), Column('name'), Column('description'), Column('price', type='real'), Column('active', type='int'), Column('min_count', type='int'), Column('max_count', type='int'), Column('supplier_id', type='int'), Column('ext_id', type='int'), Column('stock_count', type='int')], Table('booking_available_option_variations', key='variation_id')[ Column('variation_id', auto_increment=True), Column('option_id'), Column('name')], Table('booking_available_option_variation_items', key='ovi_id')[ Column('ovi_id', auto_increment=True), Column('variation_id'), Column('name'), Column('value'), Column('description')], Table('option_to_event', key=['ao_id', 'e_id'])[ Column('ao_id', type='int'), Column('e_id', type='int')], Table('booking_reminder', key='reminder_id')[ Column('reminder_id', type='int'), Column('e_id', type='int'), Column('text'), Column('notify_on', type='int'), Column('was_send_on', type='int')], Table('booking_option', key=['a_id', 'ao_id'])[ Column('bo_id', auto_increment=True), Column('a_id', type='int'), Column('ao_id', type='int'), Column('count', type='int')], Table('booking_option_variations')[ Column('attendee_id', type='int'), Column('variation_id', type='int'), Column('ovi_id', type='int')]] OptionVariationTrigger = "CREATE TRIGGER attendee_variation_trigger " \ "BEFORE DELETE ON attendee " \ "FOR EACH ROW BEGIN " \ "DELETE from booking_option_variations WHERE attendee_id = OLD.a_id; " \ "END;" EventAttendeeTrigger = "CREATE TRIGGER event_attendee_trigger " \ "BEFORE DELETE ON booking_event " \ "FOR EACH ROW BEGIN " \ "DELETE from attendee WHERE e_id = OLD.e_id; " \ "END;" EventAccountTrigger = "CREATE TRIGGER event_account_trigger " \ "BEFORE DELETE ON booking_event " \ "FOR EACH ROW BEGIN " \ "DELETE from event_account WHERE e_id = OLD.e_id; " \ "END;" EventOption2EventTrigger = "CREATE TRIGGER event_option_to_event_trigger " \ "BEFORE DELETE ON booking_event " \ "FOR EACH ROW BEGIN " \ "DELETE from option_to_event WHERE e_id = OLD.e_id; " \ "END;" EventBookingReminderTrigger = "CREATE TRIGGER event_booking_reminder_trigger " \ "BEFORE DELETE ON booking_event " \ "FOR EACH ROW BEGIN " \ "DELETE from booking_reminder WHERE e_id = OLD.e_id; " \ "END;" AttendeeBookingOptionTrigger = "CREATE TRIGGER attendee_booking_option_trigger " \ "BEFORE DELETE ON attendee " \ "FOR EACH ROW BEGIN " \ "DELETE from booking_option WHERE a_id = OLD.a_id; " \ "END;" AOptionOption2EventTrigger = "CREATE TRIGGER booking_available_option_option_to_event_trigger " \ "BEFORE DELETE ON booking_available_option " \ "FOR EACH ROW BEGIN " \ "DELETE from option_to_event WHERE ao_id = OLD.ao_id; " \ "END;" AOptionBookingTrigger = "CREATE TRIGGER booking_available_option_booking_option_trigger " \ "BEFORE DELETE ON booking_available_option " \ "FOR EACH ROW BEGIN " \ "DELETE from booking_option WHERE ao_id = OLD.ao_id; " \ "END;" def environment_created(self): self._create_models(self.env.get_db_cnx()) def environment_needs_upgrade(self, db): """First version - nothing to migrate, but possibly to create. """ cursor = db.cursor() try: cursor.execute("select count(*) from attendee") cursor.fetchone() cursor.execute("select count(*) from event_account") cursor.fetchone() cursor.execute("select count(*) from booking_available_option") cursor.fetchone() cursor.execute("select count(*) from booking_option") cursor.fetchone() cursor.execute("select count(*) from booking_event") cursor.fetchone() cursor.execute("select count(*) from supplier") cursor.fetchone() cursor.execute("select count(*) from option_to_event") cursor.fetchone() return False except: db.rollback() return True def upgrade_environment(self, db): """ nothing to do here for now """ self._create_models(db) def _create_models(self, db): """Called when a new Trac environment is created.""" EVENT_DATA = ( (u'Matebestellung 2010-001', u'', to_timestamp(datetime(2010, 4, 24, 18, tzinfo=utc)), to_timestamp(datetime(2010, 4, 30, 16, tzinfo=utc)), to_timestamp(datetime(2010, 4, 29, 16, tzinfo=utc)), to_timestamp(datetime(2010, 4, 30, 16, tzinfo=utc)), to_timestamp(datetime(2010, 4, 30, 16, tzinfo=utc))),) supplier_DATA = ( ('Getränke Rabe', "Hamm", "", "", "")) OPTION_DATA = ( (u'Club Mate - 20 x 0.5L', u"""10 Liter frische leckere Club-Mate 13.5 € Netto preis zzgl. 4.5 € Pfand Falls Du Kisten zurückgeben willst, einfach die Anzahl der Rückgabekisten angeben""", 18.0, 1, 0, 0, 1, 0, 50), (u'Matekiste Rückgabe', u'Nur komplette/vollständige Matekisten angeben', -4.5, 1, 0, 0, 1, 0, 1000), ) AO_DATA = ( (1, 1), (2, 1), ) VARIATION_DATA = () ACCOUNT_DATA = ( (1, u'Chaostreff Dortmund', 4009368600, u'GLS-Bank', 43060967, u'Mate 2010/1', ''), ) VARIATION_ITEM_DATA = () try: try: from trac.db import DatabaseManager db_backend, _ = DatabaseManager(self.env)._get_connector() except ImportError: db_backend = self.env.get_db_cnx() cursor = db.cursor() for table in self.SCHEMA: for stmt in db_backend.to_sql(table): self.env.log.debug(stmt) cursor.execute(stmt) db.commit() cursor.executemany("""INSERT INTO 'booking_event' (name, description, time_begin, time_end, register_deadline, edit_deadline, payment_deadline) VALUES(%s, %s, %s, %s, %s, %s, %s)""", EVENT_DATA) cursor.executemany("""INSERT INTO 'option_to_event' (ao_id, e_id) VALUES(%s, %s)""", AO_DATA) cursor.executemany("""INSERT INTO 'event_account' (e_id, account_owner, account_no, bank_name, bank_no, first_reason, second_reason) VALUES(%s, %s, %s, %s, %s, %s, %s)""", ACCOUNT_DATA) #cursor.executemany("""INSERT INTO 'booking_available_option_variations' #(variation_id, option_id, name) #VALUES(%s, %s, %s)""", VARIATION_DATA) #cursor.executemany("""INSERT INTO 'booking_available_option_variation_items' #(ovi_id, variation_id, name, value, description) #VALUES(%s, %s, %s, %s, %s)""", VARIATION_ITEM_DATA) print OPTION_DATA cursor.executemany("""INSERT INTO 'booking_available_option' (name, description, price, active, min_count, max_count, supplier_id, ext_id, stock_count) VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s)""", OPTION_DATA) cursor.execute(self.EventAttendeeTrigger) cursor.execute(self.EventOption2EventTrigger) cursor.execute(self.EventBookingReminderTrigger) cursor.execute(self.AttendeeBookingOptionTrigger) cursor.execute(self.AOptionBookingTrigger) cursor.execute(self.AOptionOption2EventTrigger) cursor.execute(self.OptionVariationTrigger) db.commit() except: db.rollback() raise