def onSchedule(self, evt): self.scheduledInput = self.selectedScheduleInput self.startDateInput.SetValue(TimeUtil.getMonday(self.startDateInput.GetValue())) self.endDateInput.SetValue(TimeUtil.getSunday(self.endDateInput.GetValue())) self.scheduledStartDate = self.startDateInput.GetValue() if not self.checkInput(): return self.resultList = list() for input in self.scheduledInput: scheduledWorkers = input[0] scheduledGroup = input[1] # 现在将工作和休息互换,算法不变 s = Scheduler(workers=list(range(len(scheduledWorkers))), dailyRequiredWorkerNum=len(scheduledWorkers) - int(scheduledGroup.workLoad), maxRestDay=self.maxWorkDaysInput.GetValue(), maxWorkDay=self.maxRestDaysInput.GetValue(), isShuffle=True) targetDays = TimeUtil.getDayLength(self.startDateInput.GetValue(), self.endDateInput.GetValue()) scheduleResult = s.schedule(int(targetDays)) if scheduleResult.message.strip() != '': wx.MessageBox(scheduledGroup.groupName + ": " + scheduleResult.message) self.resultList.append([scheduleResult.restCalendar, scheduledWorkers, scheduledGroup]) self.displayScheduleResult(self.resultList, self.scheduledStartDate) self.exportBtn.Enable(True) self.saveBtn.Enable(True) self.selectedScheduleInput = list()
def onExport(self, evt): dialog = wx.FileDialog(self, u"选择要导出的文件位置", os.getcwd(), style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT, wildcard="*.csv") if dialog.ShowModal() == wx.ID_OK: filePath = dialog.GetPath() if filePath: try: personalWorkDayDict = self.exportData[0] dailyAttendenceList = self.exportData[1] personalWorkDayLengthList = self.exportData[2] startDate = self.exportData[3] firstLine = u'员工名,班组名' totalWeekNum = int(len(dailyAttendenceList) / 7) for totalWeekNum in range(1, totalWeekNum + 1): dateStr = u',"第 ' + str(totalWeekNum) + u' 周\n' endDate = TimeUtil.getFormatedDate(startDate, 6) dateStr += (startDate + ' -- ' + endDate + '"') firstLine += dateStr startDate = TimeUtil.getFormatedDate(endDate, 1) lines = [firstLine] for item in personalWorkDayDict: wokerName = item[0] groupName = item[1] workDayList = item[2] lines.append(wokerName + ',' + groupName + u',' + u','.join( list(map(lambda week: ' '.join(list(map(str, week))), workDayList)))) lines.append('\n') lines.append(u'员工名,班组名,总天数,总工时(小时)') # 工时 for i in range(len(personalWorkDayLengthList)): lines.append(','.join(personalWorkDayLengthList[i])) lines.append('\n') lines.append(u'日期,出勤员工') groupInfo = ',' + ''.join(list(map(lambda x: x[1].groupName + ',' * int(x[1].workLoad), dailyAttendenceList[0][1]))) innerLines = list() for dailyAttendence in dailyAttendenceList: date = dailyAttendence[0] groupAttendenceList = dailyAttendence[1] attendenceStr = date for groupAttendence in groupAttendenceList: attendence = groupAttendence[0] attendenceStr += ',' + attendence innerLines.append(attendenceStr) lines.append(groupInfo) lines.extend(innerLines) FileUtil.writeAll(filePath, lines) wx.MessageBox(u'成功导出到文件', filePath) except Exception as e: wx.MessageBox(u'导出失败,原因为: ' + str(e)) dialog.Destroy()
def OnEnterDate(self, evt): if TimeUtil.isValidDate(self.startDateInput.GetValue()) \ and TimeUtil.isValidDate(self.endDateInput.GetValue()) \ and TimeUtil.getDayLength(self.startDateInput.GetValue(), self.endDateInput.GetValue()) > 0: self.warnMsg.Hide() self.scheduleBtn.Enable(True) else: self.warnMsg.Show() # re-layout self.vBox.Layout() self.scheduleBtn.Enable(False)
def onFileRead(self, filePath): if filePath: try: lines = DailyDataDAL.readAll(filePath) dailyData = DailyDataDAL.parse(lines, TimeUtil.getToday()) DailyDataDAL.persistAll(dailyData) newDailyData = DailyDataDAL.fetchAllByDate(TimeUtil.getToday()) self.buyerPanel.updateGrid(newDailyData.toStringList()) wx.MessageBox("导入数据成功", "导入数据", style=wx.OK | wx.ICON_EXCLAMATION) except: wx.MessageBox("导入数据失败,请检测数据格式", "导入数据", style=wx.OK | wx.ICON_EXCLAMATION)
def setupDateInput(self): sizer = wx.GridBagSizer(4, 4) dateText = wx.StaticText(self, label='日期') sizer.Add(dateText, pos=(0, 0), flag=wx.EXPAND | wx.TOP | wx.LEFT, border=15) self.dateInput = wx.TextCtrl(self, value=TimeUtil.getToday(), style=wx.TE_PROCESS_ENTER) self.Bind(wx.EVT_TEXT_ENTER, self.onSearchDate, self.dateInput) sizer.Add(self.dateInput, pos=(0, 1), flag=wx.TOP | wx.LEFT, border=12) self.calculateButton = wx.Button(self, label='计算一天战况', size=(100, 30)) sizer.Add(self.calculateButton, pos=(0, 2), flag=wx.EXPAND | wx.TOP | wx.LEFT, border=12) self.calculateButton.Enable(True) self.Bind(wx.EVT_TEXT, self.OnEnter, self.dateInput) self.Bind(wx.EVT_BUTTON, self.onSearchDate, self.calculateButton) self.warnMsg = wx.StaticText(self, label='非法日期,请重新输入') self.warnMsg.SetForegroundColour('red') sizer.Add(self.warnMsg, pos=(0, 3), flag=wx.TOP | wx.LEFT, border=15) self.warnMsg.Hide() scoreText = wx.StaticText(self, label='盈亏') sizer.Add(scoreText, pos=(1, 0), flag=wx.EXPAND | wx.TOP | wx.LEFT, border=15) self.score = wx.StaticText(self, label='0') sizer.Add(self.score, pos=(1, 1), flag=wx.EXPAND | wx.TOP | wx.LEFT, border=15) self.vBox.Add(sizer, flag=wx.ALIGN_TOP, border=10)
def displayTodayData(self): sizer = wx.GridBagSizer(4, 4) today = TimeUtil.getToday() # Load buyer data dailyData = DailyDataDAL.fetchAllByDate(today) # set data into data grid self.data = UserGridData() self.data.InsertRows(dailyData.toStringList()) self.grid = wx.grid.Grid(self, size=(500, 300)) self.grid.SetTable(self.data) self.grid.AutoSize() sizer.Add(self.grid, pos=(1, 1), span=(3, 3), flag=wx.EXPAND | wx.TOP, border=5) searchText = wx.StaticText(self, label='名称') sizer.Add(searchText, pos=(4, 1), flag=wx.EXPAND, border=5) self.searchInput = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER) self.Bind(wx.EVT_TEXT_ENTER, self.onSearchName, self.searchInput) sizer.Add(self.searchInput, pos=(4, 2), flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5) self.searchBtn = wx.Button(self, label='查找', size=(100, 20)) sizer.Add(self.searchBtn, pos=(4, 3)) self.searchBtn.Enable(True) self.Bind(wx.EVT_BUTTON, self.onSearchName, self.searchBtn) sizer.AddGrowableRow(1) self.vBox.Add(sizer, wx.ALIGN_BOTTOM, 10)
def displayScheduleResult(self, resultList, startDate): personalWorkDayDict = list() personalWorkDayLengthList = list() dailyAttendenceDict = dict() for result in resultList: calendar = result[0] workers = result[1] group = result[2] try: workdayDict = Scheduler.getWorkDayForEachWorker(calendar, workers) for (workIndex, workDayList) in workdayDict.items(): workDayList = list(map(int, workDayList)) workDayList.sort() weeklyWorkDayList = list() week = 1 startIndex = 0 for dateIndex in range(len(workDayList)): if int(workDayList[dateIndex]) > week * 7: weeklyWorkDayList.append( list( map(lambda date: date % 7 if date % 7 != 0 else 7, workDayList[startIndex: dateIndex]))) startIndex = dateIndex week += 1 if startIndex < len(workDayList): weeklyWorkDayList.append( list(map(lambda date: date % 7 if date % 7 != 0 else 7, workDayList[startIndex: len(workDayList)]))) personalWorkDayDict.append([workers[workIndex], group.groupName, weeklyWorkDayList]) personalTotalWorkDay = Scheduler.calculateWorkDayPerWorker(calendar) for i in range(len(workers)): personalWorkDayLengthList.append( [workers[i], group.groupName, str(personalTotalWorkDay.get(i, 0)), str(personalTotalWorkDay.get(i, 0) * int(group.workHour))]) # # 添加平均数行 # avgWorkDayNum = math.ceil(float(len(calendar.keys())) * int( # group.workLoad) / len( # workers)) # avgWorkHour = avgWorkDayNum * int(group.workHour) # workDayData.append([u'平均出勤天数', str(avgWorkDayNum), str(avgWorkHour)]) for keyValuePair in sorted(calendar.items(), key=lambda d: int(d[0])): currentDate = TimeUtil.getFormatedDate(startDate, int(keyValuePair[0]) - 1) currentDateArrange = dailyAttendenceDict.get(currentDate, list()) currentDateArrange.append( [", ".join(map(str, map(lambda index: workers[index], keyValuePair[1]))), group]) dailyAttendenceDict[currentDate] = currentDateArrange except Exception as e: wx.MessageBox(u'出错啦: ' + str(e)) # 按日期排序 dailyAttendenceList = sorted(dailyAttendenceDict.items(), key=lambda d: d[0]) self.exportData = [personalWorkDayDict, dailyAttendenceList, personalWorkDayLengthList, startDate] self.updateGrid(personalWorkDayLengthList) self.updateGrid1(personalWorkDayDict, startDate) self.updateGrid2(dailyAttendenceList)
def OnEnter(self, evt): if TimeUtil.isValidDate(self.dateInput.GetValue()): self.warnMsg.Hide() self.calculateButton.Enable(True) else: self.warnMsg.Show() # re-layout self.vBox.Layout() self.calculateButton.Enable(False)
def updateGrid1(self, rows, startDate): self.grid1.ClearGrid() currentRowNum = self.grid1.GetNumberRows() if currentRowNum < len(rows): self.grid1.AppendRows(numRows=(len(rows) - currentRowNum)) elif currentRowNum > len(rows): self.grid1.DeleteRows(numRows=(currentRowNum - len(rows))) totalWeekNum = len(rows[0][2]) if len(rows) > 0 else 0 currentColNum = self.grid1.GetNumberCols() - 2 if currentColNum < totalWeekNum: self.grid1.AppendCols(numCols=(totalWeekNum - currentColNum)) elif currentColNum > totalWeekNum: self.grid1.DeleteCols(numCols=(currentColNum - totalWeekNum)) for totalWeekNum in range(1, totalWeekNum + 1): dateStr = u'第 ' + str(totalWeekNum) + u' 周\n' endDate = TimeUtil.getFormatedDate(startDate, 6) dateStr += (startDate + ' -- ' + endDate) self.grid1.SetColLabelValue(totalWeekNum + 1, dateStr) startDate = TimeUtil.getFormatedDate(endDate, 1) rowNum = 0 previousGroupName = '' colorCnt = 0 for item in rows: wokerName = item[0] groupName = item[1] workDayList = item[2] if groupName != previousGroupName: colorCnt += 1 previousGroupName = groupName self.grid1.SetCellValue(rowNum, 0, wokerName) self.grid1.SetCellValue(rowNum, 1, groupName) self.grid1.SetCellBackgroundColour(rowNum, 0, self.colorList[colorCnt % 2]) self.grid1.SetCellBackgroundColour(rowNum, 1, self.colorList[colorCnt % 2]) for weekNum in range(len(workDayList)): self.grid1.SetCellValue(rowNum, weekNum + 2, ', '.join(list(map(str, workDayList[weekNum])))) self.grid1.SetCellBackgroundColour(rowNum, weekNum + 2, self.colorList[colorCnt % 2]) rowNum += 1 self.grid1.AutoSize() self.vBox.Layout()
def __init__(self, parent): scrolled.ScrolledPanel.__init__(self, parent) self.selectedScheduleInput = list() self.scheduledInput = list() self.scheduledStartDate = TimeUtil.getToday() self.exportData = list() self.displayWeeklyReport = True self.initUI() self.Show(True)
def validate(): if Constants.LICENSE_PURCHASED: return True conn = sqlite3.connect(Constants.DATABASE_ROOT_PATH + LicenseValidateUtil.LICENSE_TABLE_NAME + '.db') c = conn.cursor() c.execute("CREATE TABLE IF NOT EXISTS " + LicenseValidateUtil.LICENSE_TABLE_NAME + "(startDate VARCHAR[10], version VARCHAR[10])") c.execute("SELECT startDate FROM " + LicenseValidateUtil.LICENSE_TABLE_NAME + " WHERE version=" + Constants.APPLICATION_VERSION) startDate = c.fetchone() if startDate == None: c.execute("INSERT INTO " + LicenseValidateUtil.LICENSE_TABLE_NAME + " VALUES ('" + TimeUtil.getToday() + "','" + Constants.APPLICATION_VERSION + "')") conn.commit() conn.close() return True else: conn.close() return TimeUtil.getDayLength(startDate[0], TimeUtil.getToday()) < Constants.MAX_FREE_TRIAL_DAY
def setupDateInput(self): optionSizer = wx.GridBagSizer(4, 4) optionOuterSizer = wx.StaticBoxSizer(wx.HORIZONTAL, self, label=u'选项') userGroupText = wx.StaticText(self, label=u'排班班组') optionSizer.Add(userGroupText, pos=(0, 0), flag=wx.EXPAND | wx.TOP | wx.LEFT, border=15) self.userGroupDropDown = wx.ListBox(self, style=wx.LB_MULTIPLE, choices=self.loadGroupList(), size=(100, 50)) self.userGroupDropDown.Bind(wx.EVT_LISTBOX, self.onSelection) optionSizer.Add(self.userGroupDropDown, pos=(0, 1), flag=wx.EXPAND | wx.TOP | wx.LEFT, border=15) minWorkDays = wx.StaticText(self, label=u'最大连续休息天数') optionSizer.Add(minWorkDays, pos=(1, 0), flag=wx.EXPAND | wx.TOP | wx.LEFT, border=15) self.maxRestDaysInput = wx.TextCtrl(self, value='3', style=wx.TE_PROCESS_ENTER) optionSizer.Add(self.maxRestDaysInput, pos=(1, 1), flag=wx.TOP | wx.LEFT, border=12) maxWorkDaysText = wx.StaticText(self, label=u'最大连续工作天数') optionSizer.Add(maxWorkDaysText, pos=(1, 2), flag=wx.EXPAND | wx.TOP | wx.LEFT, border=15) self.maxWorkDaysInput = wx.TextCtrl(self, value='6', style=wx.TE_PROCESS_ENTER) optionSizer.Add(self.maxWorkDaysInput, pos=(1, 3), flag=wx.TOP | wx.LEFT, border=12) startDate = wx.StaticText(self, label=u'开始日期') optionSizer.Add(startDate, pos=(2, 0), flag=wx.EXPAND | wx.TOP | wx.LEFT, border=15) self.startDateInput = wx.TextCtrl(self, value=TimeUtil.getMonday(TimeUtil.getToday()), style=wx.TE_PROCESS_ENTER) self.Bind(wx.EVT_TEXT, self.OnEnterDate, self.startDateInput) optionSizer.Add(self.startDateInput, pos=(2, 1), flag=wx.TOP | wx.LEFT, border=12) endDate = wx.StaticText(self, label=u'结束日期') optionSizer.Add(endDate, pos=(2, 2), flag=wx.EXPAND | wx.TOP | wx.LEFT, border=15) self.endDateInput = wx.TextCtrl(self, value=TimeUtil.getSunday( TimeUtil.getFormatedDate(self.startDateInput.GetValue(), 55)), style=wx.TE_PROCESS_ENTER) self.Bind(wx.EVT_TEXT, self.OnEnterDate, self.endDateInput) optionSizer.Add(self.endDateInput, pos=(2, 3), flag=wx.TOP | wx.LEFT, border=12) blankMsg = wx.StaticText(self, label=u' ') optionSizer.Add(blankMsg, pos=(3, 0), flag=wx.TOP | wx.LEFT, border=15) self.warnMsg = wx.StaticText(self, label=u'非法日期,请重新输入') self.warnMsg.SetForegroundColour('red') optionSizer.Add(self.warnMsg, pos=(3, 1), span=(1, 3), flag=wx.TOP | wx.LEFT, border=15) self.warnMsg.Hide() optionOuterSizer.Add(optionSizer) fontBtn = wx.Font(13, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.FONTWEIGHT_BOLD) btnOuterSizer = wx.StaticBoxSizer(wx.VERTICAL, self, u'操作') btnSizer = wx.GridBagSizer(4, 4) self.scheduleBtn = wx.Button(self, label=u'开始\n排班', size=(80, 66)) self.scheduleBtn.SetFont(fontBtn) btnSizer.Add(self.scheduleBtn, pos=(0, 0), flag=wx.LEFT | wx.RIGHT, border=12) self.scheduleBtn.Enable(False) self.Bind(wx.EVT_BUTTON, self.onSchedule, self.scheduleBtn) self.exportBtn = wx.Button(self, label=u'导出\n排班', size=(80, 66)) self.exportBtn.SetFont(fontBtn) btnSizer.Add(self.exportBtn, pos=(1, 0), flag=wx.BOTTOM | wx.LEFT | wx.RIGHT, border=12) self.exportBtn.Enable(False) self.Bind(wx.EVT_BUTTON, self.onExport, self.exportBtn) self.convertDisplayBtn = wx.Button(self, label=u'切换\n排班\n格式', size=(80, 66)) self.convertDisplayBtn.SetFont(fontBtn) btnSizer.Add(self.convertDisplayBtn, pos=(0, 2), span=(0, 1), flag=wx.BOTTOM | wx.LEFT | wx.RIGHT, border=12) self.Bind(wx.EVT_BUTTON, self.onConvertDisplay, self.convertDisplayBtn) self.saveBtn = wx.Button(self, label=u'保存\n排班', size=(80, 66)) self.saveBtn.SetFont(fontBtn) btnSizer.Add(self.saveBtn, pos=(0, 1), flag=wx.BOTTOM | wx.LEFT | wx.RIGHT, border=12) self.saveBtn.Enable(False) self.Bind(wx.EVT_BUTTON, self.onSaveCalendar, self.saveBtn) self.loadBtn = wx.Button(self, label=u'加载\n排班', size=(80, 66)) self.loadBtn.SetFont(fontBtn) btnSizer.Add(self.loadBtn, pos=(1, 1), flag=wx.BOTTOM | wx.LEFT | wx.RIGHT, border=12) self.Bind(wx.EVT_BUTTON, self.onLoadCalendar, self.loadBtn) self.deleteBtn = wx.Button(self, label=u'删除\n排班', size=(80, 66)) self.deleteBtn.SetFont(fontBtn) btnSizer.Add(self.deleteBtn, pos=(1, 2), flag=wx.BOTTOM | wx.LEFT | wx.RIGHT, border=12) self.Bind(wx.EVT_BUTTON, self.onDeleteCalendar, self.deleteBtn) btnOuterSizer.Add(btnSizer) outerSizer = wx.BoxSizer(orient=wx.HORIZONTAL) outerSizer.Add(optionOuterSizer) outerSizer.AddSpacer(15) outerSizer.Add(btnOuterSizer) self.vBox.Add(outerSizer, wx.ALIGN_TOP | wx.ALIGN_LEFT, 10)