2021-05-25 19:01:20 +00:00
|
|
|
""" Database management """
|
|
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
from urllib.parse import urlparse, parse_qsl
|
2021-05-26 11:55:56 +00:00
|
|
|
from pony.orm import Database, Required, Optional, Set, PrimaryKey, LongStr, Json
|
|
|
|
from pony.orm import DatabaseError
|
2021-05-25 19:01:20 +00:00
|
|
|
|
|
|
|
db = Database()
|
2021-05-25 19:55:25 +00:00
|
|
|
|
2021-05-26 11:55:56 +00:00
|
|
|
|
2021-05-25 19:01:20 +00:00
|
|
|
class Service(db.Entity):
|
|
|
|
id = PrimaryKey(int, auto=True)
|
|
|
|
name = Required(str, unique=True)
|
|
|
|
localisation = Optional(str)
|
|
|
|
max_appointement = Required(int)
|
2021-05-26 11:55:56 +00:00
|
|
|
plannings = Set("Planning")
|
|
|
|
service_category = Required("Service_category")
|
|
|
|
appointments = Set("Appointment")
|
2021-05-25 19:01:20 +00:00
|
|
|
description = Optional(str)
|
|
|
|
|
|
|
|
|
|
|
|
class Planning(db.Entity):
|
|
|
|
id = PrimaryKey(int, auto=True)
|
|
|
|
name = Required(str, unique=True)
|
2021-05-26 11:55:56 +00:00
|
|
|
working_plan = Required(Json)
|
2021-05-25 19:01:20 +00:00
|
|
|
services = Set(Service)
|
2021-05-26 11:55:56 +00:00
|
|
|
appointments = Set("Appointment")
|
|
|
|
planners = Set("Planner")
|
2021-05-25 19:01:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Setting(db.Entity):
|
|
|
|
id = PrimaryKey(int, auto=True)
|
|
|
|
name = Required(str, unique=True)
|
|
|
|
value = Optional(str)
|
|
|
|
|
|
|
|
|
|
|
|
class Appointment(db.Entity):
|
|
|
|
id = PrimaryKey(int, auto=True)
|
|
|
|
book_datetime = Required(datetime)
|
|
|
|
start_datetime = Required(datetime)
|
2021-06-01 12:15:29 +00:00
|
|
|
end_datetime = Required(datetime)
|
2021-05-25 19:01:20 +00:00
|
|
|
localisation = Optional(str, nullable=True)
|
|
|
|
is_unavaillable = Required(bool)
|
|
|
|
service = Required(Service)
|
|
|
|
planning = Required(Planning)
|
2021-05-26 11:55:56 +00:00
|
|
|
ticket = Optional("Ticket")
|
|
|
|
customer = Optional("Customer")
|
2021-05-25 19:01:20 +00:00
|
|
|
notes = Optional(LongStr)
|
|
|
|
|
|
|
|
|
2021-05-25 19:55:25 +00:00
|
|
|
class Customer(db.Entity):
|
2021-05-25 19:01:20 +00:00
|
|
|
id = PrimaryKey(int, auto=True)
|
|
|
|
first_name = Required(str)
|
|
|
|
last_name = Required(str)
|
|
|
|
email = Required(str, unique=True)
|
|
|
|
localisation = Optional(str)
|
|
|
|
mobile_number = Optional(str)
|
|
|
|
phone_number = Optional(str)
|
2021-05-26 11:55:56 +00:00
|
|
|
tickets = Set("Ticket")
|
2021-05-25 19:01:20 +00:00
|
|
|
appointments = Set(Appointment)
|
|
|
|
notes = Optional(str)
|
|
|
|
|
|
|
|
|
|
|
|
class Ticket(db.Entity):
|
|
|
|
id = PrimaryKey(int, auto=True)
|
|
|
|
ref = Optional(str, unique=True)
|
2021-05-26 11:55:56 +00:00
|
|
|
service_category = Required("Service_category")
|
2021-05-25 19:55:25 +00:00
|
|
|
customer = Required(Customer)
|
2021-05-25 19:01:20 +00:00
|
|
|
appointment = Required(Appointment)
|
|
|
|
notes = Optional(str)
|
|
|
|
|
|
|
|
|
|
|
|
class Service_category(db.Entity):
|
|
|
|
id = PrimaryKey(int, auto=True)
|
|
|
|
name = Required(str)
|
|
|
|
tickets = Set(Ticket)
|
|
|
|
duration = Required(int)
|
|
|
|
free_order = Required(bool)
|
|
|
|
services = Set(Service)
|
|
|
|
description = Optional(str)
|
|
|
|
|
|
|
|
|
2021-05-25 19:55:25 +00:00
|
|
|
class Planner(Customer):
|
|
|
|
plannings = Set(Planning)
|
|
|
|
password = Required(str)
|
|
|
|
is_admin = Optional(bool)
|
2021-05-25 19:01:20 +00:00
|
|
|
|
2021-05-26 11:55:56 +00:00
|
|
|
|
2021-05-25 19:01:20 +00:00
|
|
|
def parse_uri(database_uri):
|
|
|
|
if not isinstance(database_uri, str):
|
|
|
|
raise TypeError("Expecting a string")
|
|
|
|
|
|
|
|
uri = urlparse(database_uri)
|
|
|
|
args = dict(parse_qsl(uri.query))
|
|
|
|
if uri.port is not None:
|
|
|
|
args["port"] = uri.port
|
|
|
|
|
|
|
|
if uri.scheme == "sqlite":
|
|
|
|
path = uri.path
|
|
|
|
if not path:
|
|
|
|
path = ":memory:"
|
|
|
|
elif path[0] == "/":
|
|
|
|
path = path[1:]
|
|
|
|
|
|
|
|
return dict(provider="sqlite", filename=path, create_db=True, **args)
|
|
|
|
elif uri.scheme in ("postgres", "postgresql"):
|
|
|
|
return dict(
|
|
|
|
provider="postgres",
|
|
|
|
user=uri.username,
|
|
|
|
password=uri.password,
|
|
|
|
host=uri.hostname,
|
|
|
|
dbname=uri.path[1:],
|
|
|
|
**args
|
|
|
|
)
|
|
|
|
elif uri.scheme == "mysql":
|
|
|
|
args.setdefault("charset", "utf8mb4")
|
|
|
|
args.setdefault("binary_prefix", True)
|
|
|
|
return dict(
|
|
|
|
provider="mysql",
|
|
|
|
user=uri.username,
|
|
|
|
passwd=uri.password,
|
|
|
|
host=uri.hostname,
|
|
|
|
db=uri.path[1:],
|
|
|
|
**args
|
|
|
|
)
|
|
|
|
return dict()
|
|
|
|
|
2021-05-26 11:55:56 +00:00
|
|
|
|
2021-05-25 19:01:20 +00:00
|
|
|
def init_database(database_uri):
|
|
|
|
settings = parse_uri(database_uri)
|
2021-06-01 12:15:29 +00:00
|
|
|
|
2021-05-25 19:01:20 +00:00
|
|
|
db.bind(**settings)
|
2021-05-26 11:55:56 +00:00
|
|
|
db.generate_mapping(check_tables=False)
|
|
|
|
try:
|
|
|
|
db.check_tables()
|
|
|
|
except DatabaseError:
|
|
|
|
db.create_tables()
|
|
|
|
|
2021-05-25 19:01:20 +00:00
|
|
|
|
|
|
|
def release_database():
|
|
|
|
db.disconnect()
|
2021-06-01 12:15:29 +00:00
|
|
|
db.provider = None
|
|
|
|
db.schema = None
|