ctdo-trac/TracBooking/tracbooking/model.py

1304 lines
49 KiB
Python

# -*- 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