diff --git a/GoogleCloudDocumentation.docx b/GoogleCloudDocumentation.docx index e729d6d..f095447 100644 Binary files a/GoogleCloudDocumentation.docx and b/GoogleCloudDocumentation.docx differ diff --git a/TaskManager.docx b/TaskManager.docx index 9b2c1b3..d52e656 100644 Binary files a/TaskManager.docx and b/TaskManager.docx differ diff --git a/driver.py b/driver.py index e145e14..f34dfbf 100644 --- a/driver.py +++ b/driver.py @@ -8,17 +8,23 @@ import scheduledPayrollWindow as PWin #TODO demonstrate workflow with git #TODO search section/date (show curr and orig people assigned) +#TODO drop rows that are "closed" in the sections.txt (in sectionsCSVHelper) #TODO document how to setup for next semester (staff and section changes) -#TODO document how to get through the cert expiration every week +#TODO document how to get through the cert expiration every week? Didn't expire this week? #TODO do error checking within while loop (update text color / valid status) +# IMPOSSIBLE: pysimplegui does not allow for changing of the layout object after the window is created, +# so the number of rows of checkboxes cannot be changed without reopening the window +# It would be possible to have a "main menu" but all the processing work would still happen during the "sub menu" phase +# and it would open more race-condition issues with overlapping requests +# So it doesn't make much difference compared to simply re-running the program #---LOW PRIORITY (due to payroll being entered by ULAs directly)--- #TODO hours database #TODO section/helproom attendence verification form (filled out by ULAs themselves) -#TODO add to hours database +#TODO add to hours database. #TODO staff meeting attendence google form #TODO add to hours database #TODO request ad hoc hours google form & approval interface (mirrors sub requests workflow) diff --git a/helperFunctions.py b/helperFunctions.py index 63a581c..8760629 100644 --- a/helperFunctions.py +++ b/helperFunctions.py @@ -79,6 +79,13 @@ def getDatesFromSection(sec): dates = list(secD.loc[secD["Section"]==sec]["Date"]) return dates +def getAllDataForSection(sec): + secD = pd.read_csv(sectionDatabaseFilename,dtype=str,index_col=False) + secDOrig = pd.read_csv(sectionDatabaseFilename[:-4]+"_Orig.csv",dtype=str,index_col=False) + ret=secD.loc[secD["Section"]==sec].dropna(axis=1).drop('Section',axis=1) + ret2=secD.loc[secD["Section"]==sec].dropna(axis=1).drop('Section',axis=1) + return ret,ret2 + #Tests if a netID is currently assigned to a given section on a given date def isAssigned(netID,period,date): secD = pd.read_csv(sectionDatabaseFilename,dtype=str,index_col=False) diff --git a/lastUpdatedToken.txt b/lastUpdatedToken.txt index 53d5ce0..58fa9ca 100644 --- a/lastUpdatedToken.txt +++ b/lastUpdatedToken.txt @@ -1 +1 @@ -2023-10-11 15:40:17.780872 \ No newline at end of file +2022-10-04 15:15:51.231447 \ No newline at end of file diff --git a/sectionViewWindow.py b/sectionViewWindow.py new file mode 100644 index 0000000..4326475 --- /dev/null +++ b/sectionViewWindow.py @@ -0,0 +1,65 @@ +import PySimpleGUI as sg +import csv +import pandas as pd +import helperFunctions as HF + +def secViewWin(defaultFont): + + #Printing options for the Pandas dataframe + pd.set_option('display.min_rows', 20) + pd.set_option('display.expand_frame_repr', False) + pd.set_option('max_colwidth', 30) + + #Pull all section titles for the poopulation of the drop-down box + sections=HF.getAllSectionTitles() + + #Define the window's layout + layout=[[sg.Combo(sections,size=(7,1),key="-SECTION-",readonly=True, enable_events=True)], + [sg.Multiline("",size=(160,40),key="-OUTPUT-")], + [sg.Button("Close")]] + + # Create the Window + window = sg.Window('Section Viewer', layout, font=defaultFont,resizable=True) + + #Event Loop to process "events" and get the "values" of the inputs + #Cease running if they close the window + event=-1 + while event != sg.WIN_CLOSED and event != "Close": + event, values = window.read() + + #If the 'section' box is interacted with and is not blank (i.e. an option was selected from the dropdown box) + if event=="-SECTION-" and values['-SECTION-']!="": + #Clear the box + window["-OUTPUT-"].Update('') + + #get the data + sec=values['-SECTION-'] + output,output2=HF.getAllDataForSection(sec) + output=output.values.tolist() + output2=output2.head(1).values.tolist()[0] + + #Print the normal schedule + window["-OUTPUT-"].print("Normally Scheduled: "+str(output2[2])+" @ "+str(output2[3]),text_color='black') + normalNames=[] + for ID in output2[4:]: + normalNames.append(f'{HF.IDToName(ID)[:15]:15}') + window["-OUTPUT-"].print('1 '+output2[1]+' '+', '.join(normalNames),text_color='blue') + + #Print a linebreak + window["-OUTPUT-"].print("-"*160,text_color='black') + + #print the schedule for each week + window["-OUTPUT-"].print("Currently Scheduled:",text_color='black') + for line in output: + names=[] + for ID in line[4:]: + names.append(f'{HF.IDToName(ID)[:15]:15}') + color='blue' + if names!=normalNames: + color='red' + window["-OUTPUT-"].print(f'{line[0]:2} '+line[1]+' '+', '.join(names),text_color=color) + + + + + window.close() diff --git a/sectionsDatabase.csv b/sectionsDatabase.csv index 300af45..4bc8598 100644 --- a/sectionsDatabase.csv +++ b/sectionsDatabase.csv @@ -1714,4 +1714,4 @@ Sec 56,13,11/21,12:40 PM-2:30 PM,403 Computer Center,john7531,imranmoh,,,,,,,,,, Sec 56,14,11/28,12:40 PM-2:30 PM,403 Computer Center,john7531,imranmoh,,,,,,,,,,,,,,,,,, Sec 56,14,11/30,12:40 PM-2:30 PM,403 Computer Center,john7531,imranmoh,,,,,,,,,,,,,,,,,, Sec 56,15,12/05,12:40 PM-2:30 PM,403 Computer Center,john7531,imranmoh,,,,,,,,,,,,,,,,,, -Sec 56,15,12/07,12:40 PM-2:30 PM,403 Computer Center,john7531,imranmoh,,,,,,,,,,,,,,,,,, +Sec 56,15,12/07,12:40 PM-2:30 PM,403 Computer Center,john7531,imranmoh,,,,,,,,,,,,,,,,,, \ No newline at end of file diff --git a/substitutionApprovalWindow.py b/substitutionApprovalWindow.py index a1ed30d..87b87ad 100644 --- a/substitutionApprovalWindow.py +++ b/substitutionApprovalWindow.py @@ -4,6 +4,7 @@ import pandas as pd import helperFunctions as HF import substitutionHistoryWindow as SHW import substitutionManualWindow as SMW +import sectionViewWindow as SVW #Printing options for Pandas (for debugging) pd.set_option('display.min_rows', 20) @@ -107,7 +108,7 @@ def subAppWin(staffDatabaseFilename,secDFilename,subRequestsFilename,subRequests layout.append([sg.Text('-'*(sum(columnWidths)+27))]) #Adding buttons - layout.append([sg.Button('Ok'), sg.Button('Cancel'), sg.Button('See Sub History'), sg.Button('Make Manual Changes')]) + layout.append([sg.Button('Ok'), sg.Button('Cancel'), sg.Button('See Sub History'), sg.Button('Make Manual Changes'), sg.Button('Section Viewer')]) layout=[[sg.Column(layout,scrollable=True,expand_y=True,expand_x=True)]] # Create the Window @@ -135,6 +136,8 @@ def subAppWin(staffDatabaseFilename,secDFilename,subRequestsFilename,subRequests #event is the most recent "click" from the user if event == "See Sub History": SHW.subHisWin(subRequestsArchiveFilename,defaultFont) #open history window + if event == "Section Viewer": + SVW.secViewWin(defaultFont) #open section viewer if event == "Make Manual Changes": window['Ok'].Update(disabled=True) #This is to prevent undefined behavior as a result of manual changes not being represented in the main window SMW.subManualWin(subRequestsArchiveFilename,defaultFont) #open manual change window diff --git a/substitutionManualWindow.py b/substitutionManualWindow.py index b38c639..32a81f7 100644 --- a/substitutionManualWindow.py +++ b/substitutionManualWindow.py @@ -12,9 +12,9 @@ def subManualWin(subRequestsArchiveFilename,defaultFont): #Define the window's layout layout=[[sg.Text("Email?| Sec | Date | Replacee | Replacement")], - [sg.Checkbox('',size=(3,1),key='-EMAILCHECK-'),sg.Combo(sections,size=(6,1),key="-SECTION-",readonly=True, enable_events=True),sg.Combo([""],size=(6,1),key='-DATE-',readonly=True, enable_events=True),sg.Combo([""],size=(30,1),key="-REPLACEE-", enable_events=True,readonly=True),sg.Combo(allnames,size=(30,1),key="-REPLACEMENT-", enable_events=True,readonly=True)], + [sg.Checkbox('',size=(3,1),key='-EMAILCHECK-'),sg.Combo(sections,size=(7,1),key="-SECTION-",readonly=True, enable_events=True),sg.Combo([""],size=(6,1),key='-DATE-',readonly=True, enable_events=True),sg.Combo([""],size=(30,1),key="-REPLACEE-", enable_events=True,readonly=True),sg.Combo(allnames,size=(30,1),key="-REPLACEMENT-", enable_events=True,readonly=True)], [sg.Text("Reason for manual change: "),sg.Input(key='-REASON-')], - [sg.Button("Close Window"),sg.Button("Make Change")]] + [sg.Button("Close"),sg.Button("Make Change")]] # Create the Window window = sg.Window('Manual Substitution', layout, font=defaultFont,resizable=True) @@ -22,7 +22,7 @@ def subManualWin(subRequestsArchiveFilename,defaultFont): #Event Loop to process "events" and get the "values" of the inputs #Cease running if they close the window event=-1 - while event != sg.WIN_CLOSED and event != "Close Window": + while event != sg.WIN_CLOSED and event != "Close": event, values = window.read() #If the 'section' box is interacted with and is not blank (i.e. an option was selected from the dropdown box) diff --git a/substitutionRequestForm.csv b/substitutionRequestForm.csv index 6697163..c302847 100644 --- a/substitutionRequestForm.csv +++ b/substitutionRequestForm.csv @@ -1,27 +1 @@ Timestamp,Requestor,Section,Dates,Replacement,Reason -2023-09-19 13:57:17.596000,sipahiog,Sec 46,09/19,haggart3,Sickness -2023-09-19 18:45:55.239000,sebalyma,Sec 40,10/10,ngvivian,will be in ohio for beginning of that week -2023-09-19 22:32:06.420000,mcgui186,Sec 6,09/21,schul769,Funeral -2023-09-20 17:12:04.654000,austi143,Sec 11,09/20,,"Grandpa had stroke, have to go home" -2023-09-20 17:12:30.949000,gautamya,Sec 21,09/20,,Sick -2023-09-20 17:29:31.529000,upadhy19,Sec 4,09/20,,Strong Stomachache -2023-09-21 13:22:29.001000,sipahiog,Sec 46,09/21,,Sickness -2023-09-21 18:25:24.758000,mcgui186,R_HR2,09/21,sipahiog,Funeral -2023-09-21 18:26:11.335000,mcgui186,R_HR1,09/21,haggart3,Funeral -2023-09-23 14:25:11.349000,borekmi1,Sec 1,09/25,sebalyma,Problem with the transportation to MSU -2023-09-25 17:05:16.919000,burgejae,Sec 46,09/26,aggarw75,Important meeting came up -2023-09-25 17:05:25.520000,anindhos,M_HR1;M_HR2,09/25,bhardw41,Mandatory project meeting -2023-09-25 21:37:26.276000,aggarw75,Sec 11,09/27,lnumehak, -2023-09-26 01:51:03.453000,john7531,S_HR1;S_HR2,10/02,bhardw41,Laptop died. Replacement may not come before my shift. -2023-09-26 14:52:30.307000,darshanv,W_HR1;W_HR2;Sec 20,09/27,micksoph,Visiting the SSN office for on campus registration and receiving SSN -2023-09-26 16:25:19.977000,sipahiog,T_HR1;T_HR2,09/26,haggart3,Something came up with a class -2023-09-28 14:58:15.450000,sonarsoh,Sec 17,10/02;10/04,tagaychr,broken arm -2023-10-03 19:14:01.917000,sipahiog,Sec 30,10/09,john7531,out of town -2023-10-04 19:47:39.642000,schne542,Sec 19,10/09,aggarw75,I have a doctors appointment on 10/9 back home. -2023-10-04 20:02:13.852000,mcgui186,R_HR1;R_HR2,10/05,haggart3,I need to go to helproom for a project of mine -2023-10-04 20:07:34.501000,sipahiog,Sec 46,10/10,haggart3,Out of town -2023-10-09 17:51:15.406000,austi143,Sec 11,10/09,bhardw41,I’m sick -2023-10-11 01:06:38.157000,pittend2,Sec 25,10/11,kumararn,Sick -2023-10-11 16:49:39.541000,murraydr,M_HR1;M_HR2,10/09,,test1 -2023-10-11 16:50:11.365000,murraydr,M_HR1,10/02;10/09,,test2 -2023-10-11 17:24:59.666000,austi143,Sec 11,10/11,lnumehak,I’m sick