def roster_users_submit(request, roster): try: roster = Roster.objects.get(name=roster) except Roster.DoesNotExist: return notification( request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if roster.state > 0: return notification( request, 'Dit rooster is geblokkeerd omdat uren al verdeeld worden of zijn') RosterWorker.objects.filter(roster=roster).delete() hours = {} for key in request.POST.keys(): if key[0:6] == 'extra_': upk = int(key[6:]) try: hours[upk] = float(request.POST[key]) except ValueError: pass if key[0:5] == 'user_': user = get_user_model().objects.get(pk=int(key[5:])) RosterWorker(user=user, roster=roster).save() for upk, extra in hours.items(): user = get_user_model().objects.get(pk=upk) rosteruser = RosterWorker.objects.filter(user=user, roster=roster) if rosteruser: rosteruser[0].extra = extra rosteruser[0].save() return redirect(to=reverse('roster_users', kwargs={'roster': roster.name}))
def assignment_submit_staff(request, assignment): assignment = Assignment.objects.get(pk = int(assignment)) if not request.user.is_staff: return notification(request, 'Alleen beheerders mogen dit doen') if 'action' in request.POST.keys(): if request.POST['action'] == 'transfer': users = [worker.user for worker in RosterWorker.objects.filter(roster = assignment.timeslot.roster).all()] return render(request, 'gift_select_user.html', { 'assignment': assignment, 'slot': assignment.timeslot, 'roster': assignment.timeslot.roster, 'users': users, 'staff': 1, }) elif request.POST['action'] == 'terminate': timeslot = assignment.timeslot if timeslot.degeneracy <= 1: roster_name = timeslot.roster.name timeslot.delete() return redirect(to = reverse('final_roster', kwargs = {'roster': roster_name, 'year': timeslot.year(), 'week': timeslot.week()})) else: assignment.delete() timeslot.degeneracy -= 1 timeslot.save() else: return notification(request, 'Action not recognized') return redirect(to = reverse('slot_info', kwargs = {'slot': assignment.timeslot.pk})) else: return notification(request, 'Form not recognized')
def availability_submit(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if not roster.state == 1: return notification(request, 'Je kunt nog niet, of niet meer, je beschikbaarheid doorgeven') if not RosterWorker.objects.filter(roster = roster, user = request.user): return notification(request, 'Je bent niet uitgenodigd voor dit rooster') if request.POST['shifts']: shift_pks = map(int, request.POST['shifts'].split(';')) else: shift_pks = [] year = int(request.POST['year']) week = int(request.POST['week']) monday = week_start_date(year, week) day = datetime.timedelta(days = 1) weekslots = TimeSlot.objects.filter(roster = roster, start__gt = monday, end__lt = monday + 7 * day) Availability.objects.filter(user = request.user, timeslot__pk__in = map(lambda sl: sl.pk, weekslots)).delete() for shift_pk in shift_pks: shift = TimeSlot.objects.get(pk = shift_pk) Availability(user = request.user, timeslot = shift).save() return redirect(to = reverse('availability', kwargs = {'roster': roster.name, 'year': year, 'week': week}))
def roster_users_submit(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if roster.state > 0: return notification(request, 'Dit rooster is geblokkeerd omdat uren al verdeeld worden of zijn') RosterWorker.objects.filter(roster = roster).delete() hours = {} for key in request.POST.keys(): if key[0:6] == 'extra_': upk = int(key[6:]) try: hours[upk] = float(request.POST[key]) except ValueError: pass if key[0:5] == 'user_': user = get_user_model().objects.get(pk = int(key[5:])) RosterWorker(user = user, roster = roster).save() for upk, extra in hours.items(): user = get_user_model().objects.get(pk = upk) rosteruser = RosterWorker.objects.filter(user = user, roster = roster) if rosteruser: rosteruser[0].extra = extra rosteruser[0].save() return redirect(to = reverse('roster_users', kwargs = {'roster': roster.name}))
def invite_workers(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if roster.state > 1: return notification(request, 'Je kunt nog niet, of niet langer, mensen uitnodigen') workers = RosterWorker.objects.filter(roster = roster) if not workers: return notification(request, 'Voeg een of meer werkers toe') else: roster.state = 1 roster.save() for worker in workers: availabilities = filter(lambda av: av.roster == roster, Availability.objects.filter(user = worker.user)) if availabilities: worker.hours_entered = to_hours(reduce(lambda d1, d2: d1 + d2, map(lambda av: av.timeslot.duration, availabilities))) else: worker.hours_entered = 0 base_url = 'http://' + request.META['HTTP_HOST'] timedelta_total = roster.total_work_time hours_total = timedelta_total.days * 24 + timedelta_total.seconds / 3600 return render(request, 'invite_workers.html', { 'hours_total': hours_total, 'hours_pp': round(hours_total / len(workers), 1), 'roster': roster, 'workers': workers, 'base_url': base_url, })
def roster_users(request, roster): try: roster = Roster.objects.get(name=roster) except Roster.DoesNotExist: return notification( request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if roster.state > 0: return notification( request, 'Dit rooster is geblokkeerd omdat uren al verdeeld worden of zijn') users = get_user_model().objects.all() active_user_pks = map(lambda rw: rw.user.pk, RosterWorker.objects.filter(roster=roster)) for user in users: if user.pk in active_user_pks: user.working = True user.extra = RosterWorker.objects.get(user=user, roster=roster).extra else: user.working = False user.extra = 0.0 return render(request, 'add_users.html', { 'users': users, 'roster': roster, })
def change_password(request): if not request.POST['new_password'] == request.POST['repeat_password']: return notification(request, 'De opgegeven nieuwe wachtwoorden zijn niet gelijk', next_page = reverse('change_password')) if not request.user.check_password(request.POST['current_password']): return notification(request, 'Dit is niet je huidige wachtwoord', next_page = reverse('change_password')) request.user.set_password(request.POST['new_password']) request.user.save() return notification(request, 'Je wachtwoord is veranderd', next_page = reverse('home'))
def calculate_restart(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if not roster.state == 2: return notification(request, 'Je kan niet herstarten als er geen berekening bezig is') roster.state = 1 roster.save() return redirect(to = reverse('invite_workers', kwargs = {'roster': roster.name}))
def roster_lock(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if roster.state > 0: return notification(request, 'Dit rooster is al geblokkeerd') return render(request, 'roster_lock.html', { 'roster': roster, })
def calculate_status(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if not roster.state in [2, 3]: return notification(request, 'Dit rooster wordt op het moment niet verdeeld') return render(request, 'calculate_status.html', { 'roster': roster })
def calculate_publish(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if not roster.state == 3: return notification(request, 'Dit rooster kan niet openbaar worden gemaakt') roster.state = 4 roster.save() return redirect(to = reverse('final_roster', kwargs = {'roster': roster.name}))
def timeslots_empty_day(request, roster, date, to = None): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if roster.state > 0: return notification(request, 'Dit rooster is geblokkeerd omdat uren al verdeeld worden of zijn') dateobj = datetime.datetime.strptime(date, DATEFORMAT) day_slots = TimeSlot.objects.filter(roster = roster).filter(start__gt = dateobj, start__lt = dateobj + datetime.timedelta(days = 1)).order_by('start') for slot in day_slots: slot.delete() return redirect(to = reverse('add_timeslots', kwargs = {'roster': roster.name}))
def timeslots_copy_day(request, roster, date, to=None): dateobj = datetime.datetime.strptime(date, DATEFORMAT) oneday = datetime.timedelta(days=1) try: roster = Roster.objects.get(name=roster) except Roster.DoesNotExist: return notification( request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if roster.state > 0: return notification( request, 'Dit rooster is geblokkeerd omdat uren al verdeeld worden of zijn') day_slots = TimeSlot.objects.filter(roster=roster).filter( start__gt=dateobj, start__lt=dateobj + oneday).order_by('start') to_days = [] if to == None: return render( request, 'copy_slots.html', { 'roster': roster, 'date': date, 'slots': day_slots, 'weekday': dateobj.strftime('%A'), }) elif to == 'samedays' or to == 'weekdays' or to == 'alldays': refday = roster.start while refday <= roster.end: if to == 'samedays': if refday.weekday() == dateobj.weekday(): to_days.append(refday) elif to == 'weekdays': if refday.weekday() <= 4: to_days.append(refday) elif to == 'alldays': to_days.append(refday) refday += oneday elif to == 'nextday': to_days = [dateobj + oneday] else: return notification(request, 'This is not a valid copying option') for day in to_days: slotcount = TimeSlot.objects.filter(roster=roster).filter( start__gt=day, start__lt=day + oneday).count() if not slotcount: for slot in day_slots: start = datetime.datetime.combine(day, slot.start.time()) end = datetime.datetime.combine(day, slot.end.time()) TimeSlot(roster=roster, start=start, end=end, degeneracy=slot.degeneracy).save() return redirect( to=reverse('add_timeslots', kwargs={'roster': roster.name}))
def calculate_start(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if not roster.state in [1, 3]: return notification(request, 'Je kunt nu geen berekening starten') roster.state = 2 roster.save() command = ['nohup', 'python', 'manage.py', 'calculate_roster', '%d' % roster.pk] Popen(command, shell = False, stdout = open(os.devnull, 'w'), stderr = STDOUT, stdin = open(os.devnull, 'w')) return redirect(to = reverse('calculate_status', kwargs = {'roster': roster.name}))
def change_password(request): if not request.POST['new_password'] == request.POST['repeat_password']: return notification( request, 'De opgegeven nieuwe wachtwoorden zijn niet gelijk', next_page=reverse('change_password')) if not request.user.check_password(request.POST['current_password']): return notification(request, 'Dit is niet je huidige wachtwoord', next_page=reverse('change_password')) request.user.set_password(request.POST['new_password']) request.user.save() return notification(request, 'Je wachtwoord is veranderd', next_page=reverse('home'))
def assignment_submit_add_degeneracy(request, timeslot): timeslot = TimeSlot.objects.get(pk = int(timeslot)) if not request.user.is_staff: return notification(request, 'Alleen beheerders mogen dit doen') timeslot.degeneracy += 1 timeslot.save() return redirect(to = reverse('slot_info', kwargs = { 'slot': timeslot.pk }))
def delete_timeslot(request, slot): slot = TimeSlot.objects.get(pk = int(slot)) roster = slot.roster if roster.state > 0: return notification(request, 'Dit rooster is geblokkeerd omdat uren al verdeeld worden of zijn') slot.delete() return redirect(to = reverse('add_timeslots', kwargs = {'roster': roster.name}))
def delete_roster(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) roster.delete() return redirect(to = reverse('roster_overview'))
def assignment_submit_gift(request, assignment): assignment = Assignment.objects.get(pk = int(assignment)) if request.user == assignment.user: if 'user' in request.POST.keys(): user = get_user_model().objects.get(pk = int(request.POST['user'])) if not RosterWorker.objects.filter(user = user, roster = assignment.timeslot.roster): return notification(request, '%s kan tijdens dit rooster niet werken (account is niet toegevoegd)' % unicode(user)) if Assignment.objects.filter(timeslot = assignment.timeslot, user = user): return notification(request, '%s heeft dan al een shift' % user, next_page = reverse('slot_info', kwargs = {'slot': assignment.timeslot.pk})) assignment.giveto = user assignment.fortrade = 3 assignment.save() return redirect(to = reverse('slot_info', kwargs = {'slot': assignment.timeslot.pk})) else: return notification(request, 'Form not recognized') else: return notification(request, 'Not authorized (not your shift)')
def delete_roster(request, roster): try: roster = Roster.objects.get(name=roster) except Roster.DoesNotExist: return notification( request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) roster.delete() return redirect(to=reverse('roster_overview'))
def timeslots_empty_day(request, roster, date, to=None): try: roster = Roster.objects.get(name=roster) except Roster.DoesNotExist: return notification( request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if roster.state > 0: return notification( request, 'Dit rooster is geblokkeerd omdat uren al verdeeld worden of zijn') dateobj = datetime.datetime.strptime(date, DATEFORMAT) day_slots = TimeSlot.objects.filter(roster=roster).filter( start__gt=dateobj, start__lt=dateobj + datetime.timedelta(days=1)).order_by('start') for slot in day_slots: slot.delete() return redirect( to=reverse('add_timeslots', kwargs={'roster': roster.name}))
def assignment_submit_claim(request, timeslot): timeslot = TimeSlot.objects.get(pk = int(timeslot)) assignments = Assignment.objects.filter(timeslot = timeslot) if not RosterWorker.objects.filter(user = request.user, roster = timeslot.roster): return notification(request, 'Je kan tijdens dit rooster niet werken (je account is niet toegevoegd)') if any(assignment.user == request.user for assignment in assignments): return notification(request, 'You already have a shift at this time', next_page = reverse('slot_info', kwargs = {'slot': '%s' % timeslot.pk})) if len(assignments) < timeslot.degeneracy: Assignment(user = request.user, timeslot = timeslot, note = 'shift unknown (originally empty)').save() return redirect(to = reverse('slot_info', kwargs = {'slot': '%s' % timeslot.pk})) else: for assignment in assignments: if assignment.fortrade == 2: assignment.fortrade = 0 assignment.user = request.user assignment.save() return redirect(to = reverse('slot_info', kwargs = {'slot': '%s' % timeslot.pk})) return notification(request, 'There is no shift to claim (anymore)', next_page = reverse('slot_info', kwargs = {'slot': '%s' % timeslot.pk}))
def assignment_submit_staff_empty(request, timeslot): timeslot = TimeSlot.objects.get(pk = int(timeslot)) if not request.user.is_staff: return notification(request, 'Alleen beheerders mogen dit doen') try: if Assignment.objects.filter(timeslot = timeslot).count() < timeslot.degeneracy: assignment = Assignment(user = request.user, timeslot = timeslot, note = 'assigned by %s' % request.user) assignment.save() except IntegrityError: return notification(request, 'Sorry, je kan geen shift toewijzen als je zelf een shift op dat moment hebt. Dit omdat het achter de schermen werkt door tijdelijk jou een shift te geven en die over te zetten. Geef dus tijdelijk even je eigen shift af (of geef hem meteen aan de betreffende persoon en claim dan de lege).', next_page = reverse('slot_info', kwargs = { 'slot': timeslot.pk })) users = [worker.user for worker in RosterWorker.objects.filter(roster = timeslot.roster)] return render(request, 'gift_select_user.html', { 'assignment': assignment, 'slot': timeslot, 'roster': timeslot.roster, 'users': users, 'staff': 1, 'was_empty': True, })
def assignment_trade_result(request, assignment): assignment = Assignment.objects.get(pk = int(assignment)) if not assignment.giveto == request.user: return notification(request, 'You cannot accept a shift for someone else', next_page = request.POST['next']) assignment.fortrade = 0 if request.POST['accept'] == 'yes': assignment.user = assignment.giveto assignment.giveto = None assignment.save() return redirect(to = request.POST['next'])
def delete_timeslot(request, slot): slot = TimeSlot.objects.get(pk=int(slot)) roster = slot.roster if roster.state > 0: return notification( request, 'Dit rooster is geblokkeerd omdat uren al verdeeld worden of zijn') slot.delete() return redirect( to=reverse('add_timeslots', kwargs={'roster': roster.name}))
def timeslots_copy_day(request, roster, date, to = None): dateobj = datetime.datetime.strptime(date, DATEFORMAT) oneday = datetime.timedelta(days = 1) try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if roster.state > 0: return notification(request, 'Dit rooster is geblokkeerd omdat uren al verdeeld worden of zijn') day_slots = TimeSlot.objects.filter(roster = roster).filter(start__gt = dateobj, start__lt = dateobj + oneday).order_by('start') to_days = [] if to == None: return render(request, 'copy_slots.html', { 'roster': roster, 'date': date, 'slots': day_slots, 'weekday': dateobj.strftime('%A'), }) elif to == 'samedays' or to == 'weekdays' or to == 'alldays': refday = roster.start while refday <= roster.end: if to == 'samedays': if refday.weekday() == dateobj.weekday(): to_days.append(refday) elif to == 'weekdays': if refday.weekday() <= 4: to_days.append(refday) elif to == 'alldays': to_days.append(refday) refday += oneday elif to == 'nextday': to_days = [dateobj + oneday] else: return notification(request, 'This is not a valid copying option') for day in to_days: slotcount = TimeSlot.objects.filter(roster = roster).filter(start__gt = day, start__lt = day + oneday).count() if not slotcount: for slot in day_slots: start = datetime.datetime.combine(day, slot.start.time()) end = datetime.datetime.combine(day, slot.end.time()) TimeSlot(roster = roster, start = start, end = end, degeneracy = slot.degeneracy).save() return redirect(to = reverse('add_timeslots', kwargs = {'roster': roster.name}))
def login(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None: if user.is_active: login_func(request, user) if request.GET.get('next', ''): return redirect(to = request.POST.get('next', '')) else: return redirect(to = '/') else: return notification(request, 'Gebruikeraccount is uitgeschakeld') else: return notification(request, 'Geen geldige inloggegevens') else: return render(request, 'login_template.html', { 'next': request.GET.get('next', ''), })
def roster_users(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if roster.state > 0: return notification(request, 'Dit rooster is geblokkeerd omdat uren al verdeeld worden of zijn') users = get_user_model().objects.all() active_user_pks = map(lambda rw: rw.user.pk, RosterWorker.objects.filter(roster = roster)) for user in users: if user.pk in active_user_pks: user.working = True user.extra = RosterWorker.objects.get(user = user, roster = roster).extra else: user.working = False user.extra = 0.0 return render(request, 'add_users.html', { 'users': users, 'roster': roster, })
def add_timeslot(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if roster.state > 0: return notification(request, 'Dit rooster is geblokkeerd omdat uren al verdeeld worden of zijn') refday = roster.start days = [] slots = {} while refday <= roster.end: refnext = refday + datetime.timedelta(days = 1) days.append(refday.strftime(DATEFORMAT)) slots[refday.strftime(DATEFORMAT)] = TimeSlot.objects.filter(roster = roster).filter(start__gt = refday, start__lt = refnext).order_by('start') refday = refnext if request.method == 'POST': slot_form = TimeSlotForm(request.POST) if slot_form.is_valid(): if slot_form.cleaned_data['date'] >= roster.start and slot_form.cleaned_data['date'] <= roster.end: start = datetime.datetime.combine(slot_form.cleaned_data['date'], slot_form.cleaned_data['start']) end = datetime.datetime.combine(slot_form.cleaned_data['date'], slot_form.cleaned_data['end']) TimeSlot(roster = roster, start = start, end = end, degeneracy = slot_form.cleaned_data['people']).save() slot_form = TimeSlotForm(initial = { 'next_date': start.strftime(DATEFORMAT), 'next_start': end.strftime(TIMEFORMAT), 'next_end': (end + datetime.timedelta(hours = 2)).strftime(TIMEFORMAT), #TODO: this doesn't work somehow... }) else: return notification(request, 'Dit tijdslot duurt van %s tot %s. De ingevoerde dag, %s, valt hier buiten.' % (roster.start.strftime(DATETIMEFORMAT), roster.end.strftime(DATETIMEFORMAT), slot_form.cleaned_data['date'].strftime(DATETIMEFORMAT))) else: slot_form = TimeSlotForm(initial = {'roster': roster}) return render(request, 'add_slots.html', { 'roster': roster, 'days': days, 'slotlist': slots, 'slot_form': slot_form, })
def availability_copy(request, roster, year, week): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if not roster.state == 1: return notification(request, 'Je kunt nog niet, of niet meer, je beschikbaarheid doorgeven') year = int(year) week = int(week) if year < roster.start.year or (week < roster.start.isocalendar()[1] and year == roster.start.year) \ or year > roster.end.year or (week > roster.end.isocalendar()[1] and year == roster.end.year): return notification('Geen valide week') monday = week_start_date(year, week) day = datetime.timedelta(days = 1) weekslots = TimeSlot.objects.filter(roster = roster, start__gt = monday, end__lt = monday + 7 * day) weekavailabilities = Availability.objects.filter(user = request.user, timeslot__pk__in = map(lambda sl: sl.pk, weekslots)) weeks = 0 * day while monday + weeks >= datetime.datetime.combine(roster.start, datetime.time()): weeks -= 7 * day while monday + weeks <= datetime.datetime.combine(roster.end, datetime.time()): if not ((monday + weeks).isocalendar()[0] == year and (monday + weeks).isocalendar()[1] == week): weekslots = TimeSlot.objects.filter(roster = roster, start__gt = monday + weeks, end__lt = monday + weeks + 7 * day) Availability.objects.filter(user = request.user, timeslot__pk__in = map(lambda sl: sl.pk, weekslots)).delete() weeks += 7 * day for weekav in weekavailabilities: weeks = 0 * day while weekav.timeslot.start + weeks >= datetime.datetime.combine(roster.start, datetime.time()): weeks -= 7 * day while weekav.timeslot.end + weeks <= datetime.datetime.combine(roster.end, datetime.time()): ts_match = TimeSlot.objects.filter(roster = roster, start = weekav.timeslot.start + weeks, end = weekav.timeslot.end + weeks) if ts_match: if not Availability.objects.filter(user = request.user, timeslot = ts_match): Availability(user = request.user, timeslot = ts_match[0]).save() weeks += 7 * day return redirect(to = reverse('availability', kwargs = {'roster': roster.name, 'year': year, 'week': week}))
def assignment_submit(request, assignment): assignment = Assignment.objects.get(pk = int(assignment)) if not assignment.timeslot.roster.state == 4: return notification(request, 'Dit rooster kan je op het moment niet aangepast worden') if not RosterWorker.objects.filter(user = request.user, roster = assignment.timeslot.roster): return notification(request, 'Je kan tijdens dit rooster niet werken (je account is niet toegevoegd)') if assignment.user.pk != request.user.pk: return notification(request, 'Je mag alleen je eigen shifts aanpassen') if 'action' in request.POST.keys(): if request.POST['action'] == 'keep': assignment.fortrade = 0 assignment.giveto = None elif request.POST['action'] == 'trade': assignment.fortrade = 1 assignment.giveto = None elif request.POST['action'] == 'free': assignment.fortrade = 2 assignment.giveto = None elif request.POST['action'] == 'gift': users = [worker.user for worker in RosterWorker.objects.filter(roster = assignment.timeslot.roster).exclude(pk = request.user.pk).order_by('user__first_name')] return render(request, 'gift_select_user.html', { 'assignment': assignment, 'slot': assignment.timeslot, 'roster': assignment.timeslot.roster, 'users': users, 'staff': 0, }) elif request.POST['action'] == 'split': return render(request, 'split_select_time.html', { 'timeform': TimeForm(), 'assignment': assignment, 'slot': assignment.timeslot, 'roster': assignment.timeslot.roster, 'users': get_user_model().objects.exclude(pk = request.user.pk), }) else: return notification(request, 'Action not recognized') assignment.save() return redirect(to = reverse('slot_info', kwargs = {'slot': assignment.timeslot.pk})) else: return notification(request, 'Form not recognized')
def roster_stats(request, roster): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) #if not roster.state in [3, 4]: # return notification(request, 'Alleen verdeelde roosters hebben statistische informatie') ''' Hours per person ''' users = generate_user_stats(roster) ''' Availability density (high complexity, N^4 or something) ''' timeslots = TimeSlot.objects.filter(roster = roster) availabilities = group_by(Availability.objects.filter(timeslot__roster = roster), 'timeslot') oneday = datetime.timedelta(days = 1) day = roster.start while day < roster.end: if day.isoweekday() == 1: #print '%s is monday' % day first_monday = day break day_stats = [] if first_monday: day = first_monday while day < first_monday + 7 * oneday: day_timeslots = [timeslot for timeslot in timeslots if timeslot.start.date() == day] day_stat = { 'weekday': day.strftime("%a"), 'timeslots_sets': [], } for reference_timeslot in sorted(day_timeslots, key = lambda slot: slot.start): ''' Find equivalent timeslots in other weeks ''' equivalents = { 'first_timeslots': reference_timeslot, 'equivalent_timeslots': [], 'equivalent_availabilities_length': 0, } weekday = day while weekday < roster.end: weekday_timeslots = [timeslot for timeslot in timeslots if timeslot.start.date() == weekday] for weekday_timeslot in weekday_timeslots: if weekday_timeslot.start.time() == reference_timeslot.start.time() and weekday_timeslot.end.time() == reference_timeslot.end.time(): equivalents['equivalent_timeslots'].append(weekday_timeslot) equivalents['equivalent_availabilities_length'] += len(availabilities[weekday_timeslot]) weekday += 7 * oneday day_stat['timeslots_sets'].append(equivalents) day_stats.append(day_stat) day += oneday return render(request, 'roster_stats.html', { 'roster': roster, 'users': users, 'day_stats': day_stats, })
def login(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None: if user.is_active: login_func(request, user) if request.GET.get('next', ''): return redirect(to=request.POST.get('next', '')) else: return redirect(to='/') else: return notification(request, 'Gebruikeraccount is uitgeschakeld') else: return notification(request, 'Geen geldige inloggegevens') else: return render(request, 'login_template.html', { 'next': request.GET.get('next', ''), })
def assignment_submit_split(request, assignment): assignment = Assignment.objects.get(pk = int(assignment)) if not RosterWorker.objects.filter(user = request.user, roster = assignment.timeslot.roster) and not request.user.is_staff(): return notification(request, 'Je kan tijdens dit rooster niet werken (je account is niet toegevoegd)') if 'splitting' in request.POST.keys(): form = TimeForm(request.POST) if form.is_valid(): time = form.cleaned_data['time'] sd = assignment.timeslot.start minshiftlength = datetime.timedelta(minutes = 29, seconds = 59) splitat = datetime.datetime.combine(datetime.date(sd.year, sd.month, sd.day), time) ''' Is the remaining shift long enough? ''' if splitat > assignment.timeslot.start + minshiftlength and splitat < assignment.timeslot.end - minshiftlength: ''' We need to split the timeslot (happens for everyone; better than simultaneous slots) ''' prevend = assignment.timeslot.end assignment.timeslot.end = splitat assignment.timeslot.save() ''' Clone trick ''' ts_old_pk = assignment.timeslot.pk assignment.timeslot.pk = None assignment.timeslot.start = splitat assignment.timeslot.end = prevend assignment.timeslot.save() ts_new_pk = assignment.timeslot.pk ''' Then we need to clone the assignments for everyone ''' assignments = Assignment.objects.filter(timeslot__pk = ts_old_pk) if not len(assignments): raise Exception('Impossible situation (that seems to happen anyway)') for cloneassignment in assignments: cloneassignment.pk = None cloneassignment.timeslot = assignment.timeslot cloneassignment.save() #return redirect(to = reverse('slot_info', kwargs = {'slot': assignment.timeslot.pk})) return render(request, 'split_confirm.html', { 'timeslot1': TimeSlot.objects.get(pk = ts_old_pk), 'timeslot2': TimeSlot.objects.get(pk = ts_new_pk), }) return notification(request, 'De opgegeven tijd was niet geldig') else: return notification(request, 'Form not recognized')
def assignment_submit_delete_empty(request, timeslot): timeslot = TimeSlot.objects.get(pk = int(timeslot)) if request.user.is_staff: if timeslot.degeneracy <= 1: roster_name = timeslot.roster.name timeslot.delete() return redirect(to = reverse('final_roster', kwargs = {'roster': roster_name})) else: timeslot.degeneracy -= 1 timeslot.save() return redirect(to = reverse('slot_info', kwargs = {'slot': timeslot.pk})) else: return notification(request, 'Action not recognized')
def slot_info(request, slot): slot = TimeSlot.objects.get(pk = int(slot)) if not slot.roster.state == 4 and not (slot.roster.state == 3 and request.user.is_staff): return notification(request, 'Dit rooster kan op het moment niet aangepast worden') assignments = Assignment.objects.filter(timeslot = slot) owner_shift = [assignment for assignment in assignments if assignment.user == request.user] owner_shift = owner_shift[0] if owner_shift else None availabilities = Availability.objects.filter(timeslot = slot) return render(request, 'slot_info.html', { 'user': request.user, 'slot': slot, 'roster': slot.roster, 'owner_shift': owner_shift, 'assignments': assignments, 'availabilities': availabilities, })
def month_overview(request, user, year = None, month = None): try: user = get_user_model().objects.get(username = user) except User.DoesNotExist: return notification(request, 'Gebruiker met gebruikersnaam \'%s\' niet gevonden' % user) day = datetime.timedelta(days = 1) if year and month: year = int(year) month = int(month) else: refday = datetime.datetime.today() if refday.day < 20: refday -= day * 21 year = refday.year month = refday.month return redirect(reverse('month_overview', kwargs = {'user': user.username, 'year': str(year), 'month': str(month)})) return render(request, 'shift_overview.html', overview_context(user, year, month))
def month_overview_CD(request, year = None, month = None): if year and month: year = int(year) month = int(month) monthdate = datetime.datetime(year = year, month = month, day = 1) else: ref = datetime.datetime.today() - datetime.timedelta(days = 14) return redirect(reverse('month_overview_CD', kwargs = {'year': str(ref.year), 'month': str(ref.month)})) if not request.user.is_staff: return notification(request, 'Alleen beheerders mogen gegevens voor iedereen als CSV downloaden. Je kan wel je eigen gegevens inzien.') form = KostenplaatsForm(request.POST or None) if not form.is_valid(): totals = {} for user in get_user_model().objects.filter(is_active = True): context = overview_context(user, year, month) totals[user.get_full_name()] = context['totalnr'] return render(request, 'get_kostenplaats.html', { 'form': form, 'monthdate': monthdate, 'totals': totals, 'overall_total': sum(totals.values()), }) response = HttpResponse(content_type = 'text/csv') response['Content-Disposition'] = 'attachment; filename="overview_%s.csv"' % monthdate.strftime('%b_%Y').lower() fh = writer(response) totals = {} fh.writerow(['Naam', 'Datum', 'Uur gewerkt', 'Looncomponent', 'Kostenplaats']) for user in get_user_model().objects.filter(is_active = True): context = overview_context(user, year, month) totals[user.get_full_name()] = context['totalnr'] for dayinfo in context['hourlist'].values(): if dayinfo['hournr'] > 0: looncomponent = form.cleaned_data['type_werk'] if dayinfo['percentage'] == "100" else "Loon onregelmatige uren " + dayinfo['percentage'] + "%" fh.writerow([ user.get_full_name(), dayinfo['date'], dayinfo['hournr'], looncomponent, form.cleaned_data['kostenplaatsnummer'], ]) return response
def month_overview_CD(request, year = None, month = None): if year and month: year = int(year) month = int(month) monthdate = datetime.datetime(year = year, month = month, day = 1) else: ref = datetime.datetime.today() - datetime.timedelta(days = 14) return redirect(reverse('month_overview_CD', kwargs = {'year': str(ref.year), 'month': str(ref.month)})) if not request.user.is_staff: return notification(request, 'Alleen beheerders mogen gegevens voor iedereen als CSV downloaden. Je kan wel je eigen gegevens inzien.') form = KostenplaatsForm(request.POST or None) if not form.is_valid(): totals = {} for user in get_user_model().objects.filter(is_active = True): context = overview_context(user, year, month) totals[user.get_full_name()] = context['totalnr'] return render(request, 'get_kostenplaats.html', { 'form': form, 'monthdate': monthdate, 'totals': totals, 'overall_total': sum(totals.values()), }) response = HttpResponse(content_type = 'text/csv') response['Content-Disposition'] = 'attachment; filename="overview_%s.csv"' % monthdate.strftime('%b_%Y').lower() fh = writer(response, delimiter=';') totals = {} fh.writerow(['Naam', 'Datum', 'Uur gewerkt', 'Looncomponent', 'Kostenplaats']) for user in get_user_model().objects.filter(is_active = True): context = overview_context(user, year, month) totals[user.get_full_name()] = context['totalnr'] for dayinfo in context['hourlist'].values(): if dayinfo['hournr'] > 0: if dayinfo['specialhours'] > 0 and dayinfo['normalhours'] > 0: fh.writerow([ user.get_full_name(), dayinfo['date'], str(dayinfo['normalhours']).replace(':',','), form.cleaned_data['type_werk'], form.cleaned_data['kostenplaatsnummer'], ]) fh.writerow([ user.get_full_name(), dayinfo['date'], str(dayinfo['specialhours']).replace(':',','), "Loon onregelmatige uren "+str(dayinfo['percentage'])+"%", form.cleaned_data['kostenplaatsnummer'], ]) elif dayinfo['specialhours'] <= 0: fh.writerow([ user.get_full_name(), dayinfo['date'], str(dayinfo['normalhours']).replace(':',','), form.cleaned_data['type_werk'], form.cleaned_data['kostenplaatsnummer'], ]) else: fh.writerow([ user.get_full_name(), dayinfo['date'], str(dayinfo['specialhours']).replace(':',','), "Loon onregelmatige uren "+str(dayinfo['percentage'])+"%", form.cleaned_data['kostenplaatsnummer'], ]) return response
def availability(request, roster, year = None, week = None): try: roster = Roster.objects.get(name = roster) except Roster.DoesNotExist: return notification(request, 'Er is geen rooster genaamd \'%s\' gevonden' % roster) if not roster.state == 1: return notification(request, 'Je kunt nog niet, of niet meer, je beschikbaarheid doorgeven') if not RosterWorker.objects.filter(roster = roster, user = request.user): return notification(request, 'Je bent niet uitgenodigd voor dit rooster') if year == None or week == None: return redirect(to = reverse('availability', kwargs={'roster': roster.name, 'year': roster.start.year, 'week': roster.start.isocalendar()[1]})) else: year = int(year) week = int(week) if year < roster.start.year or (week < roster.start.isocalendar()[1] and year == roster.start.year): return redirect(to = reverse('availability', kwargs={'roster': roster.name, 'year': roster.start.year, 'week': roster.start.isocalendar()[1]})) if year > roster.end.year or (week > roster.end.isocalendar()[1] and year == roster.end.year): return redirect(to = reverse('availability', kwargs={'roster': roster.name, 'year': roster.end.year, 'week': roster.end.isocalendar()[1]})) monday = week_start_date(year, week) day = datetime.timedelta(days = 1) schedule = { 'monday': {'date': monday.strftime('%a %d %b'), 'name': 'monday', 'timeslots': TimeSlot.objects.filter(roster = roster, start__gt = monday, end__lt = monday + day)}, 'tuesday': {'date': (monday + day).strftime('%a %d %b'), 'name': 'tuesday', 'timeslots': TimeSlot.objects.filter(roster = roster, start__gt = monday + day, end__lt = monday + 2 * day)}, 'wednesday': {'date': (monday + 2 * day).strftime('%a %d %b'), 'name': 'wednesday', 'timeslots': TimeSlot.objects.filter(roster = roster, start__gt = monday + 2 * day, end__lt = monday + 3 * day)}, 'thursday': {'date': (monday + 3 * day).strftime('%a %d %b'), 'name': 'thursday', 'timeslots': TimeSlot.objects.filter(roster = roster, start__gt = monday + 3 * day, end__lt = monday + 4 * day)}, 'friday': {'date': (monday + 4 * day).strftime('%a %d %b'), 'name': 'friday', 'timeslots': TimeSlot.objects.filter(roster = roster, start__gt = monday + 4 * day, end__lt = monday + 5 * day)}, 'saturday': {'date': (monday + 5 * day).strftime('%a %d %b'), 'name': 'saturday', 'timeslots': TimeSlot.objects.filter(roster = roster, start__gt = monday + 5 * day, end__lt = monday + 6 * day)}, 'sunday': {'date': (monday + 6 * day).strftime('%a %d %b'), 'name': 'sunday', 'timeslots': TimeSlot.objects.filter(roster = roster, start__gt = monday + 6 * day, end__lt = monday + 7 * day)}, } for schedule_day in schedule.values(): for timeslot in schedule_day['timeslots']: if Availability.objects.filter(user = request.user, timeslot = timeslot).count(): timeslot.available = True else: timeslot.available = False (next_year, next_week) = (monday + 7 * day).isocalendar()[0:2] (prev_year, prev_week) = (monday - 7 * day).isocalendar()[0:2] if prev_year < roster.start.year or (prev_week < roster.start.isocalendar()[1] and prev_year == roster.start.year): (prev_year, prev_week) = (None, None) if next_year > roster.end.year or (next_week > roster.end.isocalendar()[1] and next_year == roster.end.year): (next_year, next_week) = (None, None) ''' Get jump links to all the weeks ''' start_monday = week_start_date(roster.start.year, roster.start.isocalendar()[1]) end_monday = week_start_date(roster.end.year, roster.end.isocalendar()[1]) oneweek = datetime.timedelta(days = 7) mondays = [] day_k = start_monday while day_k <= end_monday: mondays.append({'name': day_k.strftime('%d %b'), 'is_this_week': monday == day_k, 'year': day_k.isocalendar()[0], 'week': day_k.isocalendar()[1]}) day_k += oneweek return render(request, 'availability.html', { 'roster': roster, 'schedule': schedule, 'year': year, 'prev_year': prev_year, 'next_year': next_year, 'week': week, 'prev_week': prev_week, 'next_week': next_week, 'mondays': mondays, })