views.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. from django.shortcuts import render, redirect
  2. from . forms import LoginForm, CreateUserForm, TimeEntryForm, SettingsForm
  3. from . models import User, Setting, Entry
  4. from hashlib import sha256
  5. import datetime
  6. from dateutil.relativedelta import relativedelta
  7. from calendar import monthrange
  8. def hash_pin(pin):
  9. return sha256(pin.encode('utf-8')).hexdigest()
  10. def get_user(uid):
  11. user = User.objects.get(id=uid)
  12. return user
  13. def check_setup():
  14. settings = Setting.objects.all()
  15. if len(settings) > 0:
  16. return True
  17. else:
  18. return False
  19. def days_of_month(year, month):
  20. r = monthrange(year, month)
  21. days = []
  22. for day in range(1, r[1]+1):
  23. d = datetime.date(year, month, day)
  24. days.append({'day': str(day), 'label': d.strftime('%B %d (%A)')})
  25. return days
  26. def logout_user(request):
  27. request.session['authenticated'] = False
  28. return redirect('home')
  29. def requires_auth(request):
  30. auth = request.session.get('authenticated', None)
  31. if auth is True:
  32. return True
  33. else:
  34. return False
  35. def setup(request):
  36. if check_setup() is True:
  37. return redirect('home')
  38. form = SettingsForm()
  39. if request.method == "POST":
  40. form = SettingsForm(request.POST)
  41. if form.is_valid():
  42. data = form.cleaned_data
  43. s = Setting()
  44. s.setting = 'Max Daily Hours'
  45. s.value = data['max_daily_hours']
  46. s.save()
  47. s = Setting()
  48. s.setting = 'Session Timeout'
  49. s.value = data['session_timeout']
  50. s.save()
  51. s = Setting()
  52. s.setting = 'Max Daily Entries'
  53. s.value = data['max_daily_entries']
  54. s.save()
  55. s = Setting()
  56. s.setting = 'Projects'
  57. s.value = data['projects']
  58. s.save()
  59. return redirect('home')
  60. context = {
  61. 'form': form
  62. }
  63. return render(request, 'setup.html', context=context)
  64. def create_user(request):
  65. form = CreateUserForm()
  66. if request.method == "POST":
  67. form = CreateUserForm(request.POST)
  68. if form.is_valid():
  69. data = form.cleaned_data
  70. users = User.objects.filter(pin=hash_pin(data['pin']))
  71. if len(users) == 0:
  72. user = User()
  73. user.first_name = data['first_name']
  74. user.last_name = data['last_name']
  75. user.pin = data['pin']
  76. user.save()
  77. return redirect('timesheet')
  78. else:
  79. form.add_error('pin', 'PIN already exists')
  80. auth_timeout = int(Setting.objects.get(setting="Session Timeout").value) * 60
  81. context = {
  82. 'form': form,
  83. 'auth_timeout': auth_timeout
  84. }
  85. return render(request, 'create_user.html', context=context)
  86. def home(request):
  87. if check_setup() is False:
  88. return redirect('setup')
  89. form = LoginForm
  90. login_error = False
  91. if request.method == "POST":
  92. form = LoginForm(request.POST or None)
  93. if form.is_valid():
  94. data = form.cleaned_data
  95. pin = sha256(data['pin'].encode('utf-8')).hexdigest()
  96. user = User.objects.filter(pin=pin, status=True).first()
  97. if user is None:
  98. form.add_error('pin', 'Invalid login')
  99. login_error = True
  100. else:
  101. request.session['authenticated'] = True
  102. request.session['uid'] = user.id
  103. return redirect('timesheet')
  104. context = {
  105. 'form': form,
  106. 'login_error': login_error
  107. }
  108. return render(request, 'home.html', context=context)
  109. def timesheet(request, year=None, month=None, day=None):
  110. date = datetime.datetime.now()
  111. if year is None:
  112. year = date.year
  113. if month is None:
  114. month = date.month
  115. if month > 12:
  116. return redirect('timesheet', year=year, month=12)
  117. if day is None:
  118. day = date.day
  119. if datetime.date(year=year, month=month, day=day) <= datetime.date.today():
  120. show_form = True
  121. else:
  122. show_form = False
  123. if datetime.date(year=year, month=month, day=day) < datetime.date.today():
  124. show_next = True
  125. else:
  126. show_next = False
  127. if datetime.date(year=year, month=month, day=day) == datetime.date.today():
  128. today_is_today = True
  129. else:
  130. today_is_today = False
  131. current_month = datetime.date(year, month, 1)
  132. next_month = current_month + relativedelta(months=+1)
  133. previous_month = current_month + relativedelta(months=-1)
  134. current_month = datetime.date(year, month, day)
  135. if requires_auth(request) is False:
  136. request.session['authenticated'] = False
  137. return redirect('home')
  138. uid = request.session.get('uid')
  139. user = get_user(uid)
  140. projects = Setting.objects.get(setting='Projects')
  141. form = TimeEntryForm()
  142. selected_day = None
  143. if request.method == "POST":
  144. form = TimeEntryForm(request.POST)
  145. if form.is_valid():
  146. data = form.cleaned_data
  147. if data['hours'] == '0' and data['minutes'] == '0':
  148. selected_day = data['day_of_month']
  149. form.add_error('hours', 'No time provided')
  150. form.add_error('minutes', 'No time provided')
  151. else:
  152. entry = Entry()
  153. entry.user = user
  154. entry.project = data['project']
  155. entry.date = datetime.date(year=current_month.year, month=current_month.month,
  156. day=int(data['day_of_month']))
  157. entry.hours = data['hours']
  158. entry.minutes = data['minutes']
  159. if current_month.year == date.year and current_month.month == date.month:
  160. entry.status = "current"
  161. else:
  162. entry.status = "historical"
  163. entry.save()
  164. form = TimeEntryForm()
  165. entries = Entry.objects.filter(user=user, date__year=current_month.year, date__month=current_month.month)\
  166. .order_by('date')
  167. max_daily_entries = Setting.objects.get(setting='Max Daily Entries')
  168. todays_entries = Entry.objects.filter(user=user, date__year=current_month.year, date__month=current_month.month)\
  169. .count()
  170. max_daily_entries_quota = False
  171. if int(todays_entries) >= int(max_daily_entries.value):
  172. max_daily_entries_quota = True
  173. time_entries = list()
  174. total_time_worked = 0
  175. for entry in entries:
  176. time_worked = float(entry.hours) + float(entry.minutes)
  177. e = {
  178. 'uid': entry.uid,
  179. 'date': entry.date,
  180. 'hours': entry.hours,
  181. 'minutes': entry.minutes,
  182. 'project': entry.project,
  183. 'time_worked': time_worked,
  184. }
  185. time_entries.append(e)
  186. total_time_worked = float(total_time_worked) + time_worked
  187. auth_timeout = int(Setting.objects.get(setting="Session Timeout").value) * 60
  188. context = {
  189. 'user': user,
  190. 'form': form,
  191. 'entries': time_entries,
  192. 'show_form': show_form,
  193. 'show_next': show_next,
  194. 'today_is_today': today_is_today,
  195. 'total_time_worked': total_time_worked,
  196. 'max_daily_entries_quota': max_daily_entries_quota,
  197. 'projects': projects.value,
  198. 'session_timeout': auth_timeout,
  199. 'current_month': current_month,
  200. 'current_month_day': str(current_month.day),
  201. 'current_month_name': current_month.strftime('%B'),
  202. 'next_month': next_month,
  203. 'previous_month': previous_month,
  204. 'days_of_month': days_of_month(current_month.year, current_month.month),
  205. 'selected_day': selected_day,
  206. }
  207. return render(request, 'timesheet.html', context=context)
  208. def remove(request, entry_id):
  209. if requires_auth(request) is False:
  210. request.session['authenticated'] = False
  211. return redirect('home')
  212. uid = request.session.get('uid')
  213. user = get_user(uid)
  214. entry = Entry.objects.filter(uid=entry_id, user=user).first()
  215. print(entry)
  216. year = entry.date.year
  217. month = entry.date.month
  218. entry.delete()
  219. return redirect('timesheet', year, month)
  220. def edit(request, entry_id):
  221. if requires_auth(request) is False:
  222. request.session['authenticated'] = False
  223. return redirect('home')
  224. uid = request.session.get('uid')
  225. user = get_user(uid)
  226. form = TimeEntryForm()
  227. if request.method == "POST":
  228. form = TimeEntryForm(request.POST)
  229. if form.is_valid():
  230. data = form.cleaned_data
  231. if data['hours'] == '0' and data['minutes'] == '0':
  232. form.add_error('hours', 'No time provided')
  233. form.add_error('minutes', 'No time provided')
  234. else:
  235. entry = Entry.objects.filter(uid=entry_id, user=user).first()
  236. year = entry.date.year
  237. month = entry.date.month
  238. entry.date = datetime.date(year=year, month=month, day=int(data['day_of_month']))
  239. entry.hours = data['hours']
  240. entry.minutes = data['minutes']
  241. entry.project = data['project']
  242. entry.save()
  243. return redirect('timesheet', year, month)
  244. entry = Entry.objects.filter(uid=entry_id, user=user).first()
  245. year = entry.date.year
  246. month = entry.date.month
  247. projects = Setting.objects.get(setting="Projects")
  248. auth_timeout = int(Setting.objects.get(setting="Session Timeout").value) * 60
  249. if entry:
  250. form.fields['hours'].initial = entry.hours
  251. form.fields['minutes'].initial = entry.minutes
  252. if projects.value == "True":
  253. form.fields['project'].initial = entry.project
  254. else:
  255. del form.fields['project']
  256. else:
  257. return redirect('timesheet', year, month)
  258. context = {
  259. 'form': form,
  260. 'user': user,
  261. 'entry': entry,
  262. 'projects': projects.value,
  263. 'session_timeout': auth_timeout,
  264. 'days_of_month': days_of_month(year, month),
  265. 'selected_day': str(entry.date.day)
  266. }
  267. return render(request, 'edit.html', context=context)