def drawTBH(self): totalTBHSet = set( self.multiOrgParser.getFilteredPeople( PeopleFilter().addIsTBHFilter())) tbhLocations = set([aTBH.getLocation() for aTBH in totalTBHSet]) or [""] tbhProducts = list(set([aTBH.getProduct() for aTBH in totalTBHSet])) or [""] tbhProducts.sort(cmp=self._sortByProduct) tbhFunctions = list(set([aTBH.getFunction() for aTBH in totalTBHSet])) tbhFunctions.sort(cmp=self._sortByFunc) for aLocation in tbhLocations: title = "Hiring" # Location might not be set. if aLocation: title = "{} - {}".format(title, aLocation) chartDrawer = DrawChartSlideTBH(self.presentation, title, self.slideLayout) for aFunction in tbhFunctions: productTBHList = self.multiOrgParser.getFilteredPeople( PeopleFilter().addIsTBHFilter().addFunctionFilter( aFunction).addLocationFilter(aLocation)) productTBHList = sorted(productTBHList, self._sortByFunc, lambda tbh: tbh.getProduct()) self.buildGroup(aFunction, productTBHList, chartDrawer) chartDrawer.drawSlide()
def drawProductManger(self): productManagers = self.multiOrgParser.getFilteredPeople( PeopleFilter().addIsProductManagerFilter()) if not len(productManagers): return chartDrawer = DrawChartSlidePM(self.presentation, "Product Management", self.slideLayout) productBuckets = list( set([aPerson.getFeatureTeam() for aPerson in productManagers])) for aBucket in productBuckets: peopleList = [ aPerson for aPerson in productManagers if aPerson.getFeatureTeam() == aBucket ] # peopleList = sorted(peopleList, key=lambda x: x.getProduct(), cmp=self._sortByProduct) peopleList.sort() # Set default name for PM who don't have 'feature team' set # If default name isn't set, these people are accidentally filtered out in the # buildGroup function if not aBucket: aBucket = orgchart_parser.NOT_SET self.buildGroup(aBucket, peopleList, chartDrawer) # peopleProducts = list(set([aPerson.getProduct() for aPerson in productManagers])) # for aProduct in peopleProducts: # self.buildGroup(aProduct, [aPerson for aPerson in productManagers if aPerson.getProduct() == aProduct], chartDrawer) chartDrawer.drawSlide()
def _getDirects(self, aManager, location=None): """ :type aManager: str :return: """ peopleFilter = PeopleFilter() directReports = [] peopleFilter.addManagerFilter(aManager) peopleFilter.addIsTBHFilter(False) if location: peopleFilter.addLocationFilter(location) directReports.extend( self.multiOrgParser.getFilteredPeople(peopleFilter)) return directReports
def drawCrossFunc(self): crossFuncPeople = self.multiOrgParser.getCrossFuncPeople() if not len(crossFuncPeople): return chartDrawer = DrawChartSlide(self.presentation, "Cross Functional", self.slideLayout) functions = list( set([aPerson.getFunction() for aPerson in crossFuncPeople])) functions.sort(cmp=self._sortByFunc) for aFunction in functions: peopleFilter = PeopleFilter() peopleFilter.addFunctionFilter(aFunction) peopleFilter.addIsCrossFuncFilter() peopleFilter.addIsExpatFilter(False) peopleFilter.addIsInternFilter(False) funcPeople = self.multiOrgParser.getFilteredPeople(peopleFilter) self.buildGroup(aFunction, funcPeople, chartDrawer) chartDrawer.drawSlide()
def drawCrossFunc(self): crossFuncPeople = self.multiOrgParser.getCrossFuncPeople() if not len(crossFuncPeople): return chartDrawer = DrawChartSlide(self.presentation, "Cross Functional", self.slideLayout) functions = list(set([aPerson.getFunction() for aPerson in crossFuncPeople])) functions.sort(cmp=self._sortByFunc) for aFunction in functions: peopleFilter = PeopleFilter() peopleFilter.addFunctionFilter(aFunction) peopleFilter.addIsCrossFuncFilter() peopleFilter.addIsExpatFilter(False) peopleFilter.addIsInternFilter(False) funcPeople = self.multiOrgParser.getFilteredPeople(peopleFilter) self.buildGroup(aFunction, funcPeople, chartDrawer) chartDrawer.drawSlide()
def drawAllProducts(self, drawFeatureTeams, drawLocations, drawExpatsInTeam): #Get all the products except the ones where a PM is the only member people = self.multiOrgParser.getFilteredPeople( PeopleFilter().addIsProductManagerFilter(False)) productList = list(set([aPerson.getProduct() for aPerson in people])) for aCrossFuncTeam in self.multiOrgParser.getCrossFuncTeams(): for aProductName in productList[:]: if aProductName.lower() == aCrossFuncTeam.lower(): productList.remove(aProductName) productList.sort(cmp=self._sortByProduct) for aProductName in productList: self.drawProduct(aProductName, drawFeatureTeams, drawLocations, drawExpatsInTeam)
def _getDirects(self, aManager, location=None): """ :type aManager: str :return: """ peopleFilter = PeopleFilter() directReports = [] peopleFilter.addManagerFilter(aManager) peopleFilter.addIsTBHFilter(False) if location: peopleFilter.addLocationFilter(location) directReports.extend(self.multiOrgParser.getFilteredPeople(peopleFilter)) return directReports
def drawAdmin(self): # Populate the manager list with managers who are entered in the spreadsheet so it's easier to match them # to the appropriate floor and identify them as 1 person even if they are entered in different ways in the # Manager column (Ben/Benjamin) managerSet = set( self.multiOrgParser.getFilteredPeople( PeopleFilter().addIsManagerFilter())) # Get all the entries in the manager column but remove entries that start with "_" as they are excluded intentionally allManagers = set([ SkeletonPerson(aManagerName) for aManagerName in self.multiOrgParser.getManagerSet() if (not aManagerName.startswith("_")) and "TBD" not in aManagerName ]) print "Info: Managers not entered as rows: {}".format( managerSet.difference(allManagers)) # Prefer Person type over SkeletonPerson type as it is more full featured - floors work better mergedManagerList = managerSet.union(allManagers) #pprint.pprint("Managers: {}".format(mergedManagerList)) managerEmployeeDict = {} for aManager in mergedManagerList: managerEmployeeDict[aManager] = self._getDirects(aManager) # A manager can have reports on more than one floor managersByFloor = {} for aManager in mergedManagerList: floors = aManager.getFloors() for floor in floors: if not floor in managersByFloor: managersByFloor[floor] = set() managersByFloor[floor].add(aManager) # Location: There can be people across locations reporting to the same manager: # Example: People report to Arno in Santa Clara and in Milan. # There will be a single slide for each unique location. Only direct reports in the specified location will be # drawn for aLocation in self.multiOrgParser.getLocationSet(): locationName = aLocation or self.multiOrgParser.getOrgName() # Floor: The floor (or other grouping) that separates manager. # Example: There are a lot of managers in Waltham so we break them up across floors # NOTE: All of the direct reports in the location will be drawn # Example: If Dave is on floor1 and floor2 in Waltham, then the same direct reports will be drawn both times sortedFloors = list(managersByFloor.keys()) sortedFloors.sort(cmp=self._sortByFloor) maxManagersPerSlide = 7 managersOnSlide = 0 partNum = 2 slideNameAddendum = "pt {}".format(partNum) for aFloor in sortedFloors: managerList = managersByFloor[aFloor] chartDrawer = DrawChartSlideAdmin( self.presentation, "{} Admin {}".format(locationName, aFloor), self.slideLayout) managerList = list(managerList) managerList.sort() for aManager in managerList: directReports = [] for aPerson in managerEmployeeDict[aManager][:]: if aPerson.getLocation() == aLocation: directReports.append(aPerson) #print "TODO: Removing - {}".format(aPerson) managerEmployeeDict[aManager].remove(aPerson) #print "TODO : Removed" #directReports.extend([aPerson for aPerson in managerEmployeeDict[aManager] if aPerson.getLocation() == aLocation]) # directReports.extend(self._getDirects(aManager, aLocation)) if not directReports: continue self.buildGroup(aManager.getPreferredName(), directReports, chartDrawer) managersOnSlide += 1 # Split the slide into multiple parts if it's getting too crowded if managersOnSlide >= maxManagersPerSlide: managersOnSlide = 0 chartDrawer.drawSlide() chartDrawer = DrawChartSlideAdmin( self.presentation, "{} Admin {}{}".format(locationName, aFloor, slideNameAddendum), self.slideLayout) partNum += 1 slideNameAddendum = "pt {}".format(partNum) # Keep track of whether this floor has any people so that we avoid spamming "WARNING" messages because # a slide is being drawn that's empty if managersOnSlide > 0: chartDrawer.drawSlide() managersOnSlide = 0 emptyManagerPeopleFilter = (PeopleFilter().addManagerEmptyFilter( ).addIsTBHFilter(False).addLocationFilter(locationName)) peopleMissingManager = (self.multiOrgParser.getFilteredPeople( emptyManagerPeopleFilter)) if peopleMissingManager: #Draw people who are missing a manager on their own slide chartDrawer = DrawChartSlideAdmin( self.presentation, "{} Missing Admin Manager".format(locationName), self.slideLayout) self.buildGroup("Chuck Norris", peopleMissingManager, chartDrawer) chartDrawer.drawSlide()
def drawProduct(self, productName, drawFeatureTeams=False, drawLocations=False, drawExpatsInTeam=True): """ :type productName: str """ if not productName: if not self.draftMode: return featureTeamList = [""] if drawFeatureTeams: featureTeamList = list( self.multiOrgParser.getFeatureTeamSet(productName)) functionList = list(self.multiOrgParser.getFunctionSet(productName)) functionList.sort(cmp=self._sortByFunc) teamModelText = None locations = [""] # If draw locations has been set (could still be an empty list) then break the chart up by locations. # if locations is set and isn't an empty list, only show the locations specified. if drawLocations is not None: locations = self.multiOrgParser.getLocationSet(productName) for drawLocation in drawLocations: if drawLocation not in locations: raise ValueError( "{} is not found in available locations: {}".format( drawLocations, locations)) for aLocation in drawLocations or locations: locationName = aLocation.strip() or self.multiOrgParser.getOrgName( ) for aFeatureTeam in featureTeamList: if not productName: slideTitle = orgchart_parser.NOT_SET elif drawFeatureTeams: teamName = "- {} ".format(aFeatureTeam) if not aFeatureTeam: if len(featureTeamList) > 1: teamName = "- Cross " else: teamName = "" slideTitle = "{} {}Feature Team".format( productName, teamName) else: slideTitle = "{}".format(productName) modelDict = self.multiOrgParser.getTeamModel() if productName in modelDict: teamModelText = modelDict[productName] chartDrawer = DrawChartSlide(self.presentation, slideTitle, self.slideLayout, teamModelText) if len(locations) > 1 and aLocation: chartDrawer.setLocation(locationName) for aFunction in functionList: if aFunction.lower( ) in self.multiOrgParser.getCrossFunctions(): continue peopleFilter = PeopleFilter() peopleFilter.addProductFilter(productName) peopleFilter.addFunctionFilter(aFunction) if drawLocations is not None: peopleFilter.addLocationFilter(aLocation) if drawFeatureTeams: peopleFilter.addFeatureTeamFilter(aFeatureTeam) else: if not drawExpatsInTeam: peopleFilter.addIsExpatFilter(False) peopleFilter.addIsInternFilter(False) # peopleFilter.addIsProductManagerFilter(False) functionPeople = self.multiOrgParser.getFilteredPeople( peopleFilter) self.buildGroup(aFunction, functionPeople, chartDrawer) chartDrawer.drawSlide()
def drawIntern(self): interns = self.multiOrgParser.getFilteredPeople( PeopleFilter().addIsInternFilter()) self._drawMiscGroups("Intern", interns)
def drawExpat(self): expats = self.multiOrgParser.getFilteredPeople( PeopleFilter().addIsExpatFilter()) #.addIsProductManagerFilter(False)) self._drawMiscGroups("ExPat", expats)
def drawProduct(self, productName, drawFeatureTeams=False, drawLocations=False, drawExpatsInTeam=True): """ :type productName: str """ if not productName: if not self.draftMode: return featureTeamList = [""] if drawFeatureTeams: featureTeamList = list(self.multiOrgParser.getFeatureTeamSet(productName)) functionList = list(self.multiOrgParser.getFunctionSet(productName)) functionList.sort(cmp=self._sortByFunc) teamModelText = None locations = [""] # If draw locations has been set (could still be an empty list) then break the chart up by locations. # if locations is set and isn't an empty list, only show the locations specified. if drawLocations is not None: locations = self.multiOrgParser.getLocationSet(productName) for drawLocation in drawLocations: if drawLocation not in locations: raise ValueError("{} is not found in available locations: {}".format(drawLocations, locations)) for aLocation in drawLocations or locations: locationName = aLocation.strip() or self.multiOrgParser.getOrgName() for aFeatureTeam in featureTeamList: if not productName: slideTitle = orgchart_parser.NOT_SET elif drawFeatureTeams: teamName = "- {} ".format(aFeatureTeam) if not aFeatureTeam: if len(featureTeamList) > 1: teamName = "- Cross " else: teamName = "" slideTitle = "{} {}Feature Team".format(productName, teamName) else: slideTitle = "{}".format(productName) modelDict = self.multiOrgParser.getTeamModel() if productName in modelDict: teamModelText = modelDict[productName] chartDrawer = DrawChartSlide(self.presentation, slideTitle, self.slideLayout, teamModelText) if len(locations) > 1 and aLocation: chartDrawer.setLocation(locationName) for aFunction in functionList: if aFunction.lower() in self.multiOrgParser.getCrossFunctions(): continue peopleFilter = PeopleFilter() peopleFilter.addProductFilter(productName) peopleFilter.addFunctionFilter(aFunction) if drawLocations is not None: peopleFilter.addLocationFilter(aLocation) if drawFeatureTeams: peopleFilter.addFeatureTeamFilter(aFeatureTeam) else: if not drawExpatsInTeam: peopleFilter.addIsExpatFilter(False) peopleFilter.addIsInternFilter(False) # peopleFilter.addIsProductManagerFilter(False) functionPeople = self.multiOrgParser.getFilteredPeople(peopleFilter) self.buildGroup(aFunction, functionPeople, chartDrawer) chartDrawer.drawSlide()