DavidD003 commited on
Commit
78699c2
·
1 Parent(s): af68ff8

Upload SchedBuilderUtyModule.py

Browse files
Files changed (1) hide show
  1. SchedBuilderUtyModule.py +368 -0
SchedBuilderUtyModule.py ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from SchedBuilderClasses import *
2
+ import openpyxl as pyxl
3
+ import pandas as pd
4
+ import numpy as np
5
+ import sqlite3
6
+
7
+
8
+ # def debug(func):
9
+ # """Print the function signature and return value"""
10
+ # @functools.wraps(func)
11
+ # def wrapper_debug(*args, **kwargs):
12
+ # args_repr = [repr(a) for a in args] # 1
13
+ # kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()] # 2
14
+ # signature = ", ".join(args_repr + kwargs_repr) # 3
15
+ # print(f"Calling {func.__name__}({signature})")
16
+ # value = func(*args, **kwargs)
17
+ # print(f"{func.__name__!r} returned {value!r}") # 4
18
+ # return value
19
+ # return wrapper_debug
20
+
21
+
22
+
23
+ def addTBL(tblName,fields="",dTypes=None,data=None,addOn=False):
24
+ """Create table if not already existing, optionally with data, optionally clearing out old data if present. Fields as list of strings. Datatypes as list of strings, one must be provided for each field. See sqlite3 docs for mroe info"""
25
+ conn = sqlite3.connect('test14.db')
26
+ c = conn.cursor()
27
+ listedFields=''
28
+ if fields=="": #If none given, make alphabetical
29
+ fields=[chr(65+i) for i in range(len(data[0]))]
30
+ if dTypes==None: #Need not specify dtypes
31
+ for f in fields:
32
+ listedFields=listedFields+', '+ f
33
+ else: #define data types at inception of table
34
+ flds=list(zip(fields,dTypes))
35
+ for pair in flds:
36
+ listedFields=listedFields+', '+pair[0]+' '+pair[1]
37
+ listedFields='('+listedFields[2:]+''')''' #Add leading and closing bracket, remove naively added comma+space from leading field
38
+ c.execute('''CREATE TABLE IF NOT EXISTS '''+tblName+listedFields) # Create table.
39
+ if addOn==False: #Delete if not adding
40
+ c.execute('''DELETE FROM '''+tblName)
41
+ if (data is not None) and len(data)>0:
42
+ stmnt='INSERT INTO '+tblName+' VALUES ('
43
+ for i in range(len(fields)-1):
44
+ stmnt=stmnt+'?,'#Add '?,' equal to num columns less 1
45
+ stmnt=stmnt+'?)' #add closing ?), no final comma
46
+ for subEntry in data:
47
+ c.execute(stmnt, subEntry)
48
+ conn.commit()
49
+
50
+ def isNumeric(n):
51
+ try:
52
+ n=int(n)
53
+ return True
54
+ except ValueError:
55
+ try:
56
+ n=float(n)
57
+ return True
58
+ except:
59
+ return False
60
+
61
+
62
+ def viewTBL(tblName,fields=None,sortBy=None,filterOn=None,returnStatement=0):
63
+ """return np array of table with optional select fields, filtered, sorted. Sort syntax=[(field1,asc/desc),(field2,asc/desc)...] Filter syntax=[(field1,value),(field2,value)...]"""
64
+ conn = sqlite3.connect('test14.db')
65
+ c = conn.cursor()
66
+ stmnt='SELECT '
67
+ if fields!=None:
68
+ flds=''
69
+ for f in fields:
70
+ flds=flds+', '+f
71
+ stmnt=stmnt+flds[2:]+ ' FROM ' +tblName+' '
72
+ else: stmnt=stmnt+'* FROM '+tblName+' ' #unspecified, select all
73
+ if filterOn!=None:
74
+ filt='WHERE '
75
+ for f in filterOn:
76
+ if isNumeric(f[1]): filt=filt+f[0]+' = '+ str(f[1])+' AND '
77
+ else: filt=filt+str(f[0])+' = "'+ str(f[1])+'" AND '
78
+ filt=filt[:-4] #Remove naively added final " and "
79
+ stmnt=stmnt+filt
80
+ if sortBy!=None:
81
+ srt='ORDER BY '
82
+ for s in sortBy:
83
+ srt=srt+s[0]+' '+s[1]+', '
84
+ srt=srt[:-2]
85
+ stmnt=stmnt+srt
86
+ stmnt=stmnt+';'
87
+ if returnStatement==True: # Add option to print out the sql statement for troubleshooting
88
+ return stmnt
89
+ else:
90
+ c.execute(stmnt)
91
+ return [list(x) for x in c.fetchall()] #sqlite3 returns list of tuples.. want sublists for being editable
92
+
93
+ def FTbtRow(ws):
94
+ """Returns the excel row number for the bottom row with data in FT employee sheet"""
95
+ #1st find bottom row with data
96
+ for i in range(5,400):
97
+ ref="C"+str(i) #Referencing EEID column. Failure mode is EEID missing for someone. Thats a bigger problem than the code not working
98
+ if ws[ref].internal_value==None:
99
+ #Condition met when end of data found.
100
+ btmRow=i-1 #backtrack to last data
101
+ break
102
+ return btmRow
103
+
104
+ def getFTinfo(flNm):
105
+ """Returns dataframe with FT employee info (seniority,crew,eeid,name,refusal hours to date, OT hrs worked this week given path to FT refusal sheet"""
106
+ myWb=pyxl.load_workbook(flNm)
107
+ ws=myWb['Hourly OT']
108
+ btmRow=FTbtRow(ws)
109
+ tab=[[x.internal_value for x in sublist] for sublist in ws['A5:I'+str(btmRow)]]
110
+ #for rec in tab: #numeric values getting cast to string on import. cast back
111
+ # for i in [0,2]:
112
+ # rec[i]=int(rec[i])
113
+ # for i in [5,6,7]:
114
+ # rec[i]=float(rec[i])
115
+ #Following to turn into dataframe
116
+ #df_FTinfo=pd.DataFrame(tab)
117
+ #df_FTinfo=df_FTinfo[[0,1,2,3,4,5,8]] #Pull out only required columns
118
+ #df_FTinfo.set_axis(['snrty', 'crew', 'eeid','last','first','yrRef','wkOT'], axis='columns', inplace=True)
119
+ return tab
120
+
121
+
122
+ def FTendCol(ws):
123
+ """Returns column # for last column of skills matrix in excel from FT refusal sheet"""
124
+ for i in range(0,400):
125
+ if ws['A1'].offset(0,i).value=='Start-up':
126
+ #Condition met when end of data found.
127
+ endCol=i-1
128
+ break
129
+ return endCol
130
+
131
+ def getFTskills(flNm):
132
+ """Returns a dataframe containing a table with 2 fields: eeid and job name, with one record for every job an ee is trained in"""
133
+ myWb=pyxl.load_workbook(flNm)
134
+ ws=myWb['Hourly OT']
135
+ endCol=FTendCol(ws) #Get right limit for iteration through skills
136
+ btmRow=FTbtRow(ws) #Get bottom limit for iteration through skills
137
+ skills=[] #Initialize empty skills list
138
+ for i in range(5,btmRow+1): #Data starts on row 5. +1 because range fn not inclusive
139
+ eeid=ws['C'+str(i)].value
140
+ for c in range(10,endCol+1):
141
+ if ws['C'+str(i)].offset(0,c-2).value==1: #subtract 2 from c because the endCol is counted from col A, and we are offsetting from col C, whihc is 2 offset from A
142
+ jobNm=ws['A2'].offset(0,c).value #if 1 indicates trained, pull job name from header row
143
+ skills.append([eeid,jobNm]) #Add new record to skills table
144
+ #idxs=np.array(skills)[:,0]
145
+ #skills=pd.DataFrame(skills,idxs) #Convert to dataframe
146
+ #skills.set_axis(['eeid','skill'], axis='columns', inplace=True)
147
+ return skills
148
+
149
+ def TempbtRow(ws):
150
+ """Returns the excel row number for the bottom row with data in Temp employee sheet"""
151
+ #1st find bottom row with data
152
+ for i in range(4,400):
153
+ ref="C"+str(i) #Referencing EEID column. Failure mode is EEID missing for someone. Thats a bigger problem than the code not working
154
+ if ws[ref].internal_value==None:
155
+ #Condition met when end of data found.
156
+ btmRow=i-1 #backtrack to last data
157
+ break
158
+ return btmRow
159
+
160
+ def getTempinfo(flNm):
161
+ """Returns dataframe with FT employee info (seniority,crew,eeid,name,refusal hours to date, OT hrs worked this week given path to FT refusal sheet"""
162
+ myWb=pyxl.load_workbook(flNm)
163
+ ws=myWb['Temp Refusal']
164
+ btmRow=TempbtRow(ws)
165
+ tab=[[x.internal_value for x in sublist] for sublist in ws['A4:I'+str(btmRow)]]
166
+ #df_Tempinfo=pd.DataFrame(tab)
167
+ #df_Tempinfo=df_Tempinfo[[0,1,2,3,4,5,8]] #Pull out only required columns
168
+ #df_Tempinfo.set_axis(['snrty', 'crew', 'eeid','last','first','yrRef','wkOT'], axis='columns', inplace=True)
169
+ return tab
170
+
171
+ def TempendCol(ws):
172
+ """Returns column # for last column of skills matrix in excel from FT refusal sheet"""
173
+ for i in range(0,400):
174
+ if ws['A2'].offset(0,i).value=='Start Up':
175
+ #Condition met when end of data found.
176
+ endCol=i-1
177
+ break
178
+ return endCol
179
+
180
+ def getTempskills(flNm):
181
+ """Returns a dataframe containing a table with 2 fields: eeid and job name, with one record for every job an ee is trained in"""
182
+ myWb=pyxl.load_workbook(flNm)
183
+ ws=myWb['Temp Refusal']
184
+ endCol=TempendCol(ws) #Get right limit for iteration through skills
185
+ btmRow=TempbtRow(ws) #Get bottom limit for iteration through skills
186
+ skills=[] #Initialize empty skills list
187
+ for i in range(4,btmRow+1): #Data starts on row 5. +1 because range fn not inclusive
188
+ eeid=ws['C'+str(i)].value
189
+ for c in range(11,endCol+1): #First skills column is 11 offset from col A
190
+ if ws['C'+str(i)].offset(0,c-2).value==1: #subtract 2 from c because the endCol is counted from col A, and we are offsetting from col C, which is 2 offset from A
191
+ jobNm=ws['A3'].offset(0,c).value #if 1 indicates trained, pull job name from header row
192
+ skills.append([eeid,jobNm]) #Add new record to skills table
193
+ #idxs=np.array(skills)[:,0]
194
+ #skills=pd.DataFrame(skills,idxs) #Convert to dataframe
195
+ #skills.set_axis(['eeid','skill'], axis='columns', inplace=True)
196
+ return skills
197
+
198
+ def imptXlTbl(XlFl,ShtNm,TblNm):
199
+ myWb=pyxl.load_workbook(XlFl)
200
+ ws=myWb[ShtNm]
201
+ tab=ws.tables[TblNm] #Pull out table
202
+ tab=[[x.value for x in sublist] for sublist in ws[tab.ref]] #Convert to list of lists (each sublist as row of excel table)
203
+ return tab[1:] #Convert nested lists to array, dropping first row which is table headings
204
+
205
+ def generateMasterPollTbl(pollDict):
206
+ """Given a dictionary containing the polling tables for all crews, generates a master tbl in SQLlite for being able to filter on peoples availabilities, with '1' indicating interest, '0' no interest, and slot seq 1 starting at index 4"""
207
+ mPollTbl=[]
208
+ #the total list of all fields the table has is programmatically generated on these 3 lines
209
+ flds=["eeid",'lastNm','firstNm','ytdRefHrs']
210
+ flds.extend(['slot_'+str(i) for i in range(1,25)])#Note that there is one field for each slot seqID, 1 through 24, for filtering
211
+ flds.append('Comment')
212
+ for crewKey in pollDict:
213
+ tbl=pollDict[crewKey] #Pull the crew specific OT polling table from dictionary
214
+ for rec in tbl:
215
+ cmnt=rec[16]#retrieve comment to tag on later
216
+ slotwise_polling=list(rec[:4])
217
+ for i in range(4,16):
218
+ if rec[i] not in ('n','N',None) :
219
+ slotwise_polling.extend(['y','y']) #Add two entries because 1 entry in polling sheet applies to two slots
220
+ else:
221
+ slotwise_polling.extend(['n','n'])
222
+ slotwise_polling.append(cmnt)
223
+ mPollTbl.append(slotwise_polling)
224
+ addTBL('allPollData',fields=flds, data=mPollTbl,addOn=False)
225
+
226
+
227
+ def pullTbls(FtBook,TempBook,AssnBook,PollBook): #Need to make volunteer shift data puller
228
+ """Take flNm, return ftInfoTbl, ftSkillsMtx, tempInfoTbl, tempSkillsMtx, AssignmentsTbl, slot_Legend, JobTrnCrossRef, pollDict, All_Slots, senList. Uses functions defined previously to return all required tables at once. Function of functions for final script"""
229
+ a=getFTinfo(FtBook) #to sqlite
230
+ b=getFTskills(FtBook) #to sqlite
231
+ b=[[int(d[0]),d[1]] for d in b] #Cast EEid to numeric value
232
+ c=getTempinfo(TempBook) #to sqlite
233
+ d=getTempskills(TempBook) #to sqlite
234
+ d=[[int(data[0]),data[1]] for data in d] #Cast EEid to numeric value
235
+ e=imptXlTbl(AssnBook,'Assignment_List','Assn_List')
236
+ f=imptXlTbl(AssnBook,'Slot_Legend','Slot_Legend')
237
+ g=imptXlTbl(AssnBook,'Job_Training_Crossref','TrainAssnMtx') #to sqlite
238
+ pollDict={} #Generate empty dictionary to store tables of people voluntary overtime
239
+ for crew in ['Blue','Bud','Rock']:
240
+ for eeType in ['FT','Temp']:
241
+ keyNm='tbl_'+crew+eeType
242
+ tbl=imptXlTbl(PollBook,'Sheet1',keyNm)
243
+ pollDict[keyNm]=tbl
244
+ h=imptXlTbl(AssnBook,'All_Slots','All_Slots')
245
+ #Generate tables in sqlite
246
+ addTBL("sklMtx",fields=["EEID","trnNm"],data=b,addOn=False) #Overwrite all training data and populate FT ops, then append temps for a master table
247
+ addTBL("sklMtx",fields=["EEID","trnNm"],data=d,addOn=True)
248
+ addTBL("xRef",fields=["dispNm","trnNm"],data=g,addOn=False) #Skill name cross ref table for fcn dispToTrn to work
249
+ addTBL("FTinfo",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],data=a,addOn=False)
250
+ addTBL("TempInfo",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],data=c,addOn=False)
251
+ # addTBL("FTinfo",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],dTypes=['NUM','TEXT','NUM','TEXT','TEXT','NUM','NUM','NUM'],data=a,addOn=False)
252
+ # addTBL("TempInfo",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],dTypes=['INTEGER','TEXT','INTEGER','TEXT','TEXT','INTEGER','INTEGER','INTEGER'],data=c,addOn=False)
253
+ #Generate a master seniority table.. following replaces hire date with integers for temps
254
+ senHiLoTemps=viewTBL('TempInfo',sortBy=[('sen','ASC')]) #First retrieve list of temps, most senior to least
255
+ i=100000 #Start new seniority number at arbitrarily high value not to interfere with full timer
256
+ for row in senHiLoTemps:
257
+ row[0]=i
258
+ i+=1
259
+ #Overwrite/make new master sen ref table. Then append the Temp data with integerized values
260
+ addTBL("senRef",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],data=a,addOn=False)
261
+ addTBL("senRef",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],data=senHiLoTemps,addOn=True)
262
+ senList=viewTBL('senRef',sortBy=[('sen','ASC')])
263
+ return a,b,c,d,e,f,g,pollDict,h,senList
264
+
265
+ def dispToTrn(dispNm):
266
+ """Returns the trnNm associated with Display name for a given job. assumes popualted sqlite table 'xRef' with dispNm/trnNm pairs"""
267
+ q=viewTBL('xRef',fields=['dispNm','trnNm'],filterOn=[('dispNm',dispNm)])
268
+ if len(q)==0:
269
+ return "Custom func error 'dispToTrn' no entry found in xRef with dispNm="+str(dispNm)
270
+ return q[0][1]
271
+
272
+ def trnToDisp(trnNm):
273
+ """Returns the trnNm associated with Display name for a given job. assumes popualted sqlite table 'xRef' with dispNm/trnNm pairs"""
274
+ q=viewTBL('xRef',fields=['dispNm','trnNm'],filterOn=[('trnNm',trnNm)])
275
+ if len(q)==0:
276
+ return "Custom func error 'trnToDisp' no entry found in xRef with trnNm="+str(trnNm)
277
+ return [e[0] for e in q] #If multiple DispNms for one train name (e.g. L4 Packer -> Packer, Candling) or Bottle Supply -> etc.
278
+ #Then return list of all dispNms
279
+
280
+ def sklChk(eeid,dispNm):
281
+ """Returns True/False if eeid is trained on job with display name or not. Requires skills matrix named sklMtx in sqlite"""
282
+ trnNm=dispToTrn(dispNm)
283
+ if len(viewTBL('sklMtx',filterOn=[('EEID',eeid),('trnNm',trnNm)]))==0:
284
+ return False
285
+ else:
286
+ return True
287
+
288
+
289
+ def makeEEdict(ftInfoTbl,tempInfoTbl,wkHrs):
290
+ eeDict={}
291
+ for dtaTbl in [ftInfoTbl,tempInfoTbl]:
292
+ for row in dtaTbl:
293
+ # if row[1].lower().strip() in ['wwf','bud','blue','rock','silver','gold','student']: #Omit people not in packaging, or off, vacation etc
294
+ eeSkills=viewTBL('sklMtx',['trnNm'],filterOn=[('EEID',row[2])])
295
+ eeSkills=[trnToDisp(nm[0]) for nm in eeSkills] #Gather display names for skills trained on, reducing lists within list to spread elements
296
+ sk=[] #Create empty to accumulate all skills present within sublists of eeSkills
297
+ for s in eeSkills:
298
+ sk.extend(s)
299
+ sen=viewTBL('senRef',fields=['sen'],filterOn=[('id',str(row[2]))])[0][0]
300
+ anEE=ee(sen,row[1].lower().strip(),int(row[2]),row[3],row[4],row[5],row[8]+wkHrs,skills=sk) #Pull info from Refusals sheet
301
+ eeDict[anEE.eeID]=anEE
302
+ return eeDict
303
+
304
+ def makeSlots(eeDict,AllSlots):
305
+ openSlots={} #Open here meaning unassigned.. Will be required when it comes time to force
306
+ for row in AllSlots:
307
+ if row[6]==1: #Check that the slot generation record is labelled as 'active'
308
+ for i in range(row[0],row[1]+1): #Generate a slot for each index over the range indicated... add 1 because python Range fn not inclusive of end point
309
+ sl=Slot(i, row[2],dispToTrn(row[2]))
310
+ #Determine how many eligible volunteers for this slot
311
+ elig=[] #To track how many people trained
312
+ for rec in viewTBL('allPollData',filterOn=[('slot_'+str(sl.seqID),'y')]): # iterate through results (employee info's) of query on who said yes to working at the time of this slot
313
+ if sl.dispNm in eeDict[rec[0]].skills: elig.append(rec[0]) #Append EEID to list 'elig' if the ee is trained on the job
314
+ sl.eligVol=elig # True values as 1.. sum to see number of eligible volunteers for the slot.
315
+ openSlots[str(sl.seqID)+'_'+str(sl.dispNm)]=sl #Enter it into the dictionary
316
+ return openSlots
317
+
318
+ def preProcessData(Acrew,wkHrs,FtBook,TempBook,AssnBook,PollBook,pNT=False):
319
+ """A function to take input data and generate all necessary tables and objects in memory to carry out algorithm. Return Schedule object containing all workSlot objects, and dictioanry fo all employee objects"""
320
+ ftInfoTbl, ftSkillsMtx, tempInfoTbl, tempSkillsMtx, AssignmentsTbl, slot_Legend, JobTrnCrossRef,pollDict,AllSlots,senList=pullTbls(FtBook,TempBook,AssnBook,PollBook)
321
+ #GenerateMasterPollTbl to facilitate making the Slots... require having a table with all employee preferences.
322
+ generateMasterPollTbl(pollDict)
323
+ #Generate Worker Objects, and assign to dictionary keyed by eeID (numeric key, not string keys)
324
+ eeDict=makeEEdict(ftInfoTbl,tempInfoTbl,wkHrs)
325
+ #Generate Schedule Slot objects (all unassigned slots for weekend)
326
+ allSlots=makeSlots(eeDict,AllSlots)
327
+ return Schedule(Acrew,allSlots,eeDict,AssignmentsTbl,senList,pollDict,slot_Legend,pNT=pNT)
328
+
329
+
330
+
331
+
332
+ def pullSomeTbls(FtBook,TempBook,AssnBook,PollBook): #Need to make volunteer shift data puller
333
+ """Take flNm, return ftInfoTbl, ftSkillsMtx, tempInfoTbl, tempSkillsMtx, AssignmentsTbl, slot_Legend, JobTrnCrossRef, pollDict, All_Slots, senList. Uses functions defined previously to return all required tables at once. Function of functions for final script"""
334
+ a=getFTinfo(FtBook) #to sqlite
335
+ b=getFTskills(FtBook) #to sqlite
336
+ b=[[int(d[0]),d[1]] for d in b] #Cast EEid to numeric value
337
+ c=getTempinfo(TempBook) #to sqlite
338
+ d=getTempskills(TempBook) #to sqlite
339
+ d=[[int(data[0]),data[1]] for data in d] #Cast EEid to numeric value
340
+ e=imptXlTbl(AssnBook,'Assignment_List','Assn_List')
341
+ f=imptXlTbl(AssnBook,'Slot_Legend','Slot_Legend')
342
+ g=imptXlTbl(AssnBook,'Job_Training_Crossref','TrainAssnMtx') #to sqlite
343
+ pollDict={} #Generate empty dictionary to store tables of people voluntary overtime
344
+ for crew in ['Blue','Bud','Rock','Silver','Gold']:
345
+ for eeType in ['FT','Temp']:
346
+ keyNm='tbl_'+crew+eeType
347
+ tbl=imptXlTbl(PollBook,'Sheet1',keyNm)
348
+ pollDict[keyNm]=tbl
349
+ h=imptXlTbl(AssnBook,'All_Slots','All_Slots')
350
+ #Generate tables in sqlite
351
+ addTBL("sklMtx",fields=["EEID","trnNm"],data=b,addOn=False) #Overwrite all training data and populate FT ops, then append temps for a master table
352
+ addTBL("sklMtx",fields=["EEID","trnNm"],data=d,addOn=True)
353
+ addTBL("xRef",fields=["dispNm","trnNm"],data=g,addOn=False) #Skill name cross ref table for fcn dispToTrn to work
354
+ addTBL("FTinfo",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],data=a,addOn=False)
355
+ addTBL("TempInfo",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],data=c,addOn=False)
356
+ # addTBL("FTinfo",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],dTypes=['NUM','TEXT','NUM','TEXT','TEXT','NUM','NUM','NUM'],data=a,addOn=False)
357
+ # addTBL("TempInfo",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],dTypes=['INTEGER','TEXT','INTEGER','TEXT','TEXT','INTEGER','INTEGER','INTEGER'],data=c,addOn=False)
358
+ #Generate a master seniority table.. following replaces hire date with integers for temps
359
+ senHiLoTemps=viewTBL('TempInfo',sortBy=[('sen','ASC')]) #First retrieve list of temps, most senior to least
360
+ i=100000 #Start new seniority number at arbitrarily high value not to interfere with full timer
361
+ for row in senHiLoTemps:
362
+ row[0]=i
363
+ i+=1
364
+ #Overwrite/make new master sen ref table. Then append the Temp data with integerized values
365
+ addTBL("senRef",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],data=a,addOn=False)
366
+ addTBL("senRef",fields=['sen','crew','id','last','first','ytd','totref','totchrg','wtdOT'],data=senHiLoTemps,addOn=True)
367
+ senList=viewTBL('senRef',sortBy=[('sen','ASC')])
368
+ return a,b,c,d,e,f,g,pollDict,h,senList