From b7eef3e2c7cf1c40f4d7e8e800bab240ed0ec9cb Mon Sep 17 00:00:00 2001
From: Nathan Baker <nathan2.baker@live.uwe.ac.uk>
Date: Mon, 24 Feb 2025 12:50:08 +0000
Subject: [PATCH] many eddits, removed dupe loginAttempt started on listing
 display funcs

remaining bug: calling staffUser.__str__ causes recursion error...
---
 GUI.py                                      |   5 +-
 __pycache__/main.cpython-312.pyc            | Bin 6324 -> 6627 bytes
 main.py                                     | 114 +++++++++++---------
 src/__pycache__/__init__.cpython-312.pyc    | Bin 512 -> 549 bytes
 src/__pycache__/adminUser.cpython-312.pyc   | Bin 823 -> 1002 bytes
 src/__pycache__/bookingObj.cpython-312.pyc  | Bin 818 -> 855 bytes
 src/__pycache__/cinemaObj.cpython-312.pyc   | Bin 2719 -> 2756 bytes
 src/__pycache__/constants.cpython-312.pyc   | Bin 601 -> 638 bytes
 src/__pycache__/dbfunc.cpython-312.pyc      | Bin 8557 -> 8696 bytes
 src/__pycache__/managerUser.cpython-312.pyc | Bin 994 -> 1173 bytes
 src/__pycache__/reportObj.cpython-312.pyc   | Bin 701 -> 738 bytes
 src/__pycache__/screenObj.cpython-312.pyc   | Bin 3543 -> 3580 bytes
 src/__pycache__/staffUser.cpython-312.pyc   | Bin 5463 -> 4867 bytes
 src/adminUser.py                            |   6 +-
 src/dbfunc.py                               |  28 +++--
 src/managerUser.py                          |   6 +-
 src/staffUser.py                            |  35 +++---
 17 files changed, 104 insertions(+), 90 deletions(-)

diff --git a/GUI.py b/GUI.py
index 24a0776..9797740 100644
--- a/GUI.py
+++ b/GUI.py
@@ -74,7 +74,7 @@ def open_dashboard(user):
     dashboard.geometry("500x400")
 
     # Display Welcome Message Using `user.username`
-    welcome_label = Label(dashboard, text=f"Welcome, {user['username']}!", font=("Arial", 16))
+    welcome_label = Label(dashboard, text=f"Welcome, {user.userName}!", font=("Arial", 16))
     welcome_label.pack(pady=20)
 
     if isinstance(user, StaffUser):
@@ -106,9 +106,10 @@ def gui_login():
 
     # Call loginAttempt() from main.py
     user = loginAttempt(username, password)  
+    #logging.debug(user)
 
     if user:
-        messagebox.showinfo("Login", f"Login successful! Welcome {user['username']}.")
+        messagebox.showinfo("Login", f"Login successful! Welcome {user.userName}.")
         window.destroy()  # Close login window
         open_dashboard(user)  # Open appropriate dashboard based on user role
     else:
diff --git a/__pycache__/main.cpython-312.pyc b/__pycache__/main.cpython-312.pyc
index 219c7b89736cb328d9b6f143a51c28993ccb875c..70f66fef1605820f3ec72c7edf20cf23200504d0 100644
GIT binary patch
delta 2900
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

delta 2428
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
PC&;uf44jMt;Gh5imr7Z?

diff --git a/main.py b/main.py
index b9d3f43..5ba6806 100644
--- a/main.py
+++ b/main.py
@@ -1,8 +1,10 @@
 import logging
-logging.basicConfig(level=0, format="{asctime} - {levelname} - {message}", style="{", datefmt="%Y-%m-%d %H:%M")
+logging.basicConfig(level=logging.DEBUG, format="{asctime} - {levelname} - {message}", style="{", datefmt="%Y-%m-%d %H:%M")
 from src import *
 from src.dbfunc import get_connection
 import json
+import pandas as pd
+import datetime as dt
 from src.staffUser import StaffUser
 from src.adminUser import AdminUser
 from src.managerUser import ManagerUser
@@ -21,37 +23,37 @@ from src.managerUser import ManagerUser
 
 
 def loginAttempt(username: str, password: str):
-    """Check if the user exists in the database and return the appropriate user object"""
+    """Check if the user exists in the database and return the appropriate user object
     
-    conn = get_connection()
-    if conn:
-        cursor = conn.cursor(dictionary=True)
-        
-        # Fetch user details from the database
-        cursor.execute("SELECT username, password_hash, role FROM users WHERE username = %s AND password_hash = %s", 
-                       (username, password))
-        user_data = cursor.fetchone()
-        
-        cursor.close()
-        conn.close()
-        
-        if user_data:
-            logging.info(f"User {user_data['username']} logged in successfully.")
-
-            # Return an instance of the correct user class
-            if user_data['role'] == 'Staff':
-                return StaffUser(username=user_data['username'])
-            elif user_data['role'] == 'Admin':
-                return AdminUser(username=user_data['username'])
-            elif user_data['role'] == 'Manager':
-                return ManagerUser(username=user_data['username'])
-            else:
-                logging.error("Unknown role in database.")
-                return None
-        else:
-            logging.warning("Invalid username or password.")
+    Arguments:
+        username (str) -- username for login.
+        password (str) -- password for login, plaintext?
+    Returns:
+        User object of type: StaffUser or AdminUser or ManagerUser
+        or None if failed login.
+    """
+    # dbug shortcut
+    if username=="debug" and password=="debug":
+        return ManagerUser(15, "manager", "password", [1], "Manager")
+    # using dbfuncs to do this:   cursor.execute("SELECT username, password_hash, role FROM users WHERE username = %s AND password_hash = %s", (username, password)) 
+    user_data = select_from_table_where("tblUsers", f"username = {username} AND password_hash = {password}", "username", "password_hash", "role")
     
-    return None  # Return None if no user found
+    if user_data:
+        logging.info(f"User {user_data['username']} logged in successfully.")
+
+        # Return an instance of the correct user class
+        if user_data['role'] == 'Staff':
+            return StaffUser(username=user_data['username'])
+        elif user_data['role'] == 'Admin':
+            return AdminUser(username=user_data['username'])
+        elif user_data['role'] == 'Manager':
+            return ManagerUser(username=user_data['username'])
+        else:
+            logging.error("Unknown role in database.")
+            return None
+    else:
+        logging.warning("Invalid username or password.")
+        return None  # Return None if no user found
 
 def staffUser_options_cli(user:StaffUser) -> None:
     while True:
@@ -82,6 +84,7 @@ def staffUser_options_cli(user:StaffUser) -> None:
     exit()
 
 def managerUser_options_cli(user:ManagerUser) -> None:
+    logging.debug("loaded into managerUser_options_cli.")
     while True:
         selection = input("Menu options:\n"
                           "  1. View Listings \n"
@@ -121,6 +124,17 @@ def adminUser_options_cli(user:AdminUser) -> None:
     user.logout()
     exit()
         
+def fetch_movies() -> dict:
+    raise NotImplementedError()
+    select_from_table("tblMovies")
+    
+def get_listings():
+    currentTime = dt.datetime.now()
+    listings = select_from_table_where("tblShowings", f"[{currentTime}] + show_time > sysdatetime()") # returns all data that matches today
+
+def display_listings_cli():
+    strListings = pd.DataFrame(get_listings())
+    return 
 
 def load_cinema(cinemaID) -> Cinema:
     raise NotImplementedError()
@@ -149,36 +163,32 @@ def main_cli() -> None:
     while True:
         username = encrypt(sanitize(input("Username: ")))
         password = encrypt(sanitize(input("Password: ")))
-        #user = loginAttempt(username=username, password=password)
-        user = ManagerUser(impBool=1) # dev remove later
-        if user is None:
+        user = loginAttempt(username=username, password=password)
+        
+        if username=="debug" and password=="debug":
+            logging.warning("Entered as debug user")
+            user = ManagerUser(15, "manager", "password", [1], "Manager")
+            #logging.debug(f"user object loaded as: {user}")
+            managerUser_options_cli(user)
+            break
+        elif user is None:
             print("Login attempt failed please try again.")
         else:
+            logging.debug(f"failed login, returned value: {user}")
             break
-    logging.info("successful login, loading menu...")
+    logging.info(f"successfuly loged in as {user.userName}, loading menu...")
     
     # based on the different user permision levels, load different menus.
-    match user.permissionLevel:
-        case 1:
-            managerUser_options_cli(user)
-        case 2:
-            adminUser_options_cli(user)
-        case _:
-            staffUser_options_cli(user)
+    if user.role=="Manager":
+        managerUser_options_cli(user)
+    elif user.role=="Admin":
+        adminUser_options_cli(user)
+    elif user.role=="Staff":
+        staffUser_options_cli(user)
 
 # following code will only execute if run directly from this file.
 if __name__ == "__main__":
     logging.debug("STARTING main_cli")
     main_cli()
     logging.debug("main_cli finished, program exiting. bye bye!")
-    
-def loginAttempt(username: str, password: str):
-    """Check if the user exists in the database"""
-    conn = get_connection()
-    if conn:
-        cursor = conn.cursor(dictionary=True)
-        cursor.execute("SELECT * FROM Users WHERE username = %s AND password_hash = %s", (username, password))
-        user = cursor.fetchone()
-        conn.close()
-        return user  # Returns user details if found
-    return None
\ No newline at end of file
+   
diff --git a/src/__pycache__/__init__.cpython-312.pyc b/src/__pycache__/__init__.cpython-312.pyc
index aaa784897475dad772c7a61107c760b558fdf570..22aab0c5e549be1de01acbc9f1c13180be82681e 100644
GIT binary patch
delta 85
zcmZo*S<1qFnwOW0fq{WR)pO5A?kYx`SZAx4(Bjmh;+Q;3-K50q)S?*wyi}K>%(7Gk
oU4_taR|Th{%;J*#oEVqX;_Q<Af|$tE#3BWw7{_3j$#WP}073v8Q~&?~

delta 48
zcmZ3=(!j!fnwOW0fq{YH{Pe9GxvLn(Et0KbLW@(2iepMri&FDqTvCg(OY#dQA7o4c
E0ARKdJpcdz

diff --git a/src/__pycache__/adminUser.cpython-312.pyc b/src/__pycache__/adminUser.cpython-312.pyc
index e862f6391397e9c67c1dd92ae1fbf20e7b084608..8cd0a263f4650f94ec2f3445ba63e1247b555380 100644
GIT binary patch
delta 621
zcmdna_KKbNG%qg~0|NuYo3K6Uk0<i>xr2EO3=E$w7#JAZ8KyI&GDI<^Fhnt>Fh((_
zFr~7jFsHJnu%xo4u%@!5u%)u3adj}HF{ZG$@I<k9FjO!`aRf7Ha!foE5Oa$uGvyXb
zUSe+QE!Kj>;^OjK?8%vVskw>8w^)kub5fJpKsG}$I|Bm)Gss>m1_p+yjMEuPpb`uW
zooqD>y{rrjH4HV3HB2?kH7u)HC;KrP*B5~ttI2+gr8qSwtq5dV5y+S#4h9B>B2Ewi
zQgDkiK0Y}ovA8%sz8EB}00s@e;*zamLW@(2ievIDb(0daQ;TB!^HN=kGRsmGbQMCw
zT@{>)GK)*{b7EXli?d7e3t}Qu6N?m#VjP2AViHrz5+|QzlxO6f{E|^dOP+y&;YS0*
z9S+`3_KO@6Gel+-EihRjx`F))hs6yM(GHeg&d(tKXmU<gW74g^#hjT}a*MgRr05n)
zPG)gQ5ibJ+!!2H@JCjp$a^mAP8H@NC7#NBf85kHGiUdHuVTBQ(fGRcx+1bMIk%@(s
z;{z8HtJn<X4-8DKVhfzX)QVy-wZjEW9Vq?|lKTiEiWmhaFJRKn5dvAtT3Vc1WO$3U
zpeQr1WF<q9Ajl4oZNE5da`RJ4b5iY!K)wSxqu7vvf#Cx)BO~Ko28Ayy9E@TUIKMD(
mFp7Q9VqoFvsJg@~`H)An+q=Q_CJSeWYOBu&b_NzHu#o^}N1!qQ

delta 411
zcmaFGzMYNtG%qg~0|NuY`RQBJXHVqqGh_ns7#J8nD={!Iv@=X+NM(p(Oks#(N@0v*
z?qEn`Okrx_h+^qrs9=m@4Q9|}p7<!hD47we3q&z9Fff4dX9ETXhN+Cx8A?E+VBE=A
z!_dphz_6NOav!6y^DX{@)S}$X;^NHwJfGCE)ErHwTP($?Icc{z<KvTa5{rxD<BLHK
zQfT;PnQRpkTAW%`98;27l$sagl3JWyl3y^{nn{I`V{!tMjG`C=1H+F7hC3X*o$MDm
zB(88s-H=!4V7ba6^BH8hCfnp?OuD{B91IK$w|JrEC#UA*#K&tg7I8B$FcgD);ZVfG
zz`#(%3L`*1DHZ}5-NNvZiG`KpI~NnH;s*vMR>dOT$-&IpUVI<}SxbvkiwtkE78GUX
zm8@ha;sxmkne>apCO1E&G$+-rNP>ZZ0c1t7Ap--$2WCb_#=8s(UsyO86(?|hVc=j?
MoP2^=js>I>0IwrrJ^%m!

diff --git a/src/__pycache__/bookingObj.cpython-312.pyc b/src/__pycache__/bookingObj.cpython-312.pyc
index 4678c08d458aad37f39f436e7a08d250feb3dad2..a95cc5867d0668f4171d2ea00ba38fac6bad3dc5 100644
GIT binary patch
delta 86
zcmdnQcAbs;G%qg~0|Ntts^^}K+>VSk@y=E;p~b01#W8u7x=D%IsYNmVd8sZ%nPsU8
qx(cD;t_n^?nZ+gfIWaD&#n~nK1u>DSiA4%VF^<75o0A#OGXel{$s5=J

delta 49
zcmcc4wuz1VG%qg~0|NuY`RQ9Xayv4LTP0h?gche36~~mM7NzFJxTF?mm*f|0?qEF6
F2mpRl5WxTd

diff --git a/src/__pycache__/cinemaObj.cpython-312.pyc b/src/__pycache__/cinemaObj.cpython-312.pyc
index e889a025d413312cfd167d1a991a2a5909f13fd5..dfc88c86489f19e676778ae90beb1d855c1faffb 100644
GIT binary patch
delta 86
zcmbO)dPJ1_G%qg~0|Ntts^^}K+{>A4;+(BwLW@(2ievIDb(0daQ;TB!^HN=kGRsmG
qbQMCwT@{>)GK)*{b7EXli?d7e3t}Qu6N?m#VjP2AHlJj=#ts0B%p9r!

delta 49
zcmX>iI$xCgG%qg~0|NuY`RQ9XaxZ5Rw@kK*2`x@7Dvl{hElSOcaY-%CF3B(0{Eq1w
FI{=En5t9G_

diff --git a/src/__pycache__/constants.cpython-312.pyc b/src/__pycache__/constants.cpython-312.pyc
index d3bc49915e4b08b2493f7d0b87854b992d1d9ce7..3bb21f47a4f77a6782ebd8e3d633e0f1b851c44f 100644
GIT binary patch
delta 85
zcmcb~@{fi4G%qg~0|Ns?LHM4H+}(^eamiLOp~b01#W8u7x=D%IsYNmVd8sZ%nPsU8
px(cD;t_n^?nZ+gfIWaD&#n~nK1u>DSiA4%VF^<75lh-n?0RW<K9O?i7

delta 48
zcmeyza+8JoG%qg~0|Ns?*@mqfxw{#~EuF1mLW@(2iepMri&FDqTvCg(OY#dQUt(MX
E0C(RI`Tzg`

diff --git a/src/__pycache__/dbfunc.cpython-312.pyc b/src/__pycache__/dbfunc.cpython-312.pyc
index 55dfe2f82b5871a26d95ff2418ec5379258e663c..5ba53e9ca58e4129c6cef290ff49a41264c7c450 100644
GIT binary patch
delta 1382
zcmaFs^uw9&G%qg~0|NuYhxk3|>qRE=Nic4ksNQXm%9p~K%9qBH!qvhO#h=36!Vo2p
z!qdVKC78n7!Vo2t!q>tOC7i<F!Vo1=$*3u?@y2szo9JY#n9$<XqT-l5OWmZz?9`$d
z|GZR}qRg^X1zm;Ea90JVqRirw{G1q<)Z*-t{DPRs)WjkMqZr3vm(AB$6d9Sgm?j&@
zinB9uGSo0-F;8}67v5~dX2-;+Ik}J{kcTC)D80Byl7WGtNM-Ux4qI_u1_lOs1_p-W
zlMD<D4Gd4XB`<SJH@HmJ<&=<G88Sm<zUEBL1uk>+HxyrxwBBKMK=pw51p&{=37nH6
zdK~#3Z5R&P$U4h1ACi=GmS8?)#0X*=vp6d-9F|~pmSsLH%M4;GD7i2(7ilsuFx=uy
z&d*E9EXmBzOJ)Lv8WgiJFfgz)Ffe@fVg$K=av;}wfnWw@h7xelf)r)(Or9tyJeh-C
zm_vo3NU4^+L~!y&5t+%exP=rW8B#cF+3VOVIU#g8V>v?wb0kAKqb65kAtM9BWI+y*
z$vHf-^;`-H3JQ)z>BUxH7Km4pn3R*Mpix{>q-mv)l30?Mlvtdq01?eg%uUr%NKLm^
zP%25v0mqCITqE2kFwF>o;*z4wymW=kJcZyuABD91qTIw1kU90%3QFM~u0gH}rNya5
zAk!6W6;z8A9Q|Ar3KENp%kzs;;xiJ9Gr+<KtF)5yb4qjbimen<E0R+SN{ST{b8-|C
zK>?YUn4^$blwO*fng<fjOHoM9&nrtUDk)Yd$w<vr$jmFr2fL!MG_}a7QXwrrCnvug
z<ho#2A6MrPg~VcnejSC(G=;qUyi~A`;*!LY)ZDxhkYkG#wDiC}pWMmgC9TO-Bm+)F
zAVL*HsDTJ|1_p-7^EspxIlz%!qz4kz0uhiT2V!Z12%Sm1CQ*hA3=AM#JQtkyzVI>d
zNP$z|O>X`h{DK{vA6Ph8MQ#X+PM4l2y@F+e^kqTa4z?RYk~k9P3HA#CkteDz2t-d#
z;FR_6;QMihTcF>*)BZZQ!bNU{PYg_~B6m3W`*}NgFG$$z2;Sj(LCon2hw~kN;ol!v
znOH@B6-zKMFidb1a#UtGs4VNG#C(WB!bz6-kSwc{(q@0YY-TYPkn2GnzQvNAT3LLH
zIVUx*NNw^3K~+YL$@yXuY7n2_VgV&2Xhs7idv<697MX(#(4K4{WW?yTIa%lvvlQ4!
zaPV1x<b*(kFo*ydC?yKYHIRTr3d70s#0(e{H=h@aVbKHY2RW(81f&aWk{O5vwhD`x
z61tp_=&=N;0>=^D=v&O$sg<|5ic?GClXDV5iBx;?JZU|~vdw3ujhSS?c7bgGMRkz|
z0|SF5Gt`@tW#lv&yEnVZO=4tJnS4`Tn{n!7R)r)+(a9MKN!*}<<`#2tNl}sE<O>SM
uT!9P>42+<HCv7sXqLl<cqv!_}VMdV!${!en8AUb-e+E&Xj3x&v$^ZZzh-~Zt

delta 981
zcmez2{ML!@G%qg~0|Ns?($=l%Q-mk-NieRNsNSvC!Vtxm!r8(Q#h=2}!Vo2p!rj6U
zC78m~!Vo2t!rQ_SC0xm<$+z**b7pZfXRDad;?$zzn3B|@)Vvs%)Z*-t{DRG_tcr|`
zLX!<dWLTNf8G;!$JFtZ_F|M3EgCmfiJvl$8G&irfNRokpp-6S|R}R}CJq88_c?JfC
z;!6w+3=IrVxFs)hOE<XO<mSJ@FWABPfrXn@^oF45bm@uGD_AB-Ul!EuV7nnCxsiQ_
z%6!e4nhV^oNa^edz98v%K<otTf$|Fi{*$XYC%I2><ac6VIK&|9tjK&wR?=C9`H&eS
zh;7c|tio_uhSgb-`LH50h^?aJ!p5A;1PTr)W@BJrU}s=p_$)EmKty744cB_68kWf$
z_(di=$Z=18$R<Bof!&&seX@dp!sK>t0lsvGWTr@l6wX@qI`(=Lg<`=_;c~`uh6?6L
zhH^$_22>@JbvQVgxvC5&@8C9^tjX)8TcpCkz@W)dq{YC%aEmiJKQAS-Br`v+NE;Mr
zkdOnhbU=je<deK6QAP|5491`^yhW8TJdu7OEdD}h!UciE$<>_x+%`Lcceq{<bGpLe
zJozf8h5iIbAtz>rL(H<yD$IuzB%S4%4_PvT*j6mg>I{eFS)Emw534YP*y>6yoSP5x
zWiyMZf}E=c@)ApSYGv^)=A6{LBK65GLaL0KlP^k3$U;5Ll9E`G2u&a$Enr_;Og_S^
zF!`{MIHUXK+d`k1rNE}CgXAqigb;`j1`%Mh#M!`sS7ZnhK?<?SV&VquaiD-Y$}st%
zkjUmlaVHi%uvs9N6`6w6gH1IDu`ECY7W1V<K~Ym=1(HUxVv>v~qt0Y889laQkQL06
z9|(zVj+c>Sk^$QQHdh0rM-vpk%uqj0o+78o*s*z^+$2Uu)yaVh+KiJX*D542icEf>
pki-Vc9YscyeHD$l0vH$=7(oU{Ozu*&;u2&O{iFdVCf`w%0RRBj^&9{I

diff --git a/src/__pycache__/managerUser.cpython-312.pyc b/src/__pycache__/managerUser.cpython-312.pyc
index 066114c00fe160c03d83e6e6c335ee8c4347c0b7..f0e34ccdc3d8c4845b485f3bf05b7bc54e67f16d 100644
GIT binary patch
delta 578
zcmaFFK9!UAG%qg~0|NuY%dkD^u@iawe8D^h28Pde3=9nI4AU7>8KM|d7^0X`7^9d|
zm{M6%m{VC(SW;P2SX0?j*iu>2xH=fp7*p6=c%s--I9eE@I64?A7^66Y88kU3Uh<5&
z#gv(HizP2HH}w{4L1J-n`7QS3%)Hdx#Nt~lMfo|Y$!s9|p_rY4fq@xhyA=Zi!&JuU
z3?)zr28K?y8irn028J4j8pax?8s-|7)vS|!8I9|UKu*?Vzr|9Vnv+%pGOY+?Oc4hI
z149ufhyW?L#Tg%;oRe5w93Ni{l2!nNhF=NERxzQ)sYS&xd6v3KiP@<|G5&d}E=8GT
zsS3IZq2aCyPDPo;CHXlqE~&-YCHVz0k*SGA3Pv%G!7ee0DP@V1PcSMn@=bolD5osX
zz`*dMf#D7ZZzuaj4v85eGl~|NtPtJ6eucy0hKOhfOE2eSC8i)Aeg+1HVnzlA28ANQ
z$qh_yY(fkS44Pb%&oJqV-(t?pE4js7TvBw4B`34Eq=*mX1JOy$qLBhHZ4O0(AVF3b
z0Sd8VQ;_8?3?G?TSUEm$F|mrxQ2xNc#45JH8BDDx22(p+z|?`_uOPW^989b#MM9Ik
znYFdV7#J9Cv6dF678%}REhx&&D_O}<1acVIvR@oFx%nxjIjMF<%99r`+p&OT09+oB
Ay8r+H

delta 394
zcmbQr`G}qOG%qg~0|NuY`RQBJMJMw1nKOZS3=9mPH5eEe+8L%Zq%uS?rZ7Y?r7%V@
zcQB+erZBZ|M6skWw=hJpb}&>hMzIAmXtGRv;c1l22-ORsm>C!tK=`u(0|UcU#_0?t
zAW<;xWUOK6Wo2Mk%`mx_(b)MGe?e+dZf0?DW`3SeYFTQICetmJ;?$h9Tb%Ln$vKI|
z#qsgQAZIBw{IX8AiU}=FEh>&FNi9mvi*ZRU&MwI>m~6$Q#>hE2kx5QUjDdmSM+3th
z4&F}oiyRVHIHYdKD|E12<&c@Yh$)DNn}LC$801ccBHl^NZftxE3=Ep=lYN+V*^4+C
z7#NBKCr@A&HRFLPb132kiL$~7ke7;uKz6h+d}Lx_<@mzI#H#p>gNaq8h;Q;gW^FBy
u<So|H;?yF;TdV~|nRz8E8HzyGfKB?vVUwGmQks)$S0pnzn8l6-Bm)5NLt7dE

diff --git a/src/__pycache__/reportObj.cpython-312.pyc b/src/__pycache__/reportObj.cpython-312.pyc
index 84e9396990ad1e391f3e1c38a0873b3ca6ac71b5..7d4fc47261d2a1e864ba1e853418bb40b86ca611 100644
GIT binary patch
delta 86
zcmdnX`iPbLG%qg~0|Ntts^^}K+*XV>an4pTp~b01#W8u7x=D%IsYNmVd8sZ%nPsU8
px(cD;t_n^?nZ+gfIWaD&#n~nK1u>DSiA4%VF^<75n`0Og83A=#8*cyr

delta 49
zcmaFFx|fyvG%qg~0|NuY`RQ9Xa$7NqTP9n@gche36~~mM7NzFJxTF?mm*f|0Ze&bk
F1OR|25Lf^J

diff --git a/src/__pycache__/screenObj.cpython-312.pyc b/src/__pycache__/screenObj.cpython-312.pyc
index 404eaa518842cffc596ae0349cfae21c58093a3f..9d274a19a39a94de809bad84c3cc3abafab5b5dc 100644
GIT binary patch
delta 86
zcmcaE{YRSnG%qg~0|Ntts^^}K+<Td9;+(BwLW@(2ievIDb(0daQ;TB!^HN=kGRsmG
qbQMCwT@{>)GK)*{b7EXli?d7e3t}Qu6N?m#VjP2AHs5FZ!36-jV;y$@

delta 49
zcmew(eO;RSG%qg~0|NuY`RQ9Xa_?mlw@kK*2`x@7Dvl{hElSOcaY-%CF3B(0%)<PG
F3jm=&5n%uT

diff --git a/src/__pycache__/staffUser.cpython-312.pyc b/src/__pycache__/staffUser.cpython-312.pyc
index 1aee61bed589a71284cd861e87f81a6ed12f6fe9..adcc99e4076d9a6c6abcf958eed4ad89ebdd0127 100644
GIT binary patch
delta 1286
zcmcbv)vTs|nwOW0fq{XcIC)PxBR>PfV-N?1S)h#1B@@*hHC8i0xKZq>94Q>x8Vn3Y
z0!$34?5iQd3{jj+45?hHoD(NG)`QJtU|{%Mz`(#TogtMWiZO*DiYbLLl{tkel_iBa
zl_iBGl{JMml{t+og{_4piY-Mjg|meviakXzg{y@niX%lZg}a3%iZg{hl{Jkig{Orj
ziYrAhg|~$ziW@4%*TNFTlOmYH-@+2bn<AJZ(83bMSIMC%G&zn@E;KnaFEux@_!di1
zeoksK8`PB`3gi)Hkn6m_uB&0JVTcEbgK-U04MRL5n90DvP{Ulq5D!uh7N}vJ{GL%t
zzmh?d(NB~07F%g?YLTbQEe;UvmzbLhVFe@>7Z>p|FfbJHFfcG^vQ6$}lJ_VEIY0pn
ze#IqQ#e^2878S?jS?VSwW~Ua#_~)g%6lIpBD(EVNhPx^_6=fEe<mbe=q!wqF<QK$5
zrY06C7{xdSyG*{w<fg64z`)SJ@IXqYgQbW2hKxc7OAqf28ATBFKmsJl`9NH*gQb_}
zGs9*b)-#M;w>V0Ya==zj{>$by*^WtKvM;-W5XgN+ActwP6$ybHEHJsAT}@XJlpsLD
zVCO0n2{SM-++xkiPtVM&;twuKOiKe9r3V&}oP3FW1Ec8Vc><D~=Wv)Z3QI6BF!*V*
z7b$?ulL8Ualb>*EF$zuQ=aOI)o~*%T$f&kCiYuK_10oADoFy|aEx(8#q*{l8fng;h
z*g3_ZXiz8;p8T9!mQjB)D~~P2qRBBlPq^Wli+Cn`^U5#^P0rwzV-%j;&TGkNI{6^4
z7o+H89=<v@h`PxW_#{R2LH>f839^+pxhQpVfq)oaa#3nxNvczRes*SFy6xnLe2QSr
ziIY?Kr35WNu0qy2xu0K?(Q)!leu%2f$u0uISX5;QXmh)Q^jd=m(arM&PBX$>lP{#L
zWd#y80HqLSuy2b%!G4RgI5j6Vxg;|`uNag>6%;`JKO$ty=sB55xT;<hq@Jlr3>?V(
zw>aYC^AdAY<Ku5}#mDF7r<CS^*gWy^g{6r(5Sb#78*VWdmlWM%$;m7(DG~wM3rayn
zpr9@SxuD1lBnEbnEr?|gB0NA5!B7OU5u5^wI2ahL89*ch2PhyD85kH^7(Os@u*%O+
z{=mS&D!;%POsyyeQ#)M1)Pds9Ai2*9lLJM}WWc6@w1b?Uo0ypwAFs(>1db!w$%{p_
zt-$6Nd4i&c6_l+Ei(EjC@dFWH&7j2ii^B%uS-YYT1_lODlos1g77!IN{LbOW$mq)W
okpWD7C}3h>;pwQl#4P!cN3`3!!SyB!XNPL5&j)q}7AdgT0F%%o9{>OV

delta 1878
zcmZoxyRM~vnwOW0fq{YH{PeBq(fkYyk3k$5W`#07mrYc6)JkPv%?uHU;z;F8;mFot
zU?>t`Vo2p!4H0ID;$mV*<xb_AIKi==7b^C-hJk@$IzuW$6k`fQ6jO?D3S%mB3R5ae
z3Uew;3QH<;3TrBB3R@~$8czy)3u_d63P%e=6i13k3U>=j6laP^3Qr456jzE!3U3Qb
z6n6?|Dr*{33SSFL6i<ps3V#br6faavpoJxhFGVCpu!SXxA0#Q%!V)D=$)zbeIe<~F
zz96+I*QYG!7JG7LUTSV)@h$eu+ybZk{G4QVs8c}{3j+fK$d{k9z|O8=E8;6*1WAB!
z3S$b>8s^nZAT|R7BSR%a4Py;MJY2qpsfHmQD$Br7!(77<4>Aj^yuOB|h9MqgJeXU<
zTEh?z3txsx22B>fTO1`xIiba=Ma8!mG?{L(mLw+Sq~798&d*E9EXmBz(`36PTAZ4b
znp_f}R+OI`Uy_s)U!IX#lzNM;v^cfM)8!Tii1tg&O@*)m5{rv(@q_%GSzOGYnV;vA
zT9%qq1d16=_Q^a<@|s0_3=9m#Apa{sz%R>Ws~E5wVoFkrQuAV5Qj4=o@(U&xGr2`r
zFfcGQFg)ZIdcvc)f@??8RUXG1JOUrs7~~Z@Tzb53D5!L}^!VOTPz6yB)b%=CuJ9;4
zkXGt&>Gk;x@^vyiq!<_&K*<giI-loE&S8_DJcCb!c{W4J<OD8p#@Unqa>&-#Fl2Fn
zbfMze3@I!%3|S!Es1gjb8B$p1as@MJviVhsD1d@OAwMZAHMv9s#P)Qtt>V@J3xh%k
z&H)9IZIzIY0yLap!DL(ii&0aP?G|Tzd~!}=adCY7Esps3yu{qp`1m4G1_p*AF%TgR
zA|x0X7*;YCNrD0s<VA%dDFz0HTkP@i#U(}Y@l}GsC5dTipkUR53W1dtfWz~Kkl1v+
ziF((CG%pHiUJ%r}pk=qCWPkO}i0U1=C#)}oM_&(5xfq^uAuRPmYQcrV((8qF7Ypky
z6x4rUU~pgxV*0?q5X=<L^c_T{Gkt_m9~c;dm@+_e8BCcVN+1hFa%M3V$!vbYbcT_&
zNPvNXVe&2(FV-Rv5KEd>Q3#YWir5$!7&O_yo+%QW?8mC6s{`^ENEnhvAf98*$xqMB
ztKvs^4J;rtc_HftMw!X^e3F~9*-ROQLDu+bvKMKC0!j@;s88O^uEi)h`5wCjqtxW@
z?1qe*n>9Jo8Py=Nppaw9%uCCMgt9qEiz3Jc(2$+HgHx8#X!12qTZlE2H*gqCj^*0I
z4cA`8J6VQXhEZ~|CAS=-)Z_?mOGb;yleoPYWhUR{u499!o1DlaDS~V+$X?#$qSVQb
zd}0R4MX8A;sZRO%*_nCi4h#$opFwflz;K6yzn{00_kx(=6%M02e2SO(lrL~77l8~;
zoNUS~CFq3V+yq`tMwiK5yozA!GbfAk31d-Z$*0Zj0n+OVB4jq_^POgdxzs^GTgU|@
zYz2xMW=PcNOs*9WXOx;eRlt_fXYyr%s(KlaEMpN9h+-;IW?*3O(-bUH0Qrk6K0Y@;
zr8FlsKK>R@e0*VPVh%JV`-7yJi%W`bvE*bHm)v4W%FoX!k_OqP1R@MT1UL>rmKTA7
zq6q93caVf9hzJ6ueuknjkp1AaQ3T4iU;@M_&Szj?Xkqxs#K)>UL-_*(AFJ{LXE3#*
z7)<Se@J@(;c^AT?KZDeKQeb4wV*1QBnO(?C25dCQFi;-MP0Y-TkJscW0!O6A<VYdy
z`de&}tPZvn;%8P+t~V_51357QM1TzeWz1h3HjvP;D~e|TmE#Ny#r6yg3?G;o85!?0
zh}>n6y~7}SmqGRmM<64kE8_&VFAQMDhcYGx7M_l(OU#lFc|^Ot8(eR)aCWG+`fz<<
LXJC;k0@(lnFJ{F!

diff --git a/src/adminUser.py b/src/adminUser.py
index 069c0d7..7dc9cb7 100644
--- a/src/adminUser.py
+++ b/src/adminUser.py
@@ -6,9 +6,9 @@ class AdminUser(StaffUser):
     Args:
         staffUser (_type_): _description_
     """
-    def __init__(self):
-        super().__init__()
-        self.permissionLevel = 1
+    def __init__(self, id:int, name:str, passw:str, cinemas:list, role:int):
+        super().__init__(self, id, name, passw, cinemas)
+        self.role = 1
 
 
 
diff --git a/src/dbfunc.py b/src/dbfunc.py
index d388d5a..377eeff 100644
--- a/src/dbfunc.py
+++ b/src/dbfunc.py
@@ -28,15 +28,13 @@ def get_connection():
         return None
 
 # Function to SELECT data from any table
-def select_from_table(table, *columns):
+def select_from_table(table, *args):
     """Fetches data from a given table."""
     conn = get_connection()
-    if not conn:
-        return []
 
     try:
         cursor = conn.cursor(dictionary=True)
-        query = f"SELECT {', '.join(columns) if columns else '*'} FROM {table}"
+        query = f"SELECT {', '.join(args) if args else '*'} FROM {table}"
         cursor.execute(query)
         results = cursor.fetchall()
         return results
@@ -48,24 +46,32 @@ def select_from_table(table, *columns):
         conn.close()
 
 # Function to SELECT data with a WHERE condition
-def select_from_table_where(table, condition, *columns):
-    """Fetches data from a table with a WHERE condition."""
+def select_from_table_where(table:str, condition:str, *args):
+    """Fetches data from a table with a WHERE condition.
+    
+    Arguments:
+        table (str): database table name, eg; "tblUsers"
+        condition (str): condition string in SQL format, eg; "WHERE username = %s AND password_hash = %s"
+        *columns: excepts all aditinal arguments and converts them into SQL query following SELECT as arguments, if none SQL statemnt uses *.
+    Returns:
+        dict
+    """
     conn = get_connection()
     if not conn:
         return []
 
     try:
         cursor = conn.cursor(dictionary=True)
-        query = f"SELECT {', '.join(columns) if columns else '*'} FROM {table} WHERE {condition}"
+        query = f"SELECT {', '.join(args) if args else '*'} FROM {table} WHERE {condition}"
         cursor.execute(query)
         results = cursor.fetchall()
         return results
     except mysql.connector.Error as err:
         logging.error(f"Error fetching data with condition: {err}")
-        return []
-    finally:
-        cursor.close()
-        conn.close()
+        return None
+    #finally:
+    #    cursor.close()
+    #    conn.close()
 
 # Function to INSERT data into any table
 def insert_into_table(table, data):
diff --git a/src/managerUser.py b/src/managerUser.py
index f74edda..18d72f2 100644
--- a/src/managerUser.py
+++ b/src/managerUser.py
@@ -6,9 +6,9 @@ class ManagerUser(AdminUser):
     Args:
         userClass (_type_): _description_
     """
-    def __init__(self):
-        super().__init__()
-        self.permissionLevel = 2
+    def __init__(self, id:int, name:str, passw:str, cinemas:list, role:int):
+        super().__init__(self, id, name, passw, cinemas)
+        self.role = 2
     
     def expand_buisness(self):
         # creates new cinemaObj and adds it to db.
diff --git a/src/staffUser.py b/src/staffUser.py
index 27e217a..0fcdd27 100644
--- a/src/staffUser.py
+++ b/src/staffUser.py
@@ -5,25 +5,22 @@ from .cinemaObj import Cinema
 
 
 # trying to make this a base implementation for all user classes.
-class StaffUser(object):  
-    def __init__(self, id:int, name:str, passw:str, permLvl:int, cinemas:list, impBool:bool=0):
-        # impbool used to switch case on a newly created user or imported from database.
-        if impBool:
-            # import user from db
-            select_from_tbl_where(table="tblUsers", condition="")
-            pass
-        else:
-            # staff id number assigned by manager during onboarding.
-            self.userID:int = id
-            self.userName:str = name
-            self.userPass:str = passw
-            # staff software level.
-            self.permissionLevel:int = permLvl
-            # list of branches active at.
-            self.cinemas = cinemas
-        
-    def __str__(self):
-        return f"{self.__class__.__name__} user object(userID={self.userID}, userName={self.userName}, userPass={self.userPass}, permissionLevel={self.permissionLevel})"
+class StaffUser:  
+    def __init__(self, id:int, name:str, passw:str, cinemas:list, role:int):
+        # staff id number assigned by manager during onboarding.
+        self.userID:int = id
+        self.userName:str = name
+        self.userPass:str = passw
+        # staff software level.
+        self.role:int = role
+        # list of branches active at.
+        self.cinemas = cinemas
+    
+    
+    # function not working, causes massive recursion?
+    #def __repr__(self):
+    #"""this function returns this object in a string readable format, eg; print(staffUser) returns 'StaffUser user object(userID=1, userName='user', userPass='password'... ' """
+    #    return f"{self.__class__.__name__} user object(userID={self.userID}, userName={self.userName}, userPass={self.userPass}, permissionLevel={self.role})"
 
     def login(self, userName, userPassword) -> None:
         """get values for self from db"""
-- 
GitLab